OSDN Git Service

Fixed issue #155: Fix SVN Rebase sets upstream as remotes/trunk
[tortoisegit/TortoiseGitJp.git] / src / TortoiseProc / Commands / RenameCommand.cpp
1 // TortoiseSVN - a Windows shell extension for easy version control\r
2 \r
3 // Copyright (C) 2007-2008 - TortoiseSVN\r
4 \r
5 // This program is free software; you can redistribute it and/or\r
6 // modify it under the terms of the GNU General Public License\r
7 // as published by the Free Software Foundation; either version 2\r
8 // of the License, or (at your option) any later version.\r
9 \r
10 // This program is distributed in the hope that it will be useful,\r
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of\r
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
13 // GNU General Public License for more details.\r
14 \r
15 // You should have received a copy of the GNU General Public License\r
16 // along with this program; if not, write to the Free Software Foundation,\r
17 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
18 //\r
19 #include "StdAfx.h"\r
20 #include "RenameCommand.h"\r
21 \r
22 #include "MessageBox.h"\r
23 //#include "SVNProgressDlg.h"\r
24 //#include "ProgressDlg.h"\r
25 #include "RenameDlg.h"\r
26 #include "InputLogDlg.h"\r
27 #include "Git.h"\r
28 #include "DirFileEnum.h"\r
29 #include "ShellUpdater.h"\r
30 \r
31 bool RenameCommand::Execute()\r
32 {\r
33         bool bRet = false;\r
34         CString filename = cmdLinePath.GetFileOrDirectoryName();\r
35         CString basePath = cmdLinePath.GetContainingDirectory().GetGitPathString();\r
36         //::SetCurrentDirectory(basePath);\r
37 \r
38         // show the rename dialog until the user either cancels or enters a new\r
39         // name (one that's different to the original name\r
40         CString sNewName;\r
41         do \r
42         {\r
43                 CRenameDlg dlg;\r
44                 dlg.m_name = filename;\r
45                 if (dlg.DoModal() != IDOK)\r
46                         return FALSE;\r
47                 sNewName = dlg.m_name;\r
48         } while(PathIsRelative(sNewName) && !PathIsURL(sNewName) && (sNewName.IsEmpty() || (sNewName.Compare(filename)==0)));\r
49 \r
50         if(!basePath.IsEmpty())\r
51                 sNewName=basePath+"/"+sNewName;\r
52 \r
53         CString cmd;\r
54         CString output;\r
55         cmd.Format(_T("git.exe mv -- \"%s\" \"%s\""),\r
56                                         cmdLinePath.GetGitPathString(),\r
57                                         sNewName);\r
58                                                                         \r
59         if(g_Git.Run(cmd,&output,CP_ACP))\r
60         {\r
61                 CMessageBox::Show(hwndExplorer, output, _T("TortoiseGit"), MB_OK);\r
62         }\r
63 \r
64         CTGitPath newpath;\r
65         newpath.SetFromGit(sNewName);\r
66 \r
67         CShellUpdater::Instance().AddPathForUpdate(newpath);\r
68 #if 0\r
69         TRACE(_T("rename file %s to %s\n"), (LPCTSTR)cmdLinePath.GetWinPathString(), (LPCTSTR)sNewName);\r
70         CTSVNPath destinationPath(basePath);\r
71         if (PathIsRelative(sNewName) && !PathIsURL(sNewName))\r
72                 destinationPath.AppendPathString(sNewName);\r
73         else\r
74                 destinationPath.SetFromWin(sNewName);\r
75         // check if a rename just with case is requested: that's not possible on windows file systems\r
76         // and we have to show an error.\r
77         if (cmdLinePath.GetWinPathString().CompareNoCase(destinationPath.GetWinPathString())==0)\r
78         {\r
79                 //rename to the same file!\r
80                 CString sHelpPath = theApp.m_pszHelpFilePath;\r
81                 sHelpPath += _T("::/tsvn-dug-rename.html#tsvn-dug-renameincase");\r
82                 CMessageBox::Show(hwndExplorer, IDS_PROC_CASERENAME, IDS_APPNAME, MB_OK|MB_HELP, sHelpPath);\r
83         }\r
84         else\r
85         {\r
86                 CString sMsg;\r
87                 if (SVN::PathIsURL(cmdLinePath))\r
88                 {\r
89                         // rename an URL.\r
90                         // Ask for a commit message, then rename directly in\r
91                         // the repository\r
92                         CInputLogDlg input;\r
93                         CString sUUID;\r
94                         SVN svn;\r
95                         svn.GetRepositoryRootAndUUID(cmdLinePath, sUUID);\r
96                         input.SetUUID(sUUID);\r
97                         CString sHint;\r
98                         sHint.Format(IDS_INPUT_MOVE, (LPCTSTR)cmdLinePath.GetSVNPathString(), (LPCTSTR)destinationPath.GetSVNPathString());\r
99                         input.SetActionText(sHint);\r
100                         if (input.DoModal() == IDOK)\r
101                         {\r
102                                 sMsg = input.GetLogMessage();\r
103                         }\r
104                         else\r
105                         {\r
106                                 return FALSE;\r
107                         }\r
108                 }\r
109                 if ((cmdLinePath.IsDirectory())||(pathList.GetCount() > 1))\r
110                 {\r
111                         // renaming a directory can take a while: use the\r
112                         // progress dialog to show the progress of the renaming\r
113                         // operation.\r
114                         CSVNProgressDlg progDlg;\r
115                         progDlg.SetCommand(CSVNProgressDlg::SVNProgress_Rename);\r
116                         if (parser.HasVal(_T("closeonend")))\r
117                                 progDlg.SetAutoClose(parser.GetLongVal(_T("closeonend")));\r
118                         progDlg.SetPathList(pathList);\r
119                         progDlg.SetUrl(destinationPath.GetWinPathString());\r
120                         progDlg.SetCommitMessage(sMsg);\r
121                         progDlg.SetRevision(SVNRev::REV_WC);\r
122                         progDlg.DoModal();\r
123                         bRet = !progDlg.DidErrorsOccur();\r
124                 }\r
125                 else\r
126                 {\r
127                         SVN svn;\r
128                         CString sFilemask = cmdLinePath.GetFilename();\r
129                         if (sFilemask.ReverseFind('.')>=0)\r
130                         {\r
131                                 sFilemask = sFilemask.Left(sFilemask.ReverseFind('.'));\r
132                         }\r
133                         else\r
134                                 sFilemask.Empty();\r
135                         CString sNewMask = sNewName;\r
136                         if (sNewMask.ReverseFind('.'>=0))\r
137                         {\r
138                                 sNewMask = sNewMask.Left(sNewMask.ReverseFind('.'));\r
139                         }\r
140                         else\r
141                                 sNewMask.Empty();\r
142 \r
143                         if (((!sFilemask.IsEmpty()) && (parser.HasKey(_T("noquestion")))) ||\r
144                                 (cmdLinePath.GetFileExtension().Compare(destinationPath.GetFileExtension())!=0))\r
145                         {\r
146                                 if (!svn.Move(CTSVNPathList(cmdLinePath), destinationPath, TRUE, sMsg))\r
147                                 {\r
148                                         TRACE(_T("%s\n"), (LPCTSTR)svn.GetLastErrorMessage());\r
149                                         CMessageBox::Show(hwndExplorer, svn.GetLastErrorMessage(), _T("TortoiseGit"), MB_ICONERROR);\r
150                                 }\r
151                                 else\r
152                                         bRet = true;\r
153                         }\r
154                         else\r
155                         {\r
156                                 // when refactoring, multiple files have to be renamed\r
157                                 // at once because those files belong together.\r
158                                 // e.g. file.aspx, file.aspx.cs, file.aspx.resx\r
159                                 CTSVNPathList renlist;\r
160                                 CSimpleFileFind filefind(cmdLinePath.GetDirectory().GetWinPathString(), sFilemask+_T(".*"));\r
161                                 while (filefind.FindNextFileNoDots())\r
162                                 {\r
163                                         if (!filefind.IsDirectory())\r
164                                                 renlist.AddPath(CTSVNPath(filefind.GetFilePath()));\r
165                                 }\r
166                                 if (renlist.GetCount()<=1)\r
167                                 {\r
168                                         // we couldn't find any other matching files\r
169                                         // just do the default...\r
170                                         if (!svn.Move(CTSVNPathList(cmdLinePath), destinationPath, TRUE, sMsg))\r
171                                         {\r
172                                                 TRACE(_T("%s\n"), (LPCTSTR)svn.GetLastErrorMessage());\r
173                                                 CMessageBox::Show(hwndExplorer, svn.GetLastErrorMessage(), _T("TortoiseGit"), MB_ICONERROR);\r
174                                         }\r
175                                         else\r
176                                         {\r
177                                                 bRet = true;\r
178                                                 CShellUpdater::Instance().AddPathForUpdate(destinationPath);\r
179                                         }\r
180                                 }\r
181                                 else\r
182                                 {\r
183                                         std::map<CString, CString> renmap;\r
184                                         CString sTemp;\r
185                                         CString sRenList;\r
186                                         for (int i=0; i<renlist.GetCount(); ++i)\r
187                                         {\r
188                                                 CString sFilename = renlist[i].GetFilename();\r
189                                                 CString sNewFilename = sNewMask + sFilename.Mid(sFilemask.GetLength());\r
190                                                 sTemp.Format(_T("\n%s -> %s"), (LPCTSTR)sFilename, (LPCTSTR)sNewFilename);\r
191                                                 if (!renlist[i].IsEquivalentTo(cmdLinePath))\r
192                                                         sRenList += sTemp;\r
193                                                 renmap[renlist[i].GetWinPathString()] = renlist[i].GetContainingDirectory().GetWinPathString()+_T("\\")+sNewFilename;\r
194                                         }\r
195                                         CString sRenameMultipleQuestion;\r
196                                         sRenameMultipleQuestion.Format(IDS_PROC_MULTIRENAME, (LPCTSTR)sRenList);\r
197                                         UINT idret = CMessageBox::Show(hwndExplorer, sRenameMultipleQuestion, _T("TortoiseGit"), MB_ICONQUESTION|MB_YESNOCANCEL);\r
198                                         if (idret == IDYES)\r
199                                         {\r
200                                                 CProgressDlg progress;\r
201                                                 progress.SetTitle(IDS_PROC_MOVING);\r
202                                                 progress.SetAnimation(IDR_MOVEANI);\r
203                                                 progress.SetTime(true);\r
204                                                 progress.ShowModeless(CWnd::FromHandle(hwndExplorer));\r
205                                                 DWORD count = 1;\r
206                                                 for (std::map<CString, CString>::iterator it=renmap.begin(); it != renmap.end(); ++it)\r
207                                                 {\r
208                                                         progress.FormatPathLine(1, IDS_PROC_MOVINGPROG, (LPCTSTR)it->first);\r
209                                                         progress.FormatPathLine(2, IDS_PROC_CPYMVPROG2, (LPCTSTR)it->second);\r
210                                                         progress.SetProgress(count, renmap.size());\r
211                                                         if (!svn.Move(CTSVNPathList(CTSVNPath(it->first)), CTSVNPath(it->second), TRUE, sMsg))\r
212                                                         {\r
213                                                                 if (svn.Err->apr_err == SVN_ERR_ENTRY_NOT_FOUND)\r
214                                                                 {\r
215                                                                         bRet = !!MoveFile(it->first, it->second);\r
216                                                                 }\r
217                                                                 else\r
218                                                                 {\r
219                                                                         TRACE(_T("%s\n"), (LPCTSTR)svn.GetLastErrorMessage());\r
220                                                                         CMessageBox::Show(hwndExplorer, svn.GetLastErrorMessage(), _T("TortoiseGit"), MB_ICONERROR);\r
221                                                                         bRet = false;\r
222                                                                 }\r
223                                                         }\r
224                                                         else\r
225                                                         {\r
226                                                                 bRet = true;\r
227                                                                 CShellUpdater::Instance().AddPathForUpdate(CTSVNPath(it->second));\r
228                                                         }\r
229                                                 }\r
230                                                 progress.Stop();\r
231                                         }\r
232                                         else if (idret == IDNO)\r
233                                         {\r
234                                                 // no, user wants to just rename the file he selected\r
235                                                 if (!svn.Move(CTSVNPathList(cmdLinePath), destinationPath, TRUE, sMsg))\r
236                                                 {\r
237                                                         TRACE(_T("%s\n"), (LPCTSTR)svn.GetLastErrorMessage());\r
238                                                         CMessageBox::Show(hwndExplorer, svn.GetLastErrorMessage(), _T("TortoiseGit"), MB_ICONERROR);\r
239                                                 }\r
240                                                 else\r
241                                                 {\r
242                                                         bRet = true;\r
243                                                         CShellUpdater::Instance().AddPathForUpdate(destinationPath);\r
244                                                 }\r
245                                         }\r
246                                         else if (idret == IDCANCEL)\r
247                                         {\r
248                                                 // nothing\r
249                                         }\r
250                                 }\r
251                         }\r
252                 }\r
253         }\r
254 #endif\r
255         CShellUpdater::Instance().Flush();\r
256         return bRet;\r
257 }\r