aboutsummaryrefslogtreecommitdiffstats
path: root/org.eclipse.jgit.test
diff options
context:
space:
mode:
authorThomas Wolf <thomas.wolf@paranor.ch>2018-08-25 01:58:09 +0200
committerThomas Wolf <thomas.wolf@paranor.ch>2018-11-26 20:53:42 +0100
commit4678f4b7354404f1ea40af6f213d3b2f7d674e3f (patch)
tree328e8ea3ecdb58484fdcfbcc6b7f7730f12a601b /org.eclipse.jgit.test
parent3f745e40a131fee439119e2c93d750688a4e47e6 (diff)
downloadjgit-4678f4b7354404f1ea40af6f213d3b2f7d674e3f.tar.gz
jgit-4678f4b7354404f1ea40af6f213d3b2f7d674e3f.zip
Fix IndexDiffs for git links
After cloning a repo with a submodule, non-recursively, JGit would encounter in its TreeWalk in IndexDiff: * first, a missing gitlink (in index & HEAD, not in working tree) * second, the untracked folder (not in index and head, in working tree) As a result, it would report the submodule as missing. Canonical git reports a clean workspace. The root cause of this is that the path of a gitlink "x" did not compare equal to the path of a tree "x" in JGit. Correct Paths.compare() to account for that. If two paths are otherwise equal, then let gitlinks match both trees and files. Matching trees solves the bug. Matching files is necessary to handle the case where the gitlink directory was replaced by a file; see the new test case IndexDiffSubmoduleTest.testSubmoduleReplacedByFile(). Comparisons of unequal paths are left untouched, so the sort order is unchanged. After the fix, another bug(?) in WorkingTreeIterator became apparent: with core.dirNoGitLinks = true, it was no longer possible to overwrite a gitlink in the index. This is now fixed in WorkingTreeIterator. Add new test cases for the bug itself and for some related cases (submodule directory deleted or replaced by a file) in IndexDiffSubmoduleTest. Add a test for missing files in IndexDiffTest, and adapt the PathsTest to test matching gitlinks. Bug: 467631 Change-Id: I0549d10d46b1858e5eec3cc15095aa9f1d5f5280 Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
Diffstat (limited to 'org.eclipse.jgit.test')
-rw-r--r--org.eclipse.jgit.test/tst/org/eclipse/jgit/api/AddCommandTest.java3
-rw-r--r--org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CleanCommandTest.java21
-rw-r--r--org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/IndexDiffSubmoduleTest.java53
-rw-r--r--org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/IndexDiffTest.java22
-rw-r--r--org.eclipse.jgit.test/tst/org/eclipse/jgit/util/PathsTest.java18
5 files changed, 116 insertions, 1 deletions
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/AddCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/AddCommandTest.java
index 16cec6485c..1a5793ce31 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/AddCommandTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/AddCommandTest.java
@@ -1245,7 +1245,8 @@ public class AddCommandTest extends RepositoryTestCase {
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();
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 065b5b4c3e..139f199f7a 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
@@ -234,6 +234,27 @@ public class CleanCommandTest extends RepositoryTestCase {
}
@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);
String path = "sub";
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/IndexDiffSubmoduleTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/IndexDiffSubmoduleTest.java
index d89aabe75f..93ada4f301 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/IndexDiffSubmoduleTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/IndexDiffSubmoduleTest.java
@@ -51,6 +51,7 @@ import java.io.File;
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;
@@ -109,6 +110,58 @@ public class IndexDiffSubmoduleTest extends RepositoryTestCase {
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 {
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/IndexDiffTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/IndexDiffTest.java
index 580b08b42f..ba5aaf1b18 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/IndexDiffTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/IndexDiffTest.java
@@ -119,6 +119,28 @@ public class IndexDiffTest extends RepositoryTestCase {
}
@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");
writeTrashFile("dir/file3", "dir/file3");
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/PathsTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/PathsTest.java
index 7542ec8910..f78cbe2601 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/PathsTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/PathsTest.java
@@ -89,14 +89,29 @@ public class PathsTest {
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,
@@ -104,6 +119,9 @@ public class PathsTest {
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");