Fixed issue #3859: Incorrect count of removed files if some files do not exist
[TortoiseGit.git] / src / TortoiseProc / Commands / RemoveCommand.cpp
blob472aec0bd0c8559b44fd4fb46d46090e085e6ce1
1 // TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2009-2013, 2015-2019, 2022 - TortoiseGit
4 // Copyright (C) 2007-2008 - TortoiseSVN
6 // This program is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU General Public License
8 // as published by the Free Software Foundation; either version 2
9 // of the License, or (at your option) any later version.
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software Foundation,
18 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 #include "stdafx.h"
21 #include "RemoveCommand.h"
23 #include "MessageBox.h"
24 #include "Git.h"
25 #include "ShellUpdater.h"
27 bool RemoveCommand::Execute()
29 if (!GitAdminDir::HasAdminDir(g_Git.m_CurrentDir))
31 CMessageBox::Show(GetExplorerHWND(), IDS_NOWORKINGCOPY, IDS_APPNAME, MB_ICONERROR);
32 return false;
35 bool bRet = false;
36 // removing items from a working copy is done item-by-item so we
37 // have a chance to show a progress bar
39 // removing items from an URL in the repository requires that we
40 // ask the user for a log message.
41 #if 0
42 BOOL bForce = FALSE;
43 SVN svn;
44 if ((!pathList.IsEmpty())&&(SVN::PathIsURL(pathList[0])))
46 // Delete using URL's, not wc paths
47 svn.SetPromptApp(&theApp);
48 CInputLogDlg dlg;
49 CString sUUID;
50 svn.GetRepositoryRootAndUUID(pathList[0], sUUID);
51 dlg.SetUUID(sUUID);
52 CString sHint;
53 if (pathList.GetCount() == 1)
54 sHint.Format(IDS_INPUT_REMOVEONE, static_cast<LPCWSTR>(pathList)[0].GetSVNPathString());
55 else
56 sHint.Format(IDS_INPUT_REMOVEMORE, pathList.GetCount());
57 dlg.SetActionText(sHint);
58 if (dlg.DoModal()==IDOK)
60 if (!svn.Remove(pathList, TRUE, parser.HasKey(L"keep"), dlg.GetLogMessage()))
62 CMessageBox::Show(GetExplorerHWND(), svn.GetLastErrorMessage(), L"TortoiseGit", MB_ICONERROR);
63 return FALSE;
65 return true;
67 return FALSE;
69 else
71 for (int nPath = 0; nPath < pathList.GetCount(); ++nPath)
73 CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) L": remove file %s\n", static_cast<LPCWSTR>(pathList)[nPath].GetUIPathString());
74 // even though SVN::Remove takes a list of paths to delete at once
75 // we delete each item individually so we can prompt the user
76 // if something goes wrong or unversioned/modified items are
77 // to be deleted
78 CTSVNPathList removePathList(pathList[nPath]);
79 if (bForce)
81 CTSVNPath delPath = removePathList[0];
82 delPath.Delete(true);
84 if (!svn.Remove(removePathList, bForce, parser.HasKey(L"keep")))
86 if ((svn.Err->apr_err == SVN_ERR_UNVERSIONED_RESOURCE) ||
87 (svn.Err->apr_err == SVN_ERR_CLIENT_MODIFIED))
89 CString msg, yes, no, yestoall;
90 if (pathList[nPath].IsDirectory())
91 msg.Format(IDS_PROC_REMOVEFORCEFOLDER, pathList[nPath].GetWinPath());
92 else
93 msg.Format(IDS_PROC_REMOVEFORCE, static_cast<LPCWSTR>(svn.GetLastErrorMessage()));
94 yes.LoadString(IDS_MSGBOX_YES);
95 no.LoadString(IDS_MSGBOX_NO);
96 yestoall.LoadString(IDS_PROC_YESTOALL);
97 UINT ret = CMessageBox::Show(GetExplorerHWND(), msg, L"TortoiseGit", 2, IDI_ERROR, yes, no, yestoall);
98 if (ret == 3)
99 bForce = TRUE;
100 if ((ret == 1)||(ret==3))
102 CTSVNPath delPath = removePathList[0];
103 delPath.Delete(true);
104 if (!svn.Remove(removePathList, TRUE, parser.HasKey(L"keep")))
105 CMessageBox::Show(GetExplorerHWND(), svn.GetLastErrorMessage(), L"TortoiseGit", MB_ICONERROR);
106 else
107 bRet = true;
110 else
111 CMessageBox::Show(GetExplorerHWND(), svn.GetLastErrorMessage(), L"TortoiseGit", MB_ICONERROR);
115 if (bRet)
116 CShellUpdater::Instance().AddPathsForUpdate(pathList);
117 #endif
119 //we don't ask user about if keep local copy.
120 //because there are command "Delete(keep local copy)" at explore context menu
121 //int key = CMessageBox::Show(GetExplorerHWND(), L"File will removed from version control\r\n Do you want to keep local copy", L"TortoiseGit", MB_ICONINFORMATION | MB_YESNOCANCEL);
122 //if(key == IDCANCEL)
124 CString format;
125 BOOL keepLocal = parser.HasKey(L"keep");
126 if (pathList.GetCount() > 1)
127 format.Format(keepLocal ? IDS_WARN_DELETE_MANY_FROM_INDEX : IDS_WARN_DELETE_MANY, pathList.GetCount());
128 else
129 format.Format(keepLocal ? IDS_WARN_DELETE_ONE_FROM_INDEX : IDS_WARN_REMOVE, static_cast<LPCWSTR>(pathList[0].GetGitPathString()));
130 if (CMessageBox::Show(GetExplorerHWND(), format, L"TortoiseGit", 2, IDI_QUESTION, CString(MAKEINTRESOURCE(IDS_REMOVEBUTTON)), CString(MAKEINTRESOURCE(IDS_MSGBOX_ABORT))) == 2)
131 return false;
133 if (keepLocal)
134 format= L"git.exe rm -r -f --cached -- \"%s\"";
135 else
136 format = L"git.exe rm -r -f -- \"%s\"";
138 int pathsHandled = 0;
139 for (int nPath = 0; nPath < pathList.GetCount(); ++nPath)
141 CString cmd;
142 CString output;
143 cmd.Format(format, static_cast<LPCWSTR>(pathList[nPath].GetGitPathString()));
144 if (g_Git.Run(cmd, &output, CP_UTF8))
146 if (CMessageBox::Show(GetExplorerHWND(), output, L"TortoiseGit", 2, IDI_ERROR, CString(MAKEINTRESOURCE(IDS_IGNOREBUTTON)), CString(MAKEINTRESOURCE(IDS_ABORTBUTTON))) == 2)
148 bRet = FALSE;
149 break;
152 else
153 ++pathsHandled;
156 CString output;
157 output.Format(IDS_PROC_FILESREMOVED, pathsHandled);
159 CShellUpdater::Instance().AddPathsForUpdate(pathList);
161 CMessageBox::Show(GetExplorerHWND(), output, L"TortoiseGit", MB_ICONINFORMATION | MB_OK);
163 CShellUpdater::Instance().Flush();
164 return bRet;