summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CleanCommandTest.java40
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/api/CleanCommand.java84
2 files changed, 113 insertions, 11 deletions
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CleanCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CleanCommandTest.java
index 7daa9957dc..68f5dd1e0d 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CleanCommandTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CleanCommandTest.java
@@ -47,6 +47,7 @@ import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.eclipse.jgit.lib.Constants.DOT_GIT_MODULES;
+import java.io.File;
import java.util.Set;
import java.util.TreeSet;
@@ -255,4 +256,43 @@ public class CleanCommandTest extends RepositoryTestCase {
assertTrue(cleanedFiles.contains("sub-clean/"));
assertTrue(cleanedFiles.size() == 4);
}
+
+ @Test
+ public void testCleanDirsWithRepository() throws Exception {
+ // Set up a repository inside the outer repository
+ String innerRepoName = "inner-repo";
+ File innerDir = new File(trash, innerRepoName);
+ innerDir.mkdir();
+ InitCommand initRepoCommand = new InitCommand();
+ initRepoCommand.setDirectory(innerDir);
+ initRepoCommand.call();
+
+ Status beforeCleanStatus = git.status().call();
+ Set<String> untrackedFolders = beforeCleanStatus.getUntrackedFolders();
+ Set<String> untrackedFiles = beforeCleanStatus.getUntracked();
+
+ // The inner repository should be listed as an untracked file
+ assertTrue(untrackedFiles.contains(innerRepoName));
+
+ // The inner repository should not be listed as an untracked folder
+ assertTrue(!untrackedFolders.contains(innerRepoName));
+
+ Set<String> cleanedFiles = git.clean().setCleanDirectories(true).call();
+
+ // The inner repository should not be cleaned.
+ assertTrue(!cleanedFiles.contains(innerRepoName + "/"));
+
+ assertTrue(cleanedFiles.contains("File2.txt"));
+ assertTrue(cleanedFiles.contains("File3.txt"));
+ assertTrue(!cleanedFiles.contains("sub-noclean/File1.txt"));
+ assertTrue(cleanedFiles.contains("sub-noclean/File2.txt"));
+ assertTrue(cleanedFiles.contains("sub-clean/"));
+ assertTrue(cleanedFiles.size() == 4);
+
+ Set<String> forceCleanedFiles = git.clean().setCleanDirectories(true)
+ .setForce(true).call();
+
+ // The inner repository should be cleaned this time
+ assertTrue(forceCleanedFiles.contains(innerRepoName + "/"));
+ }
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/CleanCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/CleanCommand.java
index 5967128113..7e331fd844 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/CleanCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/CleanCommand.java
@@ -43,6 +43,8 @@
*/
package org.eclipse.jgit.api;
+import static org.eclipse.jgit.lib.Constants.DOT_GIT;
+
import java.io.File;
import java.io.IOException;
import java.util.Collections;
@@ -73,6 +75,8 @@ public class CleanCommand extends GitCommand<Set<String>> {
private boolean ignore = true;
+ private boolean force = false;
+
/**
* @param repo
*/
@@ -121,25 +125,69 @@ public class CleanCommand extends GitCommand<Set<String>> {
for (String file : notIgnoredFiles)
if (paths.isEmpty() || paths.contains(file)) {
- if (!dryRun)
- FileUtils.delete(new File(repo.getWorkTree(), file));
- files.add(file);
+ files = cleanPath(file, files);
}
- if (directories)
- for (String dir : notIgnoredDirs)
- if (paths.isEmpty() || paths.contains(dir)) {
- if (!dryRun)
- FileUtils.delete(new File(repo.getWorkTree(), dir),
- FileUtils.RECURSIVE);
- files.add(dir + "/"); //$NON-NLS-1$
- }
+ for (String dir : notIgnoredDirs)
+ if (paths.isEmpty() || paths.contains(dir)) {
+ files = cleanPath(dir, files);
+ }
} catch (IOException e) {
throw new JGitInternalException(e.getMessage(), e);
}
return files;
}
+ /**
+ * When dryRun is false, deletes the specified path from disk. If dryRun
+ * is true, no paths are actually deleted. In both cases, the paths that
+ * would have been deleted are added to inFiles and returned.
+ *
+ * Paths that are directories are recursively deleted when
+ * {@link #directories} is true.
+ * Paths that are git repositories are recursively deleted when
+ * {@link #directories} and {@link #force} are both true.
+ *
+ * @param path
+ * The path to be cleaned
+ * @param inFiles
+ * A set of strings representing the files that have been cleaned
+ * already, the path to be cleaned will be added to this set
+ * before being returned.
+ *
+ * @return a set of strings with the cleaned path added to it
+ * @throws IOException
+ */
+ private Set<String> cleanPath(String path, Set<String> inFiles)
+ throws IOException {
+ File curFile = new File(repo.getWorkTree(), path);
+ if (curFile.isDirectory()) {
+ if (directories) {
+ // Is this directory a git repository?
+ if (new File(curFile, DOT_GIT).exists()) {
+ if (force) {
+ if (!dryRun) {
+ FileUtils.delete(curFile, FileUtils.RECURSIVE);
+ }
+ inFiles.add(path + "/"); //$NON-NLS-1$
+ }
+ } else {
+ if (!dryRun) {
+ FileUtils.delete(curFile, FileUtils.RECURSIVE);
+ }
+ inFiles.add(path + "/"); //$NON-NLS-1$
+ }
+ }
+ } else {
+ if (!dryRun) {
+ FileUtils.delete(curFile, FileUtils.NONE);
+ }
+ inFiles.add(path);
+ }
+
+ return inFiles;
+ }
+
private Set<String> filterIgnorePaths(Set<String> inputPaths,
Set<String> ignoredNotInIndex, boolean exact) {
if (ignore) {
@@ -196,6 +244,20 @@ public class CleanCommand extends GitCommand<Set<String>> {
}
/**
+ * If force is set, directories that are git repositories will also be
+ * deleted.
+ *
+ * @param force
+ * whether or not to delete git repositories
+ * @return {@code this}
+ * @since 4.5
+ */
+ public CleanCommand setForce(boolean force) {
+ this.force = force;
+ return this;
+ }
+
+ /**
* If dirs is set, in addition to files, also clean directories.
*
* @param dirs