ConfigConstants.CONFIG_KEY_DIRNOGITLINKS, true);
config.save();
- assert (db.getConfig().get(WorkingTreeOptions.KEY).isDirNoGitLinks());
+ assertTrue(
+ db.getConfig().get(WorkingTreeOptions.KEY).isDirNoGitLinks());
try (Git git = new Git(db)) {
git.add().addFilepattern("nested-repo").call();
assertTrue(cleanedFiles.contains("ignored-dir/"));
}
+ @Test
+ public void testCleanDirsWithPrefixFolder() throws Exception {
+ String path = "sub/foo.txt";
+ writeTrashFile(path, "sub is a prefix of sub-noclean");
+ git.add().addFilepattern(path).call();
+ Status beforeCleanStatus = git.status().call();
+ assertTrue(beforeCleanStatus.getAdded().contains(path));
+
+ Set<String> cleanedFiles = git.clean().setCleanDirectories(true).call();
+
+ // The "sub" directory 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);
+ }
+
@Test
public void testCleanDirsWithSubmodule() throws Exception {
SubmoduleAddCommand command = new SubmoduleAddCommand(db);
import java.io.IOException;
import java.util.Set;
+import org.eclipse.jgit.api.CloneCommand;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.errors.NoWorkTreeException;
assertFalse(indexDiff.diff());
}
+ private Repository cloneWithoutCloningSubmodule() throws Exception {
+ File directory = createTempDirectory(
+ "testCloneWithoutCloningSubmodules");
+ CloneCommand clone = Git.cloneRepository();
+ clone.setDirectory(directory);
+ clone.setCloneSubmodules(false);
+ clone.setURI(db.getDirectory().toURI().toString());
+ Git git2 = clone.call();
+ addRepoToClose(git2.getRepository());
+ return git2.getRepository();
+ }
+
+ @Theory
+ public void testCleanAfterClone(IgnoreSubmoduleMode mode) throws Exception {
+ Repository db2 = cloneWithoutCloningSubmodule();
+ IndexDiff indexDiff = new IndexDiff(db2, Constants.HEAD,
+ new FileTreeIterator(db2));
+ indexDiff.setIgnoreSubmoduleMode(mode);
+ assertFalse(indexDiff.diff());
+ }
+
+ @Theory
+ public void testMissingIfDirectoryGone(IgnoreSubmoduleMode mode)
+ throws Exception {
+ recursiveDelete(submodule_trash);
+ IndexDiff indexDiff = new IndexDiff(db, Constants.HEAD,
+ new FileTreeIterator(db));
+ indexDiff.setIgnoreSubmoduleMode(mode);
+ boolean hasChanges = indexDiff.diff();
+ if (mode != IgnoreSubmoduleMode.ALL) {
+ assertTrue(hasChanges);
+ assertEquals("[modules/submodule]",
+ indexDiff.getMissing().toString());
+ } else {
+ assertFalse(hasChanges);
+ }
+ }
+
+ @Theory
+ public void testSubmoduleReplacedByFile(IgnoreSubmoduleMode mode)
+ throws Exception {
+ recursiveDelete(submodule_trash);
+ writeTrashFile("modules/submodule", "nonsense");
+ IndexDiff indexDiff = new IndexDiff(db, Constants.HEAD,
+ new FileTreeIterator(db));
+ indexDiff.setIgnoreSubmoduleMode(mode);
+ assertTrue(indexDiff.diff());
+ assertEquals("[]", indexDiff.getMissing().toString());
+ assertEquals("[]", indexDiff.getUntracked().toString());
+ assertEquals("[modules/submodule]", indexDiff.getModified().toString());
+ }
+
@Theory
public void testDirtyRootWorktree(IgnoreSubmoduleMode mode)
throws IOException {
assertEquals(Collections.EMPTY_SET, diff.getUntrackedFolders());
}
+ @Test
+ public void testMissing() throws Exception {
+ File file2 = writeTrashFile("file2", "file2");
+ File file3 = writeTrashFile("dir/file3", "dir/file3");
+ Git git = Git.wrap(db);
+ git.add().addFilepattern("file2").addFilepattern("dir/file3").call();
+ git.commit().setMessage("commit").call();
+ assertTrue(file2.delete());
+ assertTrue(file3.delete());
+ IndexDiff diff = new IndexDiff(db, Constants.HEAD,
+ new FileTreeIterator(db));
+ diff.diff();
+ assertEquals(2, diff.getMissing().size());
+ assertTrue(diff.getMissing().contains("file2"));
+ assertTrue(diff.getMissing().contains("dir/file3"));
+ assertEquals(0, diff.getChanged().size());
+ assertEquals(0, diff.getModified().size());
+ assertEquals(0, diff.getAdded().size());
+ assertEquals(0, diff.getRemoved().size());
+ assertEquals(Collections.EMPTY_SET, diff.getUntrackedFolders());
+ }
+
@Test
public void testRemoved() throws IOException {
writeTrashFile("file2", "file2");
assertEquals(0, compare(
a, 0, a.length, FileMode.TREE.getBits(),
b, 0, b.length, FileMode.TREE.getBits()));
+ assertEquals(0, compare(
+ a, 0, a.length, FileMode.TREE.getBits(),
+ b, 0, b.length, FileMode.GITLINK.getBits()));
+ assertEquals(0, compare(
+ a, 0, a.length, FileMode.GITLINK.getBits(),
+ b, 0, b.length, FileMode.GITLINK.getBits()));
+ assertEquals(0, compare(
+ a, 0, a.length, FileMode.GITLINK.getBits(),
+ b, 0, b.length, FileMode.TREE.getBits()));
assertEquals(0, compare(
a, 0, a.length, FileMode.REGULAR_FILE.getBits(),
b, 0, b.length, FileMode.REGULAR_FILE.getBits()));
assertEquals(-47, compare(
a, 0, a.length, FileMode.REGULAR_FILE.getBits(),
b, 0, b.length, FileMode.TREE.getBits()));
+ assertEquals(0, compare(
+ a, 0, a.length, FileMode.REGULAR_FILE.getBits(),
+ b, 0, b.length, FileMode.GITLINK.getBits()));
assertEquals(47, compare(
a, 0, a.length, FileMode.TREE.getBits(),
b, 0, b.length, FileMode.REGULAR_FILE.getBits()));
+ assertEquals(0, compare(
+ a, 0, a.length, FileMode.GITLINK.getBits(),
+ b, 0, b.length, FileMode.REGULAR_FILE.getBits()));
assertEquals(0, compareSameName(
a, 0, a.length,
assertEquals(0, compareSameName(
a, 0, a.length,
b, 0, b.length, FileMode.REGULAR_FILE.getBits()));
+ assertEquals(0, compareSameName(
+ a, 0, a.length,
+ b, 0, b.length, FileMode.GITLINK.getBits()));
a = Constants.encode("a.c");
b = Constants.encode("a");
}
}
if (FileMode.GITLINK == iMode
- && FileMode.TREE == wtMode) {
+ && FileMode.TREE == wtMode && !getOptions().isDirNoGitLinks()) {
return iMode;
}
if (FileMode.TREE == iMode
/*
- * Copyright (C) 2016, Google Inc.
+ * Copyright (C) 2016, 2018 Google Inc.
* and other copyright owners as documented in the project's IP log.
*
* This program and the accompanying materials are made available
package org.eclipse.jgit.util;
+import static org.eclipse.jgit.lib.FileMode.TYPE_GITLINK;
import static org.eclipse.jgit.lib.FileMode.TYPE_MASK;
import static org.eclipse.jgit.lib.FileMode.TYPE_TREE;
aPath, aPos, aEnd, aMode,
bPath, bPos, bEnd, bMode);
if (cmp == 0) {
- cmp = lastPathChar(aMode) - lastPathChar(bMode);
+ cmp = modeCompare(aMode, bMode);
}
return cmp;
}
return 0;
}
+ private static int modeCompare(int aMode, int bMode) {
+ if ((aMode & TYPE_MASK) == TYPE_GITLINK
+ || (bMode & TYPE_MASK) == TYPE_GITLINK) {
+ // Git links can be equal to files or folders
+ return 0;
+ }
+ return lastPathChar(aMode) - lastPathChar(bMode);
+ }
+
private Paths() {
}
}