1
2
3
4
5
6
7
8
9
10 package org.eclipse.jgit.api;
11
12 import static org.eclipse.jgit.lib.Constants.DOT_GIT_MODULES;
13 import static org.junit.Assert.assertEquals;
14 import static org.junit.Assert.assertFalse;
15 import static org.junit.Assert.assertTrue;
16
17 import java.io.File;
18 import java.io.IOException;
19 import java.util.Set;
20 import java.util.TreeSet;
21
22 import org.eclipse.jgit.api.errors.GitAPIException;
23 import org.eclipse.jgit.api.errors.NoFilepatternException;
24 import org.eclipse.jgit.errors.NoWorkTreeException;
25 import org.eclipse.jgit.junit.RepositoryTestCase;
26 import org.eclipse.jgit.lib.Repository;
27 import org.junit.Before;
28 import org.junit.Test;
29
30
31
32
33 public class CleanCommandTest extends RepositoryTestCase {
34 private Git git;
35
36 @Override
37 @Before
38 public void setUp() throws Exception {
39 super.setUp();
40 git = new Git(db);
41
42
43 writeTrashFile("File1.txt", "Hello world");
44 writeTrashFile("File2.txt", "Delete Me");
45 writeTrashFile("File3.txt", "Delete Me");
46
47
48 writeTrashFile("sub-noclean/File1.txt", "Hello world");
49 writeTrashFile("sub-noclean/File2.txt", "Delete Me");
50 writeTrashFile("sub-clean/File4.txt", "Delete Me");
51 writeTrashFile("sub-noclean/Ignored.txt", "Ignored");
52 writeTrashFile(".gitignore", "/ignored-dir\n/sub-noclean/Ignored.txt");
53 writeTrashFile("ignored-dir/Ignored2.txt", "Ignored");
54
55
56 git.add().addFilepattern("File1.txt").call();
57 git.add().addFilepattern("sub-noclean/File1.txt").call();
58 git.add().addFilepattern(".gitignore").call();
59 git.commit().setMessage("Initial commit").call();
60 }
61
62 @Test
63 public void testClean() throws NoWorkTreeException, GitAPIException {
64
65 StatusCommand command = git.status();
66 Status status = command.call();
67 Set<String> files = status.getUntracked();
68 assertFalse(files.isEmpty());
69
70
71 Set<String> cleanedFiles = git.clean().call();
72
73 status = git.status().call();
74 files = status.getUntracked();
75
76 assertTrue(files.size() == 1);
77 assertTrue(cleanedFiles.contains("File2.txt"));
78 assertTrue(cleanedFiles.contains("File3.txt"));
79 assertTrue(!cleanedFiles.contains("sub-noclean/File1.txt"));
80 assertTrue(cleanedFiles.contains("sub-noclean/File2.txt"));
81 assertTrue(!cleanedFiles.contains("sub-clean/File4.txt"));
82 }
83
84 @Test
85 public void testCleanDirs() throws NoWorkTreeException, GitAPIException {
86
87 StatusCommand command = git.status();
88 Status status = command.call();
89 Set<String> files = status.getUntracked();
90 assertFalse(files.isEmpty());
91
92
93 Set<String> cleanedFiles = git.clean().setCleanDirectories(true).call();
94
95 status = git.status().call();
96 files = status.getUntracked();
97
98 assertTrue(files.isEmpty());
99 assertTrue(cleanedFiles.contains("File2.txt"));
100 assertTrue(cleanedFiles.contains("File3.txt"));
101 assertTrue(!cleanedFiles.contains("sub-noclean/File1.txt"));
102 assertTrue(cleanedFiles.contains("sub-noclean/File2.txt"));
103 assertTrue(cleanedFiles.contains("sub-clean/"));
104 }
105
106 @Test
107 public void testCleanWithPaths() throws NoWorkTreeException,
108 GitAPIException {
109
110 StatusCommand command = git.status();
111 Status status = command.call();
112 Set<String> files = status.getUntracked();
113 assertFalse(files.isEmpty());
114
115
116 Set<String> paths = new TreeSet<>();
117 paths.add("File3.txt");
118 Set<String> cleanedFiles = git.clean().setPaths(paths).call();
119
120 status = git.status().call();
121 files = status.getUntracked();
122 assertTrue(files.size() == 3);
123 assertTrue(cleanedFiles.contains("File3.txt"));
124 assertFalse(cleanedFiles.contains("File2.txt"));
125 }
126
127 @Test
128 public void testCleanWithDryRun() throws NoWorkTreeException,
129 GitAPIException {
130
131 StatusCommand command = git.status();
132 Status status = command.call();
133 Set<String> files = status.getUntracked();
134 assertFalse(files.isEmpty());
135
136
137 Set<String> cleanedFiles = git.clean().setDryRun(true).call();
138
139 status = git.status().call();
140 files = status.getUntracked();
141
142 assertEquals(4, files.size());
143 assertTrue(cleanedFiles.contains("File2.txt"));
144 assertTrue(cleanedFiles.contains("File3.txt"));
145 assertTrue(!cleanedFiles.contains("sub-noclean/File1.txt"));
146 assertTrue(cleanedFiles.contains("sub-noclean/File2.txt"));
147 }
148
149 @Test
150 public void testCleanDirsWithDryRun() throws NoWorkTreeException,
151 GitAPIException {
152
153 StatusCommand command = git.status();
154 Status status = command.call();
155 Set<String> files = status.getUntracked();
156 assertFalse(files.isEmpty());
157
158
159 Set<String> cleanedFiles = git.clean().setDryRun(true)
160 .setCleanDirectories(true).call();
161
162 status = git.status().call();
163 files = status.getUntracked();
164
165 assertTrue(files.size() == 4);
166 assertTrue(cleanedFiles.contains("File2.txt"));
167 assertTrue(cleanedFiles.contains("File3.txt"));
168 assertTrue(!cleanedFiles.contains("sub-noclean/File1.txt"));
169 assertTrue(cleanedFiles.contains("sub-noclean/File2.txt"));
170 assertTrue(cleanedFiles.contains("sub-clean/"));
171 }
172
173 @Test
174 public void testCleanWithDryRunAndNoIgnore() throws NoWorkTreeException,
175 GitAPIException {
176
177 Set<String> cleanedFiles = git.clean().setDryRun(true).setIgnore(false)
178 .call();
179
180 Status status = git.status().call();
181 Set<String> files = status.getIgnoredNotInIndex();
182
183 assertTrue(files.size() == 2);
184 assertTrue(cleanedFiles.contains("sub-noclean/Ignored.txt"));
185 assertTrue(!cleanedFiles.contains("ignored-dir/"));
186 }
187
188 @Test
189 public void testCleanDirsWithDryRunAndNoIgnore()
190 throws NoWorkTreeException, GitAPIException {
191
192 Set<String> cleanedFiles = git.clean().setDryRun(true).setIgnore(false)
193 .setCleanDirectories(true).call();
194
195 Status status = git.status().call();
196 Set<String> files = status.getIgnoredNotInIndex();
197
198 assertTrue(files.size() == 2);
199 assertTrue(cleanedFiles.contains("sub-noclean/Ignored.txt"));
200 assertTrue(cleanedFiles.contains("ignored-dir/"));
201 }
202
203 @Test
204 public void testCleanDirsWithPrefixFolder() throws Exception {
205 String path = "sub/foo.txt";
206 writeTrashFile(path, "sub is a prefix of sub-noclean");
207 git.add().addFilepattern(path).call();
208 Status beforeCleanStatus = git.status().call();
209 assertTrue(beforeCleanStatus.getAdded().contains(path));
210
211 Set<String> cleanedFiles = git.clean().setCleanDirectories(true).call();
212
213
214 assertTrue(!cleanedFiles.contains(path + "/"));
215
216 assertTrue(cleanedFiles.contains("File2.txt"));
217 assertTrue(cleanedFiles.contains("File3.txt"));
218 assertTrue(!cleanedFiles.contains("sub-noclean/File1.txt"));
219 assertTrue(cleanedFiles.contains("sub-noclean/File2.txt"));
220 assertTrue(cleanedFiles.contains("sub-clean/"));
221 assertTrue(cleanedFiles.size() == 4);
222 }
223
224 @Test
225 public void testCleanDirsWithSubmodule() throws Exception {
226 SubmoduleAddCommand command = new SubmoduleAddCommand(db);
227 String path = "sub";
228 command.setPath(path);
229 String uri = db.getDirectory().toURI().toString();
230 command.setURI(uri);
231 try (Repository repo = command.call()) {
232
233 }
234
235 Status beforeCleanStatus = git.status().call();
236 assertTrue(beforeCleanStatus.getAdded().contains(DOT_GIT_MODULES));
237 assertTrue(beforeCleanStatus.getAdded().contains(path));
238
239 Set<String> cleanedFiles = git.clean().setCleanDirectories(true).call();
240
241
242 assertTrue(!cleanedFiles.contains(path + "/"));
243
244 assertTrue(cleanedFiles.contains("File2.txt"));
245 assertTrue(cleanedFiles.contains("File3.txt"));
246 assertTrue(!cleanedFiles.contains("sub-noclean/File1.txt"));
247 assertTrue(cleanedFiles.contains("sub-noclean/File2.txt"));
248 assertTrue(cleanedFiles.contains("sub-clean/"));
249 assertTrue(cleanedFiles.size() == 4);
250 }
251
252 @Test
253 public void testCleanDirsWithRepository() throws Exception {
254
255 String innerRepoName = "inner-repo";
256 File innerDir = new File(trash, innerRepoName);
257 innerDir.mkdir();
258 InitCommand initRepoCommand = new InitCommand();
259 initRepoCommand.setDirectory(innerDir);
260 initRepoCommand.call();
261
262 Status beforeCleanStatus = git.status().call();
263 Set<String> untrackedFolders = beforeCleanStatus.getUntrackedFolders();
264 Set<String> untrackedFiles = beforeCleanStatus.getUntracked();
265
266
267 assertTrue(untrackedFiles.contains(innerRepoName));
268
269
270 assertTrue(!untrackedFolders.contains(innerRepoName));
271
272 Set<String> cleanedFiles = git.clean().setCleanDirectories(true).call();
273
274
275 assertTrue(!cleanedFiles.contains(innerRepoName + "/"));
276
277 assertTrue(cleanedFiles.contains("File2.txt"));
278 assertTrue(cleanedFiles.contains("File3.txt"));
279 assertTrue(!cleanedFiles.contains("sub-noclean/File1.txt"));
280 assertTrue(cleanedFiles.contains("sub-noclean/File2.txt"));
281 assertTrue(cleanedFiles.contains("sub-clean/"));
282 assertTrue(cleanedFiles.size() == 4);
283
284 Set<String> forceCleanedFiles = git.clean().setCleanDirectories(true)
285 .setForce(true).call();
286
287
288 assertTrue(forceCleanedFiles.contains(innerRepoName + "/"));
289 }
290
291 @Test
292
293
294 public void testFilesShouldBeCleanedInSubSubFolders()
295 throws IOException, NoFilepatternException, GitAPIException {
296 writeTrashFile(".gitignore",
297 "/ignored-dir\n/sub-noclean/Ignored.txt\n/this_is_ok\n/this_is/not_ok\n");
298 git.add().addFilepattern(".gitignore").call();
299 git.commit().setMessage("adding .gitignore").call();
300 writeTrashFile("this_is_ok/more/subdirs/file.txt", "1");
301 writeTrashFile("this_is/not_ok/more/subdirs/file.txt", "2");
302 git.clean().setCleanDirectories(true).setIgnore(false).call();
303 }
304 }