Bug 431392 - CleanCommand does not clean file in sub-directory
Summary: CleanCommand does not clean file in sub-directory
Status: NEW
Alias: None
Product: JGit
Classification: Technology
Component: JGit (show other bugs)
Version: unspecified   Edit
Hardware: All All
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: Project Inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords: helpwanted
Depends on:
Blocks:
 
Reported: 2014-03-27 13:07 EDT by Rüdiger Herrmann CLA
Modified: 2019-04-25 01:57 EDT (History)
4 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Rüdiger Herrmann CLA 2014-03-27 13:07:40 EDT
I found that the CleanCommand behaves differently than C Git clean when it comes to clean files located in sub-directories.
After executing the following shell commands within a repository, the 'file' is deleted as expected:
  mkdir folder
  cd folder
  touch file
  cd ..
  git clean -f folder/file
whereas, after running these lines:
  Set<String> paths = new HashSet<String>();
  paths.add( "folder/file" );
  git.clean().setPaths( paths ).call();
the file still exists. Am I missing someting here or is this a bug in JGit?

To easily reproduce the issue, here is a (failing) test case that fits into CleanCommandTest.
	@Test
	public void testCleanWithNestedPath() throws Exception {
		Set<String> paths = new TreeSet<String>();
		paths.add("sub-clean/File4.txt");

		Set<String> cleanedFiles = git.clean().setPaths(paths).call();

		assertTrue(cleanedFiles.contains("sub-clean/File4.txt"));
		assertFalse(new File(git.getRepository().getWorkTree(), "sub-clean/File4.txt").exists());
	}
Comment 1 Robin Rosenberg CLA 2014-03-29 10:48:03 EDT
try setCleanDirectories(true)

Maybe the docs needs updating
Comment 2 Rüdiger Herrmann CLA 2014-03-30 06:48:07 EDT
(In reply to Robin Rosenberg from comment #1)
> try setCleanDirectories(true)
Sorry, I forgot to mention that I tried that already. It doesn't make a difference.
Comment 3 Ned Twigg CLA 2019-04-25 01:57:12 EDT
I bumped into this too, spent a little time isolating it.  Here's one of the problems:

- I have a folder `build`, which is ignored
- I have a file `build.gradle`, which is untracked

If I do a clean, I would expect the untracked `build.gradle` to be deleted, but that does not happen.  That is because the code thinks that `build.gradle` is a file inside the `build` folder, because it uses `startsWith` as its check.  You could fix this with `startsWith(path + "/")` to fix the bug on this line:

https://github.com/eclipse/jgit/blob/0a15cb3a2bc14feec11baa1977567179ce3094bc/org.eclipse.jgit/src/org/eclipse/jgit/api/CleanCommand.java#L220

But the code has other bugs as well.  It seems to be making assumptions about what the output of the StatusCommand is, and I believe those assumptions no longer hold true today.

Here is a total re-implementation of the command which we use, it fixes a few bugs and simplifies the code quite a bit.  You can easily copy-paste it into your project and use it with stock JGit, no patching necessary

https://gist.github.com/nedtwigg/a5ce9dadc160a8ec2ac48deb55b4e4c6

Naturally, we would like to contribute it back upstream, but we'd rather use our limited upstreaming budget to get multiple worktree support merged, which seems to be bogged down in style nits:

https://git.eclipse.org/r/#/c/126281/