@Test public void testSomeCommits() throws NoHeadException, NoMessageException, UnmergedPathException, ConcurrentRefUpdateException, JGitInternalException, WrongRepositoryStateException { // do 4 commits Git git = new Git(db); git.commit().setMessage("initial commit").call(); git.commit().setMessage("second commit").setCommitter(committer).call(); git.commit().setMessage("third commit").setAuthor(author).call(); git.commit().setMessage("fourth commit").setAuthor(author).setCommitter(committer).call(); Iterable<RevCommit> commits = git.log().call(); // check that all commits came in correctly PersonIdent defaultCommitter = new PersonIdent(db); PersonIdent expectedAuthors[] = new PersonIdent[] {defaultCommitter, committer, author, author}; PersonIdent expectedCommitters[] = new PersonIdent[] {defaultCommitter, committer, defaultCommitter, committer}; String expectedMessages[] = new String[] {"initial commit", "second commit", "third commit", "fourth commit"}; int l = expectedAuthors.length - 1; for (RevCommit c : commits) { assertEquals(expectedAuthors[l].getName(), c.getAuthorIdent().getName()); assertEquals(expectedCommitters[l].getName(), c.getCommitterIdent().getName()); assertEquals(c.getFullMessage(), expectedMessages[l]); l--; } assertEquals(l, -1); }
private static boolean pushCurrentBranch( @NotNull Project project, @NotNull GitRepository repository, @NotNull String remoteName, @NotNull String remoteUrl, @NotNull String name, @NotNull String url) { Git git = ServiceManager.getService(Git.class); GitLocalBranch currentBranch = repository.getCurrentBranch(); if (currentBranch == null) { GithubNotifications.showErrorURL( project, "Can't finish GitHub sharing process", "Successfully created project ", "'" + name + "'", " on GitHub, but initial push failed: no current branch", url); return false; } GitCommandResult result = git.push(repository, remoteName, remoteUrl, currentBranch.getName(), true); if (!result.success()) { GithubNotifications.showErrorURL( project, "Can't finish GitHub sharing process", "Successfully created project ", "'" + name + "'", " on GitHub, but initial push failed:<br/>" + result.getErrorOutputAsHtmlString(), url); return false; } return true; }
@Test public void testAddUnstagedChanges() throws IOException, NoHeadException, NoMessageException, ConcurrentRefUpdateException, JGitInternalException, WrongRepositoryStateException, NoFilepatternException { File file = new File(db.getWorkTree(), "a.txt"); FileUtils.createNewFile(file); PrintWriter writer = new PrintWriter(file); writer.print("content"); writer.close(); Git git = new Git(db); git.add().addFilepattern("a.txt").call(); RevCommit commit = git.commit().setMessage("initial commit").call(); TreeWalk tw = TreeWalk.forPath(db, "a.txt", commit.getTree()); assertEquals("6b584e8ece562ebffc15d38808cd6b98fc3d97ea", tw.getObjectId(0).getName()); writer = new PrintWriter(file); writer.print("content2"); writer.close(); commit = git.commit().setMessage("second commit").call(); tw = TreeWalk.forPath(db, "a.txt", commit.getTree()); assertEquals("6b584e8ece562ebffc15d38808cd6b98fc3d97ea", tw.getObjectId(0).getName()); commit = git.commit().setAll(true).setMessage("third commit").setAll(true).call(); tw = TreeWalk.forPath(db, "a.txt", commit.getTree()); assertEquals("db00fd65b218578127ea51f3dffac701f12f486a", tw.getObjectId(0).getName()); }
@Test public void testPathsResetWithUnmerged() throws Exception { setupRepository(); String file = "a.txt"; writeTrashFile(file, "data"); git.add().addFilepattern(file).call(); git.commit().setMessage("commit").call(); DirCache index = db.lockDirCache(); DirCacheBuilder builder = index.builder(); builder.add(createEntry(file, FileMode.REGULAR_FILE, 1, "")); builder.add(createEntry(file, FileMode.REGULAR_FILE, 2, "")); builder.add(createEntry(file, FileMode.REGULAR_FILE, 3, "")); builder.add(createEntry("b.txt", FileMode.REGULAR_FILE)); assertTrue(builder.commit()); assertEquals( "[a.txt, mode:100644, stage:1]" + "[a.txt, mode:100644, stage:2]" + "[a.txt, mode:100644, stage:3]" + "[b.txt, mode:100644]", indexState(0)); git.reset().addPath(file).call(); assertEquals("[a.txt, mode:100644]" + "[b.txt, mode:100644]", indexState(0)); }
@Test(expected = JGitInternalException.class) public void testPathsResetToNonexistingRef() throws Exception { git = new Git(db); writeTrashFile("a.txt", "content"); git.add().addFilepattern("a.txt").call(); git.reset().setRef("doesnotexist").addPath("a.txt").call(); }
@Test public void testCleanDirsWithSubmodule() throws Exception { SubmoduleAddCommand command = new SubmoduleAddCommand(db); String path = "sub"; command.setPath(path); String uri = db.getDirectory().toURI().toString(); command.setURI(uri); Repository repo = command.call(); repo.close(); Status beforeCleanStatus = git.status().call(); assertTrue(beforeCleanStatus.getAdded().contains(DOT_GIT_MODULES)); assertTrue(beforeCleanStatus.getAdded().contains(path)); Set<String> cleanedFiles = git.clean().setCleanDirectories(true).call(); // The submodule should not be cleaned. assertTrue(!cleanedFiles.contains(path + "/")); 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); }
/* * Use the binary git repo and/or the remote service to figure out * the new commits made since the last pull on source repository. */ public void findNewCommits() throws GitException { // get the history from binary repository Git bingit = Git.wrap(binaryRepository); RevWalk binwalk = new RevWalk(binaryRepository); Iterable<RevCommit> logs; try { logs = bingit.log().call(); Iterator<RevCommit> i = logs.iterator(); while (i.hasNext()) { RevCommit commit = binwalk.parseCommit(i.next()); System.out.println(commit.getFullMessage()); } } catch (NoHeadException e) { // TODO Auto-generated catch block throw new GitException(e); } catch (GitAPIException e) { throw new GitException(e); } catch (MissingObjectException e) { throw new GitException(e); } catch (IncorrectObjectTypeException e) { throw new GitException(e); } catch (IOException e) { throw new GitException(e); } }
@Override @Before public void setUp() throws Exception { super.setUp(); dbTarget = createWorkRepository(); source = new Git(db); target = new Git(dbTarget); // put some file in the source repo sourceFile = new File(db.getWorkTree(), "SomeFile.txt"); writeToFile(sourceFile, "Hello world"); // and commit it source.add().addFilepattern("SomeFile.txt").call(); source.commit().setMessage("Initial commit for source").call(); // configure the target repo to connect to the source via "origin" StoredConfig targetConfig = dbTarget.getConfig(); targetConfig.setString("branch", "master", "remote", "origin"); targetConfig.setString("branch", "master", "merge", "refs/heads/master"); RemoteConfig config = new RemoteConfig(targetConfig, "origin"); config.addURI(new URIish(source.getRepository().getWorkTree().getPath())); config.addFetchRefSpec(new RefSpec("+refs/heads/*:refs/remotes/origin/*")); config.update(targetConfig); targetConfig.save(); targetFile = new File(dbTarget.getWorkTree(), "SomeFile.txt"); // make sure we have the same content target.pull().call(); assertFileContentsEqual(targetFile, "Hello world"); }
@Test public void testPathsResetWithRef() throws Exception { setupRepository(); DirCacheEntry preReset = DirCache.read(db.getIndexFile(), db.getFS()).getEntry(indexFile.getName()); assertNotNull(preReset); git.add().addFilepattern(untrackedFile.getName()).call(); // 'a.txt' has already been modified in setupRepository // 'notAddedToIndex.txt' has been added to repository // reset to the inital commit git.reset() .setRef(initialCommit.getName()) .addPath(indexFile.getName()) .addPath(untrackedFile.getName()) .call(); // check that HEAD hasn't moved ObjectId head = db.resolve(Constants.HEAD); assertEquals(secondCommit, head); // check if files still exist assertTrue(untrackedFile.exists()); assertTrue(indexFile.exists()); assertTrue(inHead(indexFile.getName())); assertFalse(inIndex(indexFile.getName())); assertFalse(inIndex(untrackedFile.getName())); }
private boolean cherryPick( HttpServletRequest request, HttpServletResponse response, Repository db, String commitToCherryPick) throws ServletException, JSONException { RevWalk revWalk = new RevWalk(db); try { Ref headRef = db.getRef(Constants.HEAD); if (headRef == null) return statusHandler.handleRequest( request, response, new ServerStatus( IStatus.ERROR, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "An error occured when cherry-picking.", null)); RevCommit head = revWalk.parseCommit(headRef.getObjectId()); ObjectId objectId = db.resolve(commitToCherryPick); Git git = new Git(db); CherryPickResult cherryPickResult = git.cherryPick().include(objectId).call(); RevCommit newHead = cherryPickResult.getNewHead(); JSONObject result = new JSONObject(); result.put(GitConstants.KEY_RESULT, cherryPickResult.getStatus().name()); result.put(GitConstants.KEY_HEAD_UPDATED, !head.equals(newHead)); OrionServlet.writeJSONResponse( request, response, result, JsonURIUnqualificationStrategy.ALL_NO_GIT); return true; } catch (IOException e) { return statusHandler.handleRequest( request, response, new ServerStatus( IStatus.ERROR, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "An error occured when cherry-picking.", e)); } catch (GitAPIException e) { return statusHandler.handleRequest( request, response, new ServerStatus( IStatus.ERROR, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "An error occured when cherry-picking.", e)); } finally { revWalk.release(); } }
/** * Git can execute simple git command. * * @throws Exception If something is wrong */ @Test @org.junit.Ignore public void clonesSimpleGitRepository() throws Exception { final File key = this.temp.newFile(); FileUtils.writeStringToFile(key, ""); final File folder = this.temp.newFolder(); final Git git = new Git(key, folder); MatcherAssert.assertThat( git.exec(folder.getParentFile(), "init", this.temp.newFolder().getPath()), Matchers.containsString("Initialized empty Git repository")); }
@Test public void logAllCommitsWithSkipAndMaxCount() throws Exception { Git git = Git.wrap(db); List<RevCommit> commits = createCommits(git); Iterator<RevCommit> log = git.log().all().setSkip(1).setMaxCount(1).call().iterator(); assertTrue(log.hasNext()); RevCommit commit = log.next(); assertTrue(commits.contains(commit)); assertEquals("commit#2", commit.getShortMessage()); assertFalse(log.hasNext()); }
// try to do a commit without specifying a message. Should fail! @Test public void testWrongParams() throws UnmergedPathException, NoHeadException, ConcurrentRefUpdateException, JGitInternalException, WrongRepositoryStateException { Git git = new Git(db); try { git.commit().setAuthor(author).call(); fail("Didn't get the expected exception"); } catch (NoMessageException e) { // expected } }
@Test public void testPathsResetOnUnbornBranch() throws Exception { git = new Git(db); writeTrashFile("a.txt", "content"); git.add().addFilepattern("a.txt").call(); // Should assume an empty tree, like in C Git 1.8.2 git.reset().addPath("a.txt").call(); DirCache cache = db.readDirCache(); DirCacheEntry aEntry = cache.getEntry("a.txt"); assertNull(aEntry); }
@Test public void testCleanWithDryRunAndNoIgnore() throws NoWorkTreeException, GitAPIException { // run clean Set<String> cleanedFiles = git.clean().setDryRun(true).setIgnore(false).call(); Status status = git.status().call(); Set<String> files = status.getIgnoredNotInIndex(); assertTrue(files.size() == 2); assertTrue(cleanedFiles.contains("sub-noclean/Ignored.txt")); assertTrue(!cleanedFiles.contains("ignored-dir/")); }
@Test public void testCloneRepository() { try { File directory = createTempDirectory("testCloneRepository"); CloneCommand command = Git.cloneRepository(); command.setDirectory(directory); command.setURI("file://" + git.getRepository().getWorkTree().getPath()); Git git2 = command.call(); assertNotNull(git2); } catch (Exception e) { fail(e.getMessage()); } }
@Test public void testHardResetOnUnbornBranch() throws Exception { git = new Git(db); File fileA = writeTrashFile("a.txt", "content"); git.add().addFilepattern("a.txt").call(); // Should assume an empty tree, like in C Git 1.8.2 git.reset().setMode(ResetType.HARD).call(); DirCache cache = db.readDirCache(); DirCacheEntry aEntry = cache.getEntry("a.txt"); assertNull(aEntry); assertFalse(fileA.exists()); assertNull(db.resolve(Constants.HEAD)); }
private boolean applyPatch( HttpServletRequest request, HttpServletResponse response, Repository db, String contentType) throws ServletException { try { String patch = readPatch(request.getInputStream(), contentType); Git git = new Git(db); ApplyCommand applyCommand = git.apply(); applyCommand.setPatch(IOUtilities.toInputStream(patch)); // TODO: ignore all errors for now, see bug 366008 try { ApplyResult applyResult = applyCommand.call(); JSONObject resp = new JSONObject(); JSONArray modifiedFieles = new JSONArray(); for (File file : applyResult.getUpdatedFiles()) { modifiedFieles.put(stripGlobalPaths(db, file.getAbsolutePath())); } resp.put("modifiedFieles", modifiedFieles); return statusHandler.handleRequest( request, response, new ServerStatus(Status.OK_STATUS, HttpServletResponse.SC_OK, resp)); // OrionServlet.writeJSONResponse(request, response, toJSON(applyResult)); } catch (PatchFormatException e) { return statusHandler.handleRequest( request, response, new ServerStatus( IStatus.ERROR, HttpServletResponse.SC_BAD_REQUEST, stripGlobalPaths(db, e.getMessage()), null)); } catch (PatchApplyException e) { return statusHandler.handleRequest( request, response, new ServerStatus( IStatus.ERROR, HttpServletResponse.SC_BAD_REQUEST, stripGlobalPaths(db, e.getMessage()), null)); } } catch (Exception e) { return statusHandler.handleRequest( request, response, new ServerStatus( IStatus.ERROR, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "An error occured when reading the patch.", e)); } }
@Test public void testPullConflict() throws Exception { PullResult res = target.pull().call(); // nothing to update since we don't have different data yet assertTrue(res.getFetchResult().getTrackingRefUpdates().isEmpty()); assertTrue(res.getMergeResult().getMergeStatus().equals(MergeStatus.ALREADY_UP_TO_DATE)); assertFileContentsEqual(targetFile, "Hello world"); // change the source file writeToFile(sourceFile, "Source change"); source.add().addFilepattern("SomeFile.txt").call(); source.commit().setMessage("Source change in remote").call(); // change the target file writeToFile(targetFile, "Target change"); target.add().addFilepattern("SomeFile.txt").call(); target.commit().setMessage("Target change in local").call(); res = target.pull().call(); String sourceChangeString = "Source change\n>>>>>>> branch 'refs/heads/master' of " + target.getRepository().getConfig().getString("remote", "origin", "url"); assertFalse(res.getFetchResult().getTrackingRefUpdates().isEmpty()); assertEquals(res.getMergeResult().getMergeStatus(), MergeStatus.CONFLICTING); String result = "<<<<<<< HEAD\nTarget change\n=======\n" + sourceChangeString + "\n"; assertFileContentsEqual(targetFile, result); assertEquals(RepositoryState.MERGING, target.getRepository().getRepositoryState()); }
/** * Returns absolute paths which have changed remotely comparing to the current branch, i.e. * performs <code>git diff --name-only master..origin/master</code> * * <p>Paths are absolute, Git-formatted (i.e. with forward slashes). */ @NotNull public static Collection<String> getPathsDiffBetweenRefs( @NotNull Git git, @NotNull GitRepository repository, @NotNull String beforeRef, @NotNull String afterRef) throws VcsException { List<String> parameters = Arrays.asList("--name-only", "--pretty=format:"); String range = beforeRef + ".." + afterRef; GitCommandResult result = git.diff(repository, parameters, range); if (!result.success()) { LOG.info( String.format( "Couldn't get diff in range [%s] for repository [%s]", range, repository.toLogString())); return Collections.emptyList(); } final Collection<String> remoteChanges = new HashSet<String>(); for (StringScanner s = new StringScanner(result.getOutputAsJoinedString()); s.hasMoreData(); ) { final String relative = s.line(); if (StringUtil.isEmptyOrSpaces(relative)) { continue; } final String path = repository.getRoot().getPath() + "/" + unescapePath(relative); remoteChanges.add(path); } return remoteChanges; }
@Test public void testCommitAmend() throws NoHeadException, NoMessageException, UnmergedPathException, ConcurrentRefUpdateException, JGitInternalException, WrongRepositoryStateException { Git git = new Git(db); git.commit().setMessage("first comit").call(); // typo git.commit().setAmend(true).setMessage("first commit").call(); Iterable<RevCommit> commits = git.log().call(); int c = 0; for (RevCommit commit : commits) { assertEquals("first commit", commit.getFullMessage()); c++; } assertEquals(1, c); }
public Repository call() throws JGitInternalException { checkCallable(); if (path == null || path.length() == 0) throw new IllegalArgumentException(JGitText.get().pathNotConfigured); if (uri == null || uri.length() == 0) throw new IllegalArgumentException(JGitText.get().uriNotConfigured); try { if (submoduleExists()) throw new JGitInternalException(MessageFormat.format(JGitText.get().submoduleExists, path)); } catch (IOException e) { throw new JGitInternalException(e.getMessage(), e); } // Clone submodule repository File moduleDirectory = SubmoduleWalk.getSubmoduleDirectory(repo, path); CloneCommand clone = Git.cloneRepository(); clone.setDirectory(moduleDirectory); clone.setURI(uri); if (monitor != null) clone.setProgressMonitor(monitor); if (credentialsProvider != null) clone.setCredentialsProvider(credentialsProvider); Repository subRepo = clone.call().getRepository(); // Save submodule URL to parent repository's config StoredConfig config = repo.getConfig(); config.setString( ConfigConstants.CONFIG_SUBMODULE_SECTION, path, ConfigConstants.CONFIG_KEY_URL, uri); try { config.save(); } catch (IOException e) { throw new JGitInternalException(e.getMessage(), e); } // Save path and URL to parent repository's .gitmodules file FileBasedConfig modulesConfig = new FileBasedConfig(new File(repo.getWorkTree(), Constants.DOT_GIT_MODULES), repo.getFS()); modulesConfig.setString( ConfigConstants.CONFIG_SUBMODULE_SECTION, path, ConfigConstants.CONFIG_KEY_PATH, path); modulesConfig.setString( ConfigConstants.CONFIG_SUBMODULE_SECTION, path, ConfigConstants.CONFIG_KEY_URL, uri); try { modulesConfig.save(); } catch (IOException e) { throw new JGitInternalException(e.getMessage(), e); } AddCommand add = new AddCommand(repo); // Add .gitmodules file to parent repository's index add.addFilepattern(Constants.DOT_GIT_MODULES); // Add submodule directory to parent repository's index add.addFilepattern(path); try { add.call(); } catch (NoFilepatternException e) { throw new JGitInternalException(e.getMessage(), e); } return subRepo; }
@Command("\\.rev") public void rev(CommandContext ctx) { final Git.Revision rev = this.bot.revision; ctx.respond( "Currently on revision %(#hash)s by %(#author)s -- %(#description)s", rev.getHash(), rev.getAuthor(), rev.getDescription()); ctx.respond("%s", Git.revisionLink(rev)); }
@Test public void testHardResetOnTag() throws Exception { setupRepository(); String tagName = "initialtag"; git.tag().setName(tagName).setObjectId(secondCommit).setMessage("message").call(); DirCacheEntry preReset = DirCache.read(db.getIndexFile(), db.getFS()).getEntry(indexFile.getName()); assertNotNull(preReset); git.add().addFilepattern(untrackedFile.getName()).call(); git.reset().setRef(tagName).setMode(HARD).call(); ObjectId head = db.resolve(Constants.HEAD); assertEquals(secondCommit, head); }
@Test public void testHardResetAfterSquashMerge() throws Exception { Git g = new Git(db); writeTrashFile("file1", "file1"); g.add().addFilepattern("file1").call(); RevCommit first = g.commit().setMessage("initial commit").call(); assertTrue(resolve(db.getWorkTree(), "file1").exists()); createBranch(first, "refs/heads/branch1"); checkoutBranch("refs/heads/branch1"); writeTrashFile("file2", "file2"); g.add().addFilepattern("file2").call(); g.commit().setMessage("second commit").call(); assertTrue(resolve(db.getWorkTree(), "file2").exists()); checkoutBranch("refs/heads/master"); MergeResult result = g.merge().include(db.getRef("branch1")).setSquash(true).call(); assertEquals(MergeResult.MergeStatus.FAST_FORWARD_SQUASHED, result.getMergeStatus()); assertNotNull(db.readSquashCommitMsg()); g.reset().setMode(ResetType.HARD).setRef(first.getName()).call(); assertNull(db.readSquashCommitMsg()); }
public void setUp() throws Exception { super.setUp(); git = new Git(db); // commit something writeTrashFile("Test.txt", "Hello world"); git.add().addFilepattern("Test.txt").call(); git.commit().setMessage("Initial commit").call(); // create a master branch and switch to it git.branchCreate().setName("test").call(); RefUpdate rup = db.updateRef(Constants.HEAD); rup.link("refs/heads/test"); // commit something on the test branch writeTrashFile("Test.txt", "Some change"); git.add().addFilepattern("Test.txt").call(); git.commit().setMessage("Second commit").call(); }
public void setupRepository() throws IOException, JGitInternalException, GitAPIException { // create initial commit git = new Git(db); initialCommit = git.commit().setMessage("initial commit").call(); // create nested file File dir = resolve(db.getWorkTree(), "dir"); FileUtils.mkdir(dir); File nestedFile = resolve(dir, "b.txt"); FileUtils.createNewFile(nestedFile); PrintWriter nesterFileWriter = getPrintWriter(nestedFile); nesterFileWriter.print("content"); nesterFileWriter.flush(); // create file indexFile = resolve(db.getWorkTree(), "a.txt"); FileUtils.createNewFile(indexFile); PrintWriter writer = getPrintWriter(indexFile); writer.print("content"); writer.flush(); // add file and commit it git.add().addFilepattern("dir").addFilepattern("a.txt").call(); secondCommit = git.commit().setMessage("adding a.txt and dir/b.txt").call(); prestage = DirCache.read(db.getIndexFile(), db.getFS()).getEntry(indexFile.getName()); // modify file and add to index writer.print("new content"); writer.close(); nesterFileWriter.print("new content"); nesterFileWriter.close(); git.add().addFilepattern("a.txt").addFilepattern("dir").call(); // create a file not added to the index untrackedFile = resolve(db.getWorkTree(), "notAddedToIndex.txt"); FileUtils.createNewFile(untrackedFile); PrintWriter writer2 = getPrintWriter(untrackedFile); writer2.print("content"); writer2.close(); }
@Test public void testCleanWithPaths() throws NoWorkTreeException, GitAPIException { // create status StatusCommand command = git.status(); Status status = command.call(); Set<String> files = status.getUntracked(); assertTrue(files.size() > 0); // run clean with setPaths Set<String> paths = new TreeSet<String>(); paths.add("File3.txt"); Set<String> cleanedFiles = git.clean().setPaths(paths).call(); status = git.status().call(); files = status.getUntracked(); assertTrue(files.size() == 3); assertTrue(cleanedFiles.contains("File3.txt")); assertFalse(cleanedFiles.contains("File2.txt")); }
@Command("\\.sync") public void sync(CommandContext ctx) { try { Git.attemptUpdate(); // attemptUpdate() will call NoiseBot.syncAll(), which handles outputting sync info to all // channels } catch (Git.SyncException e) { // Only output the error to the channel/user that requested the sync ctx.respond("#error %s", e.getMessage()); } }
@Test public void testCleanWithDryRun() throws NoWorkTreeException, GitAPIException { // create status StatusCommand command = git.status(); Status status = command.call(); Set<String> files = status.getUntracked(); assertTrue(files.size() > 0); // run clean Set<String> cleanedFiles = git.clean().setDryRun(true).call(); status = git.status().call(); files = status.getUntracked(); assertEquals(4, files.size()); assertTrue(cleanedFiles.contains("File2.txt")); assertTrue(cleanedFiles.contains("File3.txt")); assertTrue(!cleanedFiles.contains("sub-noclean/File1.txt")); assertTrue(cleanedFiles.contains("sub-noclean/File2.txt")); }