aboutsummaryrefslogtreecommitdiffstats
path: root/org.eclipse.jgit.test/tst/org/eclipse
diff options
context:
space:
mode:
authorMatthias Sohn <matthias.sohn@sap.com>2016-01-21 17:03:20 +0100
committerMatthias Sohn <matthias.sohn@sap.com>2016-01-21 17:07:31 +0100
commit4ec84fac86c9652847630efc2dda3e69954fdb61 (patch)
tree537cf6ffb986dc361f25a91296c04c4b5599b705 /org.eclipse.jgit.test/tst/org/eclipse
parent7e8e4ec019f4ca4d9a1892c7c882eba6013fdeaa (diff)
parent7b6122908b2aa31555cee3e0cc9dde304e0d90b3 (diff)
downloadjgit-4ec84fac86c9652847630efc2dda3e69954fdb61.tar.gz
jgit-4ec84fac86c9652847630efc2dda3e69954fdb61.zip
Merge branch 'master' into stable-4.2
Change-Id: Ieec4f51aedadf5734ae0e3f4e8713248a3c4fc52 Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
Diffstat (limited to 'org.eclipse.jgit.test/tst/org/eclipse')
-rw-r--r--org.eclipse.jgit.test/tst/org/eclipse/jgit/api/AddCommandTest.java98
-rw-r--r--org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CommitCommandTest.java31
-rw-r--r--org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PathCheckoutCommandTest.java65
-rw-r--r--org.eclipse.jgit.test/tst/org/eclipse/jgit/api/ResetCommandTest.java56
-rw-r--r--org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCachePathEditTest.java121
-rw-r--r--org.eclipse.jgit.test/tst/org/eclipse/jgit/gitrepo/RepoCommandTest.java7
-rw-r--r--org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/FileRepositoryBuilderTest.java2
-rw-r--r--org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackWriterTest.java70
-rw-r--r--org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/T0003_BasicTest.java53
-rw-r--r--org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftree/RefTreeDatabaseTest.java685
-rw-r--r--org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftree/RefTreeTest.java303
-rw-r--r--org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/DirCacheCheckoutTest.java6
-rw-r--r--org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/IndexDiffTest.java91
-rw-r--r--org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ObjectCheckerTest.java1465
-rw-r--r--org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/T0002_TreeTest.java319
-rw-r--r--org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/ObjectWalkTest.java45
-rw-r--r--org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevCommitParseTest.java85
-rw-r--r--org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevTagParseTest.java39
-rw-r--r--org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/AtomicPushTest.java15
-rw-r--r--org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/BundleWriterTest.java6
-rw-r--r--org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/ReceivePackAdvertiseRefsHookTest.java18
-rw-r--r--org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/RefSpecTest.java50
-rw-r--r--org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/TransportTest.java73
-rw-r--r--org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/URIishTest.java42
-rw-r--r--org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/TreeWalkBasicDiffTest.java77
-rw-r--r--org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/filter/PathFilterGroupTest.java150
-rw-r--r--org.eclipse.jgit.test/tst/org/eclipse/jgit/util/ChangeIdUtilTest.java3
-rw-r--r--org.eclipse.jgit.test/tst/org/eclipse/jgit/util/FileUtilTest.java26
-rw-r--r--org.eclipse.jgit.test/tst/org/eclipse/jgit/util/PathsTest.java118
29 files changed, 2588 insertions, 1531 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 d4bd68e686..4fefdfddab 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
@@ -43,6 +43,7 @@
*/
package org.eclipse.jgit.api;
+import static org.eclipse.jgit.util.FileUtils.RECURSIVE;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
@@ -797,7 +798,6 @@ public class AddCommandTest extends RepositoryTestCase {
assertEquals("[a.txt, mode:100644, content:more content,"
+ " assume-unchanged:false][b.txt, mode:100644,"
- + "" + ""
+ " content:content, assume-unchanged:true]",
indexState(CONTENT
| ASSUME_UNCHANGED));
@@ -805,6 +805,102 @@ public class AddCommandTest extends RepositoryTestCase {
}
@Test
+ public void testReplaceFileWithDirectory()
+ throws IOException, NoFilepatternException, GitAPIException {
+ try (Git git = new Git(db)) {
+ writeTrashFile("df", "before replacement");
+ git.add().addFilepattern("df").call();
+ assertEquals("[df, mode:100644, content:before replacement]",
+ indexState(CONTENT));
+ FileUtils.delete(new File(db.getWorkTree(), "df"));
+ writeTrashFile("df/f", "after replacement");
+ git.add().addFilepattern("df").call();
+ assertEquals("[df/f, mode:100644, content:after replacement]",
+ indexState(CONTENT));
+ }
+ }
+
+ @Test
+ public void testReplaceDirectoryWithFile()
+ throws IOException, NoFilepatternException, GitAPIException {
+ try (Git git = new Git(db)) {
+ writeTrashFile("df/f", "before replacement");
+ git.add().addFilepattern("df").call();
+ assertEquals("[df/f, mode:100644, content:before replacement]",
+ indexState(CONTENT));
+ FileUtils.delete(new File(db.getWorkTree(), "df"), RECURSIVE);
+ writeTrashFile("df", "after replacement");
+ git.add().addFilepattern("df").call();
+ assertEquals("[df, mode:100644, content:after replacement]",
+ indexState(CONTENT));
+ }
+ }
+
+ @Test
+ public void testReplaceFileByPartOfDirectory()
+ throws IOException, NoFilepatternException, GitAPIException {
+ try (Git git = new Git(db)) {
+ writeTrashFile("src/main", "df", "before replacement");
+ writeTrashFile("src/main", "z", "z");
+ writeTrashFile("z", "z2");
+ git.add().addFilepattern("src/main/df")
+ .addFilepattern("src/main/z")
+ .addFilepattern("z")
+ .call();
+ assertEquals(
+ "[src/main/df, mode:100644, content:before replacement]" +
+ "[src/main/z, mode:100644, content:z]" +
+ "[z, mode:100644, content:z2]",
+ indexState(CONTENT));
+ FileUtils.delete(new File(db.getWorkTree(), "src/main/df"));
+ writeTrashFile("src/main/df", "a", "after replacement");
+ writeTrashFile("src/main/df", "b", "unrelated file");
+ git.add().addFilepattern("src/main/df/a").call();
+ assertEquals(
+ "[src/main/df/a, mode:100644, content:after replacement]" +
+ "[src/main/z, mode:100644, content:z]" +
+ "[z, mode:100644, content:z2]",
+ indexState(CONTENT));
+ }
+ }
+
+ @Test
+ public void testReplaceDirectoryConflictsWithFile()
+ throws IOException, NoFilepatternException, GitAPIException {
+ DirCache dc = db.lockDirCache();
+ try (ObjectInserter oi = db.newObjectInserter()) {
+ DirCacheBuilder builder = dc.builder();
+ File f = writeTrashFile("a", "df", "content");
+ addEntryToBuilder("a", f, oi, builder, 1);
+
+ f = writeTrashFile("a", "df", "other content");
+ addEntryToBuilder("a/df", f, oi, builder, 3);
+
+ f = writeTrashFile("a", "df", "our content");
+ addEntryToBuilder("a/df", f, oi, builder, 2);
+
+ f = writeTrashFile("z", "z");
+ addEntryToBuilder("z", f, oi, builder, 0);
+ builder.commit();
+ }
+ assertEquals(
+ "[a, mode:100644, stage:1, content:content]" +
+ "[a/df, mode:100644, stage:2, content:our content]" +
+ "[a/df, mode:100644, stage:3, content:other content]" +
+ "[z, mode:100644, content:z]",
+ indexState(CONTENT));
+
+ try (Git git = new Git(db)) {
+ FileUtils.delete(new File(db.getWorkTree(), "a"), RECURSIVE);
+ writeTrashFile("a", "merged");
+ git.add().addFilepattern("a").call();
+ assertEquals("[a, mode:100644, content:merged]" +
+ "[z, mode:100644, content:z]",
+ indexState(CONTENT));
+ }
+ }
+
+ @Test
public void testExecutableRetention() throws Exception {
StoredConfig config = db.getConfig();
config.setBoolean(ConfigConstants.CONFIG_CORE_SECTION, null,
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CommitCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CommitCommandTest.java
index 0d03047d53..b39a68a22e 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CommitCommandTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CommitCommandTest.java
@@ -46,12 +46,15 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.fail;
import java.io.File;
import java.util.Date;
import java.util.List;
import java.util.TimeZone;
+import org.eclipse.jgit.api.errors.EmtpyCommitException;
import org.eclipse.jgit.api.errors.WrongRepositoryStateException;
import org.eclipse.jgit.diff.DiffEntry;
import org.eclipse.jgit.dircache.DirCache;
@@ -477,6 +480,34 @@ public class CommitCommandTest extends RepositoryTestCase {
}
@Test
+ public void commitEmptyCommits() throws Exception {
+ try (Git git = new Git(db)) {
+
+ writeTrashFile("file1", "file1");
+ git.add().addFilepattern("file1").call();
+ RevCommit initial = git.commit().setMessage("initial commit")
+ .call();
+
+ RevCommit emptyFollowUp = git.commit()
+ .setAuthor("New Author", "newauthor@example.org")
+ .setMessage("no change").call();
+
+ assertNotEquals(initial.getId(), emptyFollowUp.getId());
+ assertEquals(initial.getTree().getId(),
+ emptyFollowUp.getTree().getId());
+
+ try {
+ git.commit().setAuthor("New Author", "newauthor@example.org")
+ .setMessage("again no change").setAllowEmpty(false)
+ .call();
+ fail("Didn't get the expected EmtpyCommitException");
+ } catch (EmtpyCommitException e) {
+ // expect this exception
+ }
+ }
+ }
+
+ @Test
public void commitOnlyShouldCommitUnmergedPathAndNotAffectOthers()
throws Exception {
DirCache index = db.lockDirCache();
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PathCheckoutCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PathCheckoutCommandTest.java
index db811cdf59..3343af06dd 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PathCheckoutCommandTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PathCheckoutCommandTest.java
@@ -43,10 +43,12 @@
package org.eclipse.jgit.api;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import java.io.File;
import java.io.IOException;
+import java.nio.file.Path;
import org.eclipse.jgit.api.CheckoutCommand.Stage;
import org.eclipse.jgit.api.errors.JGitInternalException;
@@ -59,6 +61,9 @@ import org.eclipse.jgit.lib.ObjectReader;
import org.eclipse.jgit.lib.RepositoryState;
import org.eclipse.jgit.lib.StoredConfig;
import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.util.FS;
+import org.eclipse.jgit.util.FileUtils;
+import org.junit.Assume;
import org.junit.Before;
import org.junit.Test;
@@ -73,6 +78,8 @@ public class PathCheckoutCommandTest extends RepositoryTestCase {
private static final String FILE3 = "Test3.txt";
+ private static final String LINK = "link";
+
Git git;
RevCommit initialCommit;
@@ -99,6 +106,64 @@ public class PathCheckoutCommandTest extends RepositoryTestCase {
}
@Test
+ public void testUpdateSymLink() throws Exception {
+ Assume.assumeTrue(FS.DETECTED.supportsSymlinks());
+
+ Path path = writeLink(LINK, FILE1);
+ git.add().addFilepattern(LINK).call();
+ git.commit().setMessage("Added link").call();
+ assertEquals("3", read(path.toFile()));
+
+ writeLink(LINK, FILE2);
+ assertEquals("c", read(path.toFile()));
+
+ CheckoutCommand co = git.checkout();
+ co.addPath(LINK).call();
+
+ assertEquals("3", read(path.toFile()));
+ }
+
+ @Test
+ public void testUpdateBrokenSymLinkToDirectory() throws Exception {
+ Assume.assumeTrue(FS.DETECTED.supportsSymlinks());
+
+ Path path = writeLink(LINK, "f");
+ git.add().addFilepattern(LINK).call();
+ git.commit().setMessage("Added link").call();
+ assertEquals("f", FileUtils.readSymLink(path.toFile()));
+ assertTrue(path.toFile().exists());
+
+ writeLink(LINK, "link_to_nowhere");
+ assertFalse(path.toFile().exists());
+ assertEquals("link_to_nowhere", FileUtils.readSymLink(path.toFile()));
+
+ CheckoutCommand co = git.checkout();
+ co.addPath(LINK).call();
+
+ assertEquals("f", FileUtils.readSymLink(path.toFile()));
+ }
+
+ @Test
+ public void testUpdateBrokenSymLink() throws Exception {
+ Assume.assumeTrue(FS.DETECTED.supportsSymlinks());
+
+ Path path = writeLink(LINK, FILE1);
+ git.add().addFilepattern(LINK).call();
+ git.commit().setMessage("Added link").call();
+ assertEquals("3", read(path.toFile()));
+ assertEquals(FILE1, FileUtils.readSymLink(path.toFile()));
+
+ writeLink(LINK, "link_to_nowhere");
+ assertFalse(path.toFile().exists());
+ assertEquals("link_to_nowhere", FileUtils.readSymLink(path.toFile()));
+
+ CheckoutCommand co = git.checkout();
+ co.addPath(LINK).call();
+
+ assertEquals("3", read(path.toFile()));
+ }
+
+ @Test
public void testUpdateWorkingDirectory() throws Exception {
CheckoutCommand co = git.checkout();
File written = writeTrashFile(FILE1, "");
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/ResetCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/ResetCommandTest.java
index a67f2b912a..66f25e8e51 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/ResetCommandTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/ResetCommandTest.java
@@ -65,6 +65,7 @@ import org.eclipse.jgit.junit.RepositoryTestCase;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.FileMode;
import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.treewalk.TreeWalk;
@@ -139,8 +140,8 @@ public class ResetCommandTest extends RepositoryTestCase {
AmbiguousObjectException, IOException, GitAPIException {
setupRepository();
ObjectId prevHead = db.resolve(Constants.HEAD);
- git.reset().setMode(ResetType.HARD).setRef(initialCommit.getName())
- .call();
+ assertSameAsHead(git.reset().setMode(ResetType.HARD)
+ .setRef(initialCommit.getName()).call());
// check if HEAD points to initial commit now
ObjectId head = db.resolve(Constants.HEAD);
assertEquals(initialCommit, head);
@@ -176,8 +177,8 @@ public class ResetCommandTest extends RepositoryTestCase {
AmbiguousObjectException, IOException, GitAPIException {
setupRepository();
ObjectId prevHead = db.resolve(Constants.HEAD);
- git.reset().setMode(ResetType.SOFT).setRef(initialCommit.getName())
- .call();
+ assertSameAsHead(git.reset().setMode(ResetType.SOFT)
+ .setRef(initialCommit.getName()).call());
// check if HEAD points to initial commit now
ObjectId head = db.resolve(Constants.HEAD);
assertEquals(initialCommit, head);
@@ -197,8 +198,8 @@ public class ResetCommandTest extends RepositoryTestCase {
AmbiguousObjectException, IOException, GitAPIException {
setupRepository();
ObjectId prevHead = db.resolve(Constants.HEAD);
- git.reset().setMode(ResetType.MIXED).setRef(initialCommit.getName())
- .call();
+ assertSameAsHead(git.reset().setMode(ResetType.MIXED)
+ .setRef(initialCommit.getName()).call());
// check if HEAD points to initial commit now
ObjectId head = db.resolve(Constants.HEAD);
assertEquals(initialCommit, head);
@@ -241,7 +242,8 @@ public class ResetCommandTest extends RepositoryTestCase {
assertTrue(bEntry.getLength() > 0);
assertTrue(bEntry.getLastModified() > 0);
- git.reset().setMode(ResetType.MIXED).setRef(commit2.getName()).call();
+ assertSameAsHead(git.reset().setMode(ResetType.MIXED)
+ .setRef(commit2.getName()).call());
cache = db.readDirCache();
@@ -280,7 +282,7 @@ public class ResetCommandTest extends RepositoryTestCase {
+ "[a.txt, mode:100644, stage:3]",
indexState(0));
- git.reset().setMode(ResetType.MIXED).call();
+ assertSameAsHead(git.reset().setMode(ResetType.MIXED).call());
assertEquals("[a.txt, mode:100644]" + "[b.txt, mode:100644]",
indexState(0));
@@ -298,8 +300,8 @@ public class ResetCommandTest extends RepositoryTestCase {
// 'a.txt' has already been modified in setupRepository
// 'notAddedToIndex.txt' has been added to repository
- git.reset().addPath(indexFile.getName())
- .addPath(untrackedFile.getName()).call();
+ assertSameAsHead(git.reset().addPath(indexFile.getName())
+ .addPath(untrackedFile.getName()).call());
DirCacheEntry postReset = DirCache.read(db.getIndexFile(), db.getFS())
.getEntry(indexFile.getName());
@@ -329,7 +331,7 @@ public class ResetCommandTest extends RepositoryTestCase {
git.add().addFilepattern(untrackedFile.getName()).call();
// 'dir/b.txt' has already been modified in setupRepository
- git.reset().addPath("dir").call();
+ assertSameAsHead(git.reset().addPath("dir").call());
DirCacheEntry postReset = DirCache.read(db.getIndexFile(), db.getFS())
.getEntry("dir/b.txt");
@@ -358,9 +360,9 @@ public class ResetCommandTest extends RepositoryTestCase {
// '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();
+ assertSameAsHead(git.reset().setRef(initialCommit.getName())
+ .addPath(indexFile.getName()).addPath(untrackedFile.getName())
+ .call());
// check that HEAD hasn't moved
ObjectId head = db.resolve(Constants.HEAD);
@@ -397,7 +399,7 @@ public class ResetCommandTest extends RepositoryTestCase {
+ "[b.txt, mode:100644]",
indexState(0));
- git.reset().addPath(file).call();
+ assertSameAsHead(git.reset().addPath(file).call());
assertEquals("[a.txt, mode:100644]" + "[b.txt, mode:100644]",
indexState(0));
@@ -409,7 +411,7 @@ public class ResetCommandTest extends RepositoryTestCase {
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();
+ assertSameAsHead(git.reset().addPath("a.txt").call());
DirCache cache = db.readDirCache();
DirCacheEntry aEntry = cache.getEntry("a.txt");
@@ -421,7 +423,8 @@ public class ResetCommandTest extends RepositoryTestCase {
git = new Git(db);
writeTrashFile("a.txt", "content");
git.add().addFilepattern("a.txt").call();
- git.reset().setRef("doesnotexist").addPath("a.txt").call();
+ assertSameAsHead(
+ git.reset().setRef("doesnotexist").addPath("a.txt").call());
}
@Test
@@ -431,7 +434,7 @@ public class ResetCommandTest extends RepositoryTestCase {
git.add().addFilepattern("a.txt").call();
writeTrashFile("a.txt", "modified");
// should use default mode MIXED
- git.reset().call();
+ assertSameAsHead(git.reset().call());
DirCache cache = db.readDirCache();
DirCacheEntry aEntry = cache.getEntry("a.txt");
@@ -452,7 +455,7 @@ public class ResetCommandTest extends RepositoryTestCase {
git.add().addFilepattern(untrackedFile.getName()).call();
- git.reset().setRef(tagName).setMode(HARD).call();
+ assertSameAsHead(git.reset().setRef(tagName).setMode(HARD).call());
ObjectId head = db.resolve(Constants.HEAD);
assertEquals(secondCommit, head);
@@ -486,7 +489,8 @@ public class ResetCommandTest extends RepositoryTestCase {
result.getMergeStatus());
assertNotNull(db.readSquashCommitMsg());
- g.reset().setMode(ResetType.HARD).setRef(first.getName()).call();
+ assertSameAsHead(g.reset().setMode(ResetType.HARD)
+ .setRef(first.getName()).call());
assertNull(db.readSquashCommitMsg());
}
@@ -497,7 +501,7 @@ public class ResetCommandTest extends RepositoryTestCase {
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();
+ assertSameAsHead(git.reset().setMode(ResetType.HARD).call());
DirCache cache = db.readDirCache();
DirCacheEntry aEntry = cache.getEntry("a.txt");
@@ -558,4 +562,14 @@ public class ResetCommandTest extends RepositoryTestCase {
return dc.getEntry(path) != null;
}
+ /**
+ * Asserts that a certain ref is similar to repos HEAD.
+ * @param ref
+ * @throws IOException
+ */
+ private void assertSameAsHead(Ref ref) throws IOException {
+ Ref headRef = db.getRef(Constants.HEAD);
+ assertEquals(headRef.getName(), ref.getName());
+ assertEquals(headRef.getObjectId(), ref.getObjectId());
+ }
}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCachePathEditTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCachePathEditTest.java
index 63ec85861d..c85e156352 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCachePathEditTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCachePathEditTest.java
@@ -43,11 +43,13 @@
package org.eclipse.jgit.dircache;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.jgit.dircache.DirCacheEditor.PathEdit;
+import org.eclipse.jgit.errors.DirCacheNameConflictException;
import org.eclipse.jgit.lib.FileMode;
import org.eclipse.jgit.lib.ObjectId;
import org.junit.Test;
@@ -154,6 +156,125 @@ public class DirCachePathEditTest {
assertEquals(DirCacheEntry.STAGE_3, entries.get(2).getStage());
}
+ @Test
+ public void testFileReplacesTree() throws Exception {
+ DirCache dc = DirCache.newInCore();
+ DirCacheEditor editor = dc.editor();
+ editor.add(new AddEdit("a"));
+ editor.add(new AddEdit("b/c"));
+ editor.add(new AddEdit("b/d"));
+ editor.add(new AddEdit("e"));
+ editor.finish();
+
+ editor = dc.editor();
+ editor.add(new AddEdit("b"));
+ editor.finish();
+
+ assertEquals(3, dc.getEntryCount());
+ assertEquals("a", dc.getEntry(0).getPathString());
+ assertEquals("b", dc.getEntry(1).getPathString());
+ assertEquals("e", dc.getEntry(2).getPathString());
+
+ dc.clear();
+ editor = dc.editor();
+ editor.add(new AddEdit("A.c"));
+ editor.add(new AddEdit("A/c"));
+ editor.add(new AddEdit("A0c"));
+ editor.finish();
+
+ editor = dc.editor();
+ editor.add(new AddEdit("A"));
+ editor.finish();
+ assertEquals(3, dc.getEntryCount());
+ assertEquals("A", dc.getEntry(0).getPathString());
+ assertEquals("A.c", dc.getEntry(1).getPathString());
+ assertEquals("A0c", dc.getEntry(2).getPathString());
+ }
+
+ @Test
+ public void testTreeReplacesFile() throws Exception {
+ DirCache dc = DirCache.newInCore();
+ DirCacheEditor editor = dc.editor();
+ editor.add(new AddEdit("a"));
+ editor.add(new AddEdit("ab"));
+ editor.add(new AddEdit("b"));
+ editor.add(new AddEdit("e"));
+ editor.finish();
+
+ editor = dc.editor();
+ editor.add(new AddEdit("b/c/d/f"));
+ editor.add(new AddEdit("b/g/h/i"));
+ editor.finish();
+
+ assertEquals(5, dc.getEntryCount());
+ assertEquals("a", dc.getEntry(0).getPathString());
+ assertEquals("ab", dc.getEntry(1).getPathString());
+ assertEquals("b/c/d/f", dc.getEntry(2).getPathString());
+ assertEquals("b/g/h/i", dc.getEntry(3).getPathString());
+ assertEquals("e", dc.getEntry(4).getPathString());
+ }
+
+ @Test
+ public void testDuplicateFiles() throws Exception {
+ DirCache dc = DirCache.newInCore();
+ DirCacheEditor editor = dc.editor();
+ editor.add(new AddEdit("a"));
+ editor.add(new AddEdit("a"));
+
+ try {
+ editor.finish();
+ fail("Expected DirCacheNameConflictException to be thrown");
+ } catch (DirCacheNameConflictException e) {
+ assertEquals("a a", e.getMessage());
+ assertEquals("a", e.getPath1());
+ assertEquals("a", e.getPath2());
+ }
+ }
+
+ @Test
+ public void testFileOverlapsTree() throws Exception {
+ DirCache dc = DirCache.newInCore();
+ DirCacheEditor editor = dc.editor();
+ editor.add(new AddEdit("a"));
+ editor.add(new AddEdit("a/b").setReplace(false));
+ try {
+ editor.finish();
+ fail("Expected DirCacheNameConflictException to be thrown");
+ } catch (DirCacheNameConflictException e) {
+ assertEquals("a a/b", e.getMessage());
+ assertEquals("a", e.getPath1());
+ assertEquals("a/b", e.getPath2());
+ }
+
+ editor = dc.editor();
+ editor.add(new AddEdit("A.c"));
+ editor.add(new AddEdit("A/c").setReplace(false));
+ editor.add(new AddEdit("A0c"));
+ editor.add(new AddEdit("A"));
+ try {
+ editor.finish();
+ fail("Expected DirCacheNameConflictException to be thrown");
+ } catch (DirCacheNameConflictException e) {
+ assertEquals("A A/c", e.getMessage());
+ assertEquals("A", e.getPath1());
+ assertEquals("A/c", e.getPath2());
+ }
+
+ editor = dc.editor();
+ editor.add(new AddEdit("A.c"));
+ editor.add(new AddEdit("A/b/c/d").setReplace(false));
+ editor.add(new AddEdit("A/b/c"));
+ editor.add(new AddEdit("A0c"));
+ try {
+ editor.finish();
+ fail("Expected DirCacheNameConflictException to be thrown");
+ } catch (DirCacheNameConflictException e) {
+ assertEquals("A/b/c A/b/c/d", e.getMessage());
+ assertEquals("A/b/c", e.getPath1());
+ assertEquals("A/b/c/d", e.getPath2());
+ }
+ }
+
private static DirCacheEntry createEntry(String path, int stage) {
DirCacheEntry entry = new DirCacheEntry(path, stage);
entry.setFileMode(FileMode.REGULAR_FILE);
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/gitrepo/RepoCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/gitrepo/RepoCommandTest.java
index b6649b3f05..524d0b8e7e 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/gitrepo/RepoCommandTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/gitrepo/RepoCommandTest.java
@@ -409,6 +409,7 @@ public class RepoCommandTest extends RepositoryTestCase {
.append("<project path=\"foo\" name=\"").append(defaultUri)
.append("\" revision=\"").append(BRANCH).append("\" >")
.append("<copyfile src=\"hello.txt\" dest=\"Hello\" />")
+ .append("<copyfile src=\"hello.txt\" dest=\"foo/Hello\" />")
.append("</project>").append("</manifest>");
JGitTestUtil.writeTrashFile(tempDb, "manifest.xml",
xmlContent.toString());
@@ -423,8 +424,12 @@ public class RepoCommandTest extends RepositoryTestCase {
.getRepository();
// The Hello file should exist
File hello = new File(localDb.getWorkTree(), "Hello");
- localDb.close();
assertTrue("The Hello file should exist", hello.exists());
+ // The foo/Hello file should be skipped.
+ File foohello = new File(localDb.getWorkTree(), "foo/Hello");
+ assertFalse(
+ "The foo/Hello file should be skipped", foohello.exists());
+ localDb.close();
// The content of Hello file should be expected
BufferedReader reader = new BufferedReader(new FileReader(hello));
String content = reader.readLine();
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/FileRepositoryBuilderTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/FileRepositoryBuilderTest.java
index 2d72d2373b..dca356434b 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/FileRepositoryBuilderTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/FileRepositoryBuilderTest.java
@@ -107,7 +107,7 @@ public class FileRepositoryBuilderTest extends LocalDiskRepositoryTestCase {
Repository r = createWorkRepository();
StoredConfig config = r.getConfig();
config.setLong(ConfigConstants.CONFIG_CORE_SECTION, null,
- ConfigConstants.CONFIG_KEY_REPO_FORMAT_VERSION, 1);
+ ConfigConstants.CONFIG_KEY_REPO_FORMAT_VERSION, 999999);
config.save();
try {
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackWriterTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackWriterTest.java
index bc880a13ef..01d6ee68e8 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackWriterTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackWriterTest.java
@@ -43,11 +43,13 @@
package org.eclipse.jgit.internal.storage.file;
+import static org.eclipse.jgit.lib.Constants.OBJ_BLOB;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
+import static org.eclipse.jgit.internal.storage.pack.PackWriter.NONE;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
@@ -66,19 +68,19 @@ import java.util.Set;
import org.eclipse.jgit.errors.MissingObjectException;
import org.eclipse.jgit.internal.storage.file.PackIndex.MutableEntry;
import org.eclipse.jgit.internal.storage.pack.PackWriter;
-import org.eclipse.jgit.internal.storage.pack.PackWriter.ObjectIdSet;
import org.eclipse.jgit.junit.JGitTestUtil;
import org.eclipse.jgit.junit.TestRepository;
import org.eclipse.jgit.junit.TestRepository.BranchBuilder;
-import org.eclipse.jgit.lib.AnyObjectId;
import org.eclipse.jgit.lib.NullProgressMonitor;
import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.ObjectIdSet;
import org.eclipse.jgit.lib.ObjectInserter;
import org.eclipse.jgit.revwalk.RevBlob;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevObject;
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.storage.pack.PackConfig;
+import org.eclipse.jgit.storage.pack.PackStatistics;
import org.eclipse.jgit.test.resources.SampleDataRepositoryTestCase;
import org.eclipse.jgit.transport.PackParser;
import org.junit.After;
@@ -87,9 +89,6 @@ import org.junit.Test;
public class PackWriterTest extends SampleDataRepositoryTestCase {
- private static final Set<ObjectId> EMPTY_SET_OBJECT = Collections
- .<ObjectId> emptySet();
-
private static final List<RevObject> EMPTY_LIST_REVS = Collections
.<RevObject> emptyList();
@@ -170,7 +169,7 @@ public class PackWriterTest extends SampleDataRepositoryTestCase {
*/
@Test
public void testWriteEmptyPack1() throws IOException {
- createVerifyOpenPack(EMPTY_SET_OBJECT, EMPTY_SET_OBJECT, false, false);
+ createVerifyOpenPack(NONE, NONE, false, false);
assertEquals(0, writer.getObjectCount());
assertEquals(0, pack.getObjectCount());
@@ -203,8 +202,8 @@ public class PackWriterTest extends SampleDataRepositoryTestCase {
final ObjectId nonExisting = ObjectId
.fromString("0000000000000000000000000000000000000001");
try {
- createVerifyOpenPack(EMPTY_SET_OBJECT, Collections.singleton(
- nonExisting), false, false);
+ createVerifyOpenPack(NONE, Collections.singleton(nonExisting),
+ false, false);
fail("Should have thrown MissingObjectException");
} catch (MissingObjectException x) {
// expected
@@ -220,8 +219,8 @@ public class PackWriterTest extends SampleDataRepositoryTestCase {
public void testIgnoreNonExistingObjects() throws IOException {
final ObjectId nonExisting = ObjectId
.fromString("0000000000000000000000000000000000000001");
- createVerifyOpenPack(EMPTY_SET_OBJECT, Collections.singleton(
- nonExisting), false, true);
+ createVerifyOpenPack(NONE, Collections.singleton(nonExisting),
+ false, true);
// shouldn't throw anything
}
@@ -239,8 +238,8 @@ public class PackWriterTest extends SampleDataRepositoryTestCase {
final ObjectId nonExisting = ObjectId
.fromString("0000000000000000000000000000000000000001");
new GC(db).gc();
- createVerifyOpenPack(EMPTY_SET_OBJECT,
- Collections.singleton(nonExisting), false, true, true);
+ createVerifyOpenPack(NONE, Collections.singleton(nonExisting), false,
+ true, true);
// shouldn't throw anything
}
@@ -438,6 +437,38 @@ public class PackWriterTest extends SampleDataRepositoryTestCase {
}
@Test
+ public void testDeltaStatistics() throws Exception {
+ config.setDeltaCompress(true);
+ FileRepository repo = createBareRepository();
+ TestRepository<FileRepository> testRepo = new TestRepository<FileRepository>(repo);
+ ArrayList<RevObject> blobs = new ArrayList<>();
+ blobs.add(testRepo.blob(genDeltableData(1000)));
+ blobs.add(testRepo.blob(genDeltableData(1005)));
+
+ try (PackWriter pw = new PackWriter(repo)) {
+ NullProgressMonitor m = NullProgressMonitor.INSTANCE;
+ pw.preparePack(blobs.iterator());
+ pw.writePack(m, m, os);
+ PackStatistics stats = pw.getStatistics();
+ assertEquals(1, stats.getTotalDeltas());
+ assertTrue("Delta bytes not set.",
+ stats.byObjectType(OBJ_BLOB).getDeltaBytes() > 0);
+ }
+ }
+
+ // Generate consistent junk data for building files that delta well
+ private String genDeltableData(int length) {
+ assertTrue("Generated data must have a length > 0", length > 0);
+ char[] data = {'a', 'b', 'c', '\n'};
+ StringBuilder builder = new StringBuilder(length);
+ for (int i = 0; i < length; i++) {
+ builder.append(data[i % 4]);
+ }
+ return builder.toString();
+ }
+
+
+ @Test
public void testWriteIndex() throws Exception {
config.setIndexVersion(2);
writeVerifyPack4(false);
@@ -494,7 +525,7 @@ public class PackWriterTest extends SampleDataRepositoryTestCase {
RevCommit c2 = bb.commit().add("f", contentB).create();
testRepo.getRevWalk().parseHeaders(c2);
PackIndex pf2 = writePack(repo, Collections.singleton(c2),
- Collections.singleton(objectIdSet(pf1)));
+ Collections.<ObjectIdSet> singleton(pf1));
assertContent(
pf2,
Arrays.asList(c2.getId(), c2.getTree().getId(),
@@ -519,8 +550,7 @@ public class PackWriterTest extends SampleDataRepositoryTestCase {
pw.setReuseDeltaCommits(false);
for (ObjectIdSet idx : excludeObjects)
pw.excludeObjects(idx);
- pw.preparePack(NullProgressMonitor.INSTANCE, want,
- Collections.<ObjectId> emptySet());
+ pw.preparePack(NullProgressMonitor.INSTANCE, want, NONE);
String id = pw.computeName().getName();
File packdir = new File(repo.getObjectsDirectory(), "pack");
File packFile = new File(packdir, "pack-" + id + ".pack");
@@ -543,7 +573,7 @@ public class PackWriterTest extends SampleDataRepositoryTestCase {
final HashSet<ObjectId> interestings = new HashSet<ObjectId>();
interestings.add(ObjectId
.fromString("82c6b885ff600be425b4ea96dee75dca255b69e7"));
- createVerifyOpenPack(interestings, EMPTY_SET_OBJECT, false, false);
+ createVerifyOpenPack(interestings, NONE, false, false);
final ObjectId expectedOrder[] = new ObjectId[] {
ObjectId.fromString("82c6b885ff600be425b4ea96dee75dca255b69e7"),
@@ -699,12 +729,4 @@ public class PackWriterTest extends SampleDataRepositoryTestCase {
assertEquals(objectsOrder[i++].toObjectId(), me.toObjectId());
}
}
-
- private static ObjectIdSet objectIdSet(final PackIndex idx) {
- return new ObjectIdSet() {
- public boolean contains(AnyObjectId objectId) {
- return idx.hasObject(objectId);
- }
- };
- }
}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/T0003_BasicTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/T0003_BasicTest.java
index a92ff8d04e..f4d655f86b 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/T0003_BasicTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/T0003_BasicTest.java
@@ -67,7 +67,6 @@ import org.eclipse.jgit.lib.AnyObjectId;
import org.eclipse.jgit.lib.CommitBuilder;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.FileMode;
-import org.eclipse.jgit.lib.FileTreeEntry;
import org.eclipse.jgit.lib.ObjectDatabase;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectInserter;
@@ -75,7 +74,6 @@ import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.lib.RefUpdate;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.lib.TagBuilder;
-import org.eclipse.jgit.lib.Tree;
import org.eclipse.jgit.lib.TreeFormatter;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevTag;
@@ -420,29 +418,6 @@ public class T0003_BasicTest extends SampleDataRepositoryTestCase {
}
@Test
- public void test012_SubtreeExternalSorting() throws IOException {
- final ObjectId emptyBlob = insertEmptyBlob();
- final Tree t = new Tree(db);
- final FileTreeEntry e0 = t.addFile("a-");
- final FileTreeEntry e1 = t.addFile("a-b");
- final FileTreeEntry e2 = t.addFile("a/b");
- final FileTreeEntry e3 = t.addFile("a=");
- final FileTreeEntry e4 = t.addFile("a=b");
-
- e0.setId(emptyBlob);
- e1.setId(emptyBlob);
- e2.setId(emptyBlob);
- e3.setId(emptyBlob);
- e4.setId(emptyBlob);
-
- final Tree a = (Tree) t.findTreeMember("a");
- a.setId(insertTree(a));
- assertEquals(ObjectId
- .fromString("b47a8f0a4190f7572e11212769090523e23eb1ea"),
- insertTree(t));
- }
-
- @Test
public void test020_createBlobTag() throws IOException {
final ObjectId emptyId = insertEmptyBlob();
final TagBuilder t = new TagBuilder();
@@ -465,9 +440,8 @@ public class T0003_BasicTest extends SampleDataRepositoryTestCase {
@Test
public void test021_createTreeTag() throws IOException {
final ObjectId emptyId = insertEmptyBlob();
- final Tree almostEmptyTree = new Tree(db);
- almostEmptyTree.addEntry(new FileTreeEntry(almostEmptyTree, emptyId,
- "empty".getBytes(), false));
+ TreeFormatter almostEmptyTree = new TreeFormatter();
+ almostEmptyTree.append("empty", FileMode.REGULAR_FILE, emptyId);
final ObjectId almostEmptyTreeId = insertTree(almostEmptyTree);
final TagBuilder t = new TagBuilder();
t.setObjectId(almostEmptyTreeId, Constants.OBJ_TREE);
@@ -489,9 +463,8 @@ public class T0003_BasicTest extends SampleDataRepositoryTestCase {
@Test
public void test022_createCommitTag() throws IOException {
final ObjectId emptyId = insertEmptyBlob();
- final Tree almostEmptyTree = new Tree(db);
- almostEmptyTree.addEntry(new FileTreeEntry(almostEmptyTree, emptyId,
- "empty".getBytes(), false));
+ TreeFormatter almostEmptyTree = new TreeFormatter();
+ almostEmptyTree.append("empty", FileMode.REGULAR_FILE, emptyId);
final ObjectId almostEmptyTreeId = insertTree(almostEmptyTree);
final CommitBuilder almostEmptyCommit = new CommitBuilder();
almostEmptyCommit.setAuthor(new PersonIdent(author, 1154236443000L,
@@ -521,9 +494,8 @@ public class T0003_BasicTest extends SampleDataRepositoryTestCase {
@Test
public void test023_createCommitNonAnullii() throws IOException {
final ObjectId emptyId = insertEmptyBlob();
- final Tree almostEmptyTree = new Tree(db);
- almostEmptyTree.addEntry(new FileTreeEntry(almostEmptyTree, emptyId,
- "empty".getBytes(), false));
+ TreeFormatter almostEmptyTree = new TreeFormatter();
+ almostEmptyTree.append("empty", FileMode.REGULAR_FILE, emptyId);
final ObjectId almostEmptyTreeId = insertTree(almostEmptyTree);
CommitBuilder commit = new CommitBuilder();
commit.setTreeId(almostEmptyTreeId);
@@ -543,9 +515,8 @@ public class T0003_BasicTest extends SampleDataRepositoryTestCase {
@Test
public void test024_createCommitNonAscii() throws IOException {
final ObjectId emptyId = insertEmptyBlob();
- final Tree almostEmptyTree = new Tree(db);
- almostEmptyTree.addEntry(new FileTreeEntry(almostEmptyTree, emptyId,
- "empty".getBytes(), false));
+ TreeFormatter almostEmptyTree = new TreeFormatter();
+ almostEmptyTree.append("empty", FileMode.REGULAR_FILE, emptyId);
final ObjectId almostEmptyTreeId = insertTree(almostEmptyTree);
CommitBuilder commit = new CommitBuilder();
commit.setTreeId(almostEmptyTreeId);
@@ -747,14 +718,6 @@ public class T0003_BasicTest extends SampleDataRepositoryTestCase {
return emptyId;
}
- private ObjectId insertTree(Tree tree) throws IOException {
- try (ObjectInserter oi = db.newObjectInserter()) {
- ObjectId id = oi.insert(Constants.OBJ_TREE, tree.format());
- oi.flush();
- return id;
- }
- }
-
private ObjectId insertTree(TreeFormatter tree) throws IOException {
try (ObjectInserter oi = db.newObjectInserter()) {
ObjectId id = oi.insert(tree);
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftree/RefTreeDatabaseTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftree/RefTreeDatabaseTest.java
new file mode 100644
index 0000000000..020d1b1b51
--- /dev/null
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftree/RefTreeDatabaseTest.java
@@ -0,0 +1,685 @@
+/*
+ * Copyright (C) 2010, 2013, 2016 Google Inc.
+ * and other copyright owners as documented in the project's IP log.
+ *
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Distribution License v1.0 which
+ * accompanies this distribution, is reproduced below, and is
+ * available at http://www.eclipse.org/org/documents/edl-v10.php
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * - Neither the name of the Eclipse Foundation, Inc. nor the
+ * names of its contributors may be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.eclipse.jgit.internal.storage.reftree;
+
+import static org.eclipse.jgit.lib.Constants.HEAD;
+import static org.eclipse.jgit.lib.Constants.R_HEADS;
+import static org.eclipse.jgit.lib.Constants.R_TAGS;
+import static org.eclipse.jgit.lib.Ref.Storage.LOOSE;
+import static org.eclipse.jgit.lib.Ref.Storage.PACKED;
+import static org.eclipse.jgit.lib.RefDatabase.ALL;
+import static org.eclipse.jgit.transport.ReceiveCommand.Result.LOCK_FAILURE;
+import static org.eclipse.jgit.transport.ReceiveCommand.Result.OK;
+import static org.eclipse.jgit.transport.ReceiveCommand.Result.REJECTED_NONFASTFORWARD;
+import static org.eclipse.jgit.transport.ReceiveCommand.Result.REJECTED_OTHER_REASON;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.IOException;
+import java.text.MessageFormat;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.jgit.internal.JGitText;
+import org.eclipse.jgit.internal.storage.dfs.DfsRepositoryDescription;
+import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository;
+import org.eclipse.jgit.junit.TestRepository;
+import org.eclipse.jgit.lib.AnyObjectId;
+import org.eclipse.jgit.lib.BatchRefUpdate;
+import org.eclipse.jgit.lib.CommitBuilder;
+import org.eclipse.jgit.lib.NullProgressMonitor;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.ObjectIdRef;
+import org.eclipse.jgit.lib.ObjectInserter;
+import org.eclipse.jgit.lib.ObjectReader;
+import org.eclipse.jgit.lib.Ref;
+import org.eclipse.jgit.lib.RefDatabase;
+import org.eclipse.jgit.lib.RefUpdate;
+import org.eclipse.jgit.lib.SymbolicRef;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.revwalk.RevTag;
+import org.eclipse.jgit.revwalk.RevWalk;
+import org.eclipse.jgit.transport.ReceiveCommand;
+import org.junit.Before;
+import org.junit.Test;
+
+public class RefTreeDatabaseTest {
+ private InMemRefTreeRepo repo;
+ private RefTreeDatabase refdb;
+ private RefDatabase bootstrap;
+
+ private TestRepository<InMemRefTreeRepo> testRepo;
+ private RevCommit A;
+ private RevCommit B;
+ private RevTag v1_0;
+
+ @Before
+ public void setUp() throws Exception {
+ repo = new InMemRefTreeRepo(new DfsRepositoryDescription("test"));
+ bootstrap = refdb.getBootstrap();
+
+ testRepo = new TestRepository<>(repo);
+ A = testRepo.commit().create();
+ B = testRepo.commit(testRepo.getRevWalk().parseCommit(A));
+ v1_0 = testRepo.tag("v1_0", B);
+ testRepo.getRevWalk().parseBody(v1_0);
+ }
+
+ @Test
+ public void testSupportsAtomic() {
+ assertTrue(refdb.performsAtomicTransactions());
+ }
+
+ @Test
+ public void testGetRefs_EmptyDatabase() throws IOException {
+ assertTrue("no references", refdb.getRefs(ALL).isEmpty());
+ assertTrue("no references", refdb.getRefs(R_HEADS).isEmpty());
+ assertTrue("no references", refdb.getRefs(R_TAGS).isEmpty());
+ }
+
+ @Test
+ public void testGetRefs_HeadOnOneBranch() throws IOException {
+ symref(HEAD, "refs/heads/master");
+ update("refs/heads/master", A);
+
+ Map<String, Ref> all = refdb.getRefs(ALL);
+ assertEquals(2, all.size());
+ assertTrue("has HEAD", all.containsKey(HEAD));
+ assertTrue("has master", all.containsKey("refs/heads/master"));
+
+ Ref head = all.get(HEAD);
+ Ref master = all.get("refs/heads/master");
+
+ assertEquals(HEAD, head.getName());
+ assertTrue(head.isSymbolic());
+ assertSame(LOOSE, head.getStorage());
+ assertSame("uses same ref as target", master, head.getTarget());
+
+ assertEquals("refs/heads/master", master.getName());
+ assertFalse(master.isSymbolic());
+ assertSame(PACKED, master.getStorage());
+ assertEquals(A, master.getObjectId());
+ }
+
+ @Test
+ public void testGetRefs_DetachedHead() throws IOException {
+ update(HEAD, A);
+
+ Map<String, Ref> all = refdb.getRefs(ALL);
+ assertEquals(1, all.size());
+ assertTrue("has HEAD", all.containsKey(HEAD));
+
+ Ref head = all.get(HEAD);
+ assertEquals(HEAD, head.getName());
+ assertFalse(head.isSymbolic());
+ assertSame(PACKED, head.getStorage());
+ assertEquals(A, head.getObjectId());
+ }
+
+ @Test
+ public void testGetRefs_DeeplyNestedBranch() throws IOException {
+ String name = "refs/heads/a/b/c/d/e/f/g/h/i/j/k";
+ update(name, A);
+
+ Map<String, Ref> all = refdb.getRefs(ALL);
+ assertEquals(1, all.size());
+
+ Ref r = all.get(name);
+ assertEquals(name, r.getName());
+ assertFalse(r.isSymbolic());
+ assertSame(PACKED, r.getStorage());
+ assertEquals(A, r.getObjectId());
+ }
+
+ @Test
+ public void testGetRefs_HeadBranchNotBorn() throws IOException {
+ update("refs/heads/A", A);
+ update("refs/heads/B", B);
+
+ Map<String, Ref> all = refdb.getRefs(ALL);
+ assertEquals(2, all.size());
+ assertFalse("no HEAD", all.containsKey(HEAD));
+
+ Ref a = all.get("refs/heads/A");
+ Ref b = all.get("refs/heads/B");
+
+ assertEquals(A, a.getObjectId());
+ assertEquals(B, b.getObjectId());
+
+ assertEquals("refs/heads/A", a.getName());
+ assertEquals("refs/heads/B", b.getName());
+ }
+
+ @Test
+ public void testGetRefs_HeadsOnly() throws IOException {
+ update("refs/heads/A", A);
+ update("refs/heads/B", B);
+ update("refs/tags/v1.0", v1_0);
+
+ Map<String, Ref> heads = refdb.getRefs(R_HEADS);
+ assertEquals(2, heads.size());
+
+ Ref a = heads.get("A");
+ Ref b = heads.get("B");
+
+ assertEquals("refs/heads/A", a.getName());
+ assertEquals("refs/heads/B", b.getName());
+
+ assertEquals(A, a.getObjectId());
+ assertEquals(B, b.getObjectId());
+ }
+
+ @Test
+ public void testGetRefs_TagsOnly() throws IOException {
+ update("refs/heads/A", A);
+ update("refs/heads/B", B);
+ update("refs/tags/v1.0", v1_0);
+
+ Map<String, Ref> tags = refdb.getRefs(R_TAGS);
+ assertEquals(1, tags.size());
+
+ Ref a = tags.get("v1.0");
+ assertEquals("refs/tags/v1.0", a.getName());
+ assertEquals(v1_0, a.getObjectId());
+ assertTrue(a.isPeeled());
+ assertEquals(v1_0.getObject(), a.getPeeledObjectId());
+ }
+
+ @Test
+ public void testGetRefs_HeadsSymref() throws IOException {
+ symref("refs/heads/other", "refs/heads/master");
+ update("refs/heads/master", A);
+
+ Map<String, Ref> heads = refdb.getRefs(R_HEADS);
+ assertEquals(2, heads.size());
+
+ Ref master = heads.get("master");
+ Ref other = heads.get("other");
+
+ assertEquals("refs/heads/master", master.getName());
+ assertEquals(A, master.getObjectId());
+
+ assertEquals("refs/heads/other", other.getName());
+ assertEquals(A, other.getObjectId());
+ assertSame(master, other.getTarget());
+ }
+
+ @Test
+ public void testGetRefs_InvalidPrefixes() throws IOException {
+ update("refs/heads/A", A);
+
+ assertTrue("empty refs/heads", refdb.getRefs("refs/heads").isEmpty());
+ assertTrue("empty objects", refdb.getRefs("objects").isEmpty());
+ assertTrue("empty objects/", refdb.getRefs("objects/").isEmpty());
+ }
+
+ @Test
+ public void testGetRefs_DiscoversNew() throws IOException {
+ update("refs/heads/master", A);
+ Map<String, Ref> orig = refdb.getRefs(ALL);
+
+ update("refs/heads/next", B);
+ Map<String, Ref> next = refdb.getRefs(ALL);
+
+ assertEquals(1, orig.size());
+ assertEquals(2, next.size());
+
+ assertFalse(orig.containsKey("refs/heads/next"));
+ assertTrue(next.containsKey("refs/heads/next"));
+
+ assertEquals(A, next.get("refs/heads/master").getObjectId());
+ assertEquals(B, next.get("refs/heads/next").getObjectId());
+ }
+
+ @Test
+ public void testGetRefs_DiscoversModified() throws IOException {
+ symref(HEAD, "refs/heads/master");
+ update("refs/heads/master", A);
+
+ Map<String, Ref> all = refdb.getRefs(ALL);
+ assertEquals(A, all.get(HEAD).getObjectId());
+
+ update("refs/heads/master", B);
+ all = refdb.getRefs(ALL);
+ assertEquals(B, all.get(HEAD).getObjectId());
+ assertEquals(B, refdb.exactRef(HEAD).getObjectId());
+ }
+
+ @Test
+ public void testGetRefs_CycleInSymbolicRef() throws IOException {
+ symref("refs/1", "refs/2");
+ symref("refs/2", "refs/3");
+ symref("refs/3", "refs/4");
+ symref("refs/4", "refs/5");
+ symref("refs/5", "refs/end");
+ update("refs/end", A);
+
+ Map<String, Ref> all = refdb.getRefs(ALL);
+ Ref r = all.get("refs/1");
+ assertNotNull("has 1", r);
+
+ assertEquals("refs/1", r.getName());
+ assertEquals(A, r.getObjectId());
+ assertTrue(r.isSymbolic());
+
+ r = r.getTarget();
+ assertEquals("refs/2", r.getName());
+ assertEquals(A, r.getObjectId());
+ assertTrue(r.isSymbolic());
+
+ r = r.getTarget();
+ assertEquals("refs/3", r.getName());
+ assertEquals(A, r.getObjectId());
+ assertTrue(r.isSymbolic());
+
+ r = r.getTarget();
+ assertEquals("refs/4", r.getName());
+ assertEquals(A, r.getObjectId());
+ assertTrue(r.isSymbolic());
+
+ r = r.getTarget();
+ assertEquals("refs/5", r.getName());
+ assertEquals(A, r.getObjectId());
+ assertTrue(r.isSymbolic());
+
+ r = r.getTarget();
+ assertEquals("refs/end", r.getName());
+ assertEquals(A, r.getObjectId());
+ assertFalse(r.isSymbolic());
+
+ symref("refs/5", "refs/6");
+ symref("refs/6", "refs/end");
+ all = refdb.getRefs(ALL);
+ assertNull("mising 1 due to cycle", all.get("refs/1"));
+ assertEquals(A, all.get("refs/2").getObjectId());
+ assertEquals(A, all.get("refs/3").getObjectId());
+ assertEquals(A, all.get("refs/4").getObjectId());
+ assertEquals(A, all.get("refs/5").getObjectId());
+ assertEquals(A, all.get("refs/6").getObjectId());
+ assertEquals(A, all.get("refs/end").getObjectId());
+ }
+
+ @Test
+ public void testGetRef_NonExistingBranchConfig() throws IOException {
+ assertNull("find branch config", refdb.getRef("config"));
+ assertNull("find branch config", refdb.getRef("refs/heads/config"));
+ }
+
+ @Test
+ public void testGetRef_FindBranchConfig() throws IOException {
+ update("refs/heads/config", A);
+
+ for (String t : new String[] { "config", "refs/heads/config" }) {
+ Ref r = refdb.getRef(t);
+ assertNotNull("find branch config (" + t + ")", r);
+ assertEquals("for " + t, "refs/heads/config", r.getName());
+ assertEquals("for " + t, A, r.getObjectId());
+ }
+ }
+
+ @Test
+ public void testFirstExactRef() throws IOException {
+ update("refs/heads/A", A);
+ update("refs/tags/v1.0", v1_0);
+
+ Ref a = refdb.firstExactRef("refs/heads/A", "refs/tags/v1.0");
+ Ref one = refdb.firstExactRef("refs/tags/v1.0", "refs/heads/A");
+
+ assertEquals("refs/heads/A", a.getName());
+ assertEquals("refs/tags/v1.0", one.getName());
+
+ assertEquals(A, a.getObjectId());
+ assertEquals(v1_0, one.getObjectId());
+ }
+
+ @Test
+ public void testExactRef_DiscoversModified() throws IOException {
+ symref(HEAD, "refs/heads/master");
+ update("refs/heads/master", A);
+ assertEquals(A, refdb.exactRef(HEAD).getObjectId());
+
+ update("refs/heads/master", B);
+ assertEquals(B, refdb.exactRef(HEAD).getObjectId());
+ }
+
+ @Test
+ public void testIsNameConflicting() throws IOException {
+ update("refs/heads/a/b", A);
+ update("refs/heads/q", B);
+
+ // new references cannot replace an existing container
+ assertTrue(refdb.isNameConflicting("refs"));
+ assertTrue(refdb.isNameConflicting("refs/heads"));
+ assertTrue(refdb.isNameConflicting("refs/heads/a"));
+
+ // existing reference is not conflicting
+ assertFalse(refdb.isNameConflicting("refs/heads/a/b"));
+
+ // new references are not conflicting
+ assertFalse(refdb.isNameConflicting("refs/heads/a/d"));
+ assertFalse(refdb.isNameConflicting("refs/heads/master"));
+
+ // existing reference must not be used as a container
+ assertTrue(refdb.isNameConflicting("refs/heads/a/b/c"));
+ assertTrue(refdb.isNameConflicting("refs/heads/q/master"));
+
+ // refs/txn/ names always conflict.
+ assertTrue(refdb.isNameConflicting(refdb.getTxnCommitted()));
+ assertTrue(refdb.isNameConflicting("refs/txn/foo"));
+ }
+
+ @Test
+ public void testUpdate_RefusesRefsTxnNamespace() throws IOException {
+ ObjectId txnId = getTxnCommitted();
+
+ RefUpdate u = refdb.newUpdate("refs/txn/tmp", false);
+ u.setNewObjectId(B);
+ assertEquals(RefUpdate.Result.LOCK_FAILURE, u.update());
+ assertEquals(txnId, getTxnCommitted());
+
+ ReceiveCommand cmd = command(null, B, "refs/txn/tmp");
+ BatchRefUpdate batch = refdb.newBatchUpdate();
+ batch.addCommand(cmd);
+ batch.execute(new RevWalk(repo), NullProgressMonitor.INSTANCE);
+
+ assertEquals(REJECTED_OTHER_REASON, cmd.getResult());
+ assertEquals(MessageFormat.format(JGitText.get().invalidRefName,
+ "refs/txn/tmp"), cmd.getMessage());
+ assertEquals(txnId, getTxnCommitted());
+ }
+
+ @Test
+ public void testUpdate_RefusesDotLockInRefName() throws IOException {
+ ObjectId txnId = getTxnCommitted();
+
+ RefUpdate u = refdb.newUpdate("refs/heads/pu.lock", false);
+ u.setNewObjectId(B);
+ assertEquals(RefUpdate.Result.REJECTED, u.update());
+ assertEquals(txnId, getTxnCommitted());
+
+ ReceiveCommand cmd = command(null, B, "refs/heads/pu.lock");
+ BatchRefUpdate batch = refdb.newBatchUpdate();
+ batch.addCommand(cmd);
+ batch.execute(new RevWalk(repo), NullProgressMonitor.INSTANCE);
+
+ assertEquals(REJECTED_OTHER_REASON, cmd.getResult());
+ assertEquals(JGitText.get().funnyRefname, cmd.getMessage());
+ assertEquals(txnId, getTxnCommitted());
+ }
+
+ @Test
+ public void testBatchRefUpdate_NonFastForwardAborts() throws IOException {
+ update("refs/heads/master", A);
+ update("refs/heads/masters", B);
+ ObjectId txnId = getTxnCommitted();
+
+ List<ReceiveCommand> commands = Arrays.asList(
+ command(A, B, "refs/heads/master"),
+ command(B, A, "refs/heads/masters"));
+ BatchRefUpdate batchUpdate = refdb.newBatchUpdate();
+ batchUpdate.addCommand(commands);
+ batchUpdate.execute(new RevWalk(repo), NullProgressMonitor.INSTANCE);
+ assertEquals(txnId, getTxnCommitted());
+
+ assertEquals(REJECTED_NONFASTFORWARD,
+ commands.get(1).getResult());
+ assertEquals(REJECTED_OTHER_REASON,
+ commands.get(0).getResult());
+ assertEquals(JGitText.get().transactionAborted,
+ commands.get(0).getMessage());
+ }
+
+ @Test
+ public void testBatchRefUpdate_ForceUpdate() throws IOException {
+ update("refs/heads/master", A);
+ update("refs/heads/masters", B);
+ ObjectId txnId = getTxnCommitted();
+
+ List<ReceiveCommand> commands = Arrays.asList(
+ command(A, B, "refs/heads/master"),
+ command(B, A, "refs/heads/masters"));
+ BatchRefUpdate batchUpdate = refdb.newBatchUpdate();
+ batchUpdate.setAllowNonFastForwards(true);
+ batchUpdate.addCommand(commands);
+ batchUpdate.execute(new RevWalk(repo), NullProgressMonitor.INSTANCE);
+ assertNotEquals(txnId, getTxnCommitted());
+
+ Map<String, Ref> refs = refdb.getRefs(ALL);
+ assertEquals(OK, commands.get(0).getResult());
+ assertEquals(OK, commands.get(1).getResult());
+ assertEquals(
+ "[refs/heads/master, refs/heads/masters]",
+ refs.keySet().toString());
+ assertEquals(B.getId(), refs.get("refs/heads/master").getObjectId());
+ assertEquals(A.getId(), refs.get("refs/heads/masters").getObjectId());
+ }
+
+ @Test
+ public void testBatchRefUpdate_NonFastForwardDoesNotDoExpensiveMergeCheck()
+ throws IOException {
+ update("refs/heads/master", B);
+ ObjectId txnId = getTxnCommitted();
+
+ List<ReceiveCommand> commands = Arrays.asList(
+ command(B, A, "refs/heads/master"));
+ BatchRefUpdate batchUpdate = refdb.newBatchUpdate();
+ batchUpdate.setAllowNonFastForwards(true);
+ batchUpdate.addCommand(commands);
+ batchUpdate.execute(new RevWalk(repo) {
+ @Override
+ public boolean isMergedInto(RevCommit base, RevCommit tip) {
+ fail("isMergedInto() should not be called");
+ return false;
+ }
+ }, NullProgressMonitor.INSTANCE);
+ assertNotEquals(txnId, getTxnCommitted());
+
+ Map<String, Ref> refs = refdb.getRefs(ALL);
+ assertEquals(OK, commands.get(0).getResult());
+ assertEquals(A.getId(), refs.get("refs/heads/master").getObjectId());
+ }
+
+ @Test
+ public void testBatchRefUpdate_ConflictCausesAbort() throws IOException {
+ update("refs/heads/master", A);
+ update("refs/heads/masters", B);
+ ObjectId txnId = getTxnCommitted();
+
+ List<ReceiveCommand> commands = Arrays.asList(
+ command(A, B, "refs/heads/master"),
+ command(null, A, "refs/heads/master/x"),
+ command(null, A, "refs/heads"));
+ BatchRefUpdate batchUpdate = refdb.newBatchUpdate();
+ batchUpdate.setAllowNonFastForwards(true);
+ batchUpdate.addCommand(commands);
+ batchUpdate.execute(new RevWalk(repo), NullProgressMonitor.INSTANCE);
+ assertEquals(txnId, getTxnCommitted());
+
+ assertEquals(LOCK_FAILURE, commands.get(0).getResult());
+
+ assertEquals(REJECTED_OTHER_REASON, commands.get(1).getResult());
+ assertEquals(JGitText.get().transactionAborted,
+ commands.get(1).getMessage());
+
+ assertEquals(REJECTED_OTHER_REASON, commands.get(2).getResult());
+ assertEquals(JGitText.get().transactionAborted,
+ commands.get(2).getMessage());
+ }
+
+ @Test
+ public void testBatchRefUpdate_NoConflictIfDeleted() throws IOException {
+ update("refs/heads/master", A);
+ update("refs/heads/masters", B);
+ ObjectId txnId = getTxnCommitted();
+
+ List<ReceiveCommand> commands = Arrays.asList(
+ command(A, B, "refs/heads/master"),
+ command(null, A, "refs/heads/masters/x"),
+ command(B, null, "refs/heads/masters"));
+ BatchRefUpdate batchUpdate = refdb.newBatchUpdate();
+ batchUpdate.setAllowNonFastForwards(true);
+ batchUpdate.addCommand(commands);
+ batchUpdate.execute(new RevWalk(repo), NullProgressMonitor.INSTANCE);
+ assertNotEquals(txnId, getTxnCommitted());
+
+ assertEquals(OK, commands.get(0).getResult());
+ assertEquals(OK, commands.get(1).getResult());
+ assertEquals(OK, commands.get(2).getResult());
+
+ Map<String, Ref> refs = refdb.getRefs(ALL);
+ assertEquals(
+ "[refs/heads/master, refs/heads/masters/x]",
+ refs.keySet().toString());
+ assertEquals(A.getId(), refs.get("refs/heads/masters/x").getObjectId());
+ }
+
+ private ObjectId getTxnCommitted() throws IOException {
+ Ref r = bootstrap.exactRef(refdb.getTxnCommitted());
+ if (r != null && r.getObjectId() != null) {
+ return r.getObjectId();
+ }
+ return ObjectId.zeroId();
+ }
+
+ private static ReceiveCommand command(AnyObjectId a, AnyObjectId b,
+ String name) {
+ return new ReceiveCommand(
+ a != null ? a.copy() : ObjectId.zeroId(),
+ b != null ? b.copy() : ObjectId.zeroId(),
+ name);
+ }
+
+ private void symref(final String name, final String dst)
+ throws IOException {
+ commit(new Function() {
+ @Override
+ public boolean apply(ObjectReader reader, RefTree tree)
+ throws IOException {
+ Ref old = tree.exactRef(reader, name);
+ Command n = new Command(
+ old,
+ new SymbolicRef(
+ name,
+ new ObjectIdRef.Unpeeled(Ref.Storage.NEW, dst, null)));
+ return tree.apply(Collections.singleton(n));
+ }
+ });
+ }
+
+ private void update(final String name, final ObjectId id)
+ throws IOException {
+ commit(new Function() {
+ @Override
+ public boolean apply(ObjectReader reader, RefTree tree)
+ throws IOException {
+ Ref old = tree.exactRef(reader, name);
+ Command n;
+ try (RevWalk rw = new RevWalk(repo)) {
+ n = new Command(old, Command.toRef(rw, id, name, true));
+ }
+ return tree.apply(Collections.singleton(n));
+ }
+ });
+ }
+
+ interface Function {
+ boolean apply(ObjectReader reader, RefTree tree) throws IOException;
+ }
+
+ private void commit(Function fun) throws IOException {
+ try (ObjectReader reader = repo.newObjectReader();
+ ObjectInserter inserter = repo.newObjectInserter();
+ RevWalk rw = new RevWalk(reader)) {
+ RefUpdate u = bootstrap.newUpdate(refdb.getTxnCommitted(), false);
+ CommitBuilder cb = new CommitBuilder();
+ testRepo.setAuthorAndCommitter(cb);
+
+ Ref ref = bootstrap.exactRef(refdb.getTxnCommitted());
+ RefTree tree;
+ if (ref != null && ref.getObjectId() != null) {
+ tree = RefTree.read(reader, rw.parseTree(ref.getObjectId()));
+ cb.setParentId(ref.getObjectId());
+ u.setExpectedOldObjectId(ref.getObjectId());
+ } else {
+ tree = RefTree.newEmptyTree();
+ u.setExpectedOldObjectId(ObjectId.zeroId());
+ }
+
+ assertTrue(fun.apply(reader, tree));
+ cb.setTreeId(tree.writeTree(inserter));
+ u.setNewObjectId(inserter.insert(cb));
+ inserter.flush();
+ switch (u.update(rw)) {
+ case NEW:
+ case FAST_FORWARD:
+ break;
+ default:
+ fail("Expected " + u.getName() + " to update");
+ }
+ }
+ }
+
+ private class InMemRefTreeRepo extends InMemoryRepository {
+ private final RefTreeDatabase refs;
+
+ InMemRefTreeRepo(DfsRepositoryDescription repoDesc) {
+ super(repoDesc);
+ refs = new RefTreeDatabase(this, super.getRefDatabase(),
+ "refs/txn/committed");
+ RefTreeDatabaseTest.this.refdb = refs;
+ }
+
+ public RefDatabase getRefDatabase() {
+ return refs;
+ }
+ }
+}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftree/RefTreeTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftree/RefTreeTest.java
new file mode 100644
index 0000000000..8e0f38c69a
--- /dev/null
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftree/RefTreeTest.java
@@ -0,0 +1,303 @@
+/*
+ * Copyright (C) 2016, Google Inc.
+ * and other copyright owners as documented in the project's IP log.
+ *
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Distribution License v1.0 which
+ * accompanies this distribution, is reproduced below, and is
+ * available at http://www.eclipse.org/org/documents/edl-v10.php
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * - Neither the name of the Eclipse Foundation, Inc. nor the
+ * names of its contributors may be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.eclipse.jgit.internal.storage.reftree;
+
+import static org.eclipse.jgit.lib.Constants.HEAD;
+import static org.eclipse.jgit.lib.Constants.R_HEADS;
+import static org.eclipse.jgit.lib.Constants.R_TAGS;
+import static org.eclipse.jgit.lib.Ref.Storage.LOOSE;
+import static org.eclipse.jgit.lib.Ref.Storage.NEW;
+import static org.eclipse.jgit.transport.ReceiveCommand.Result.LOCK_FAILURE;
+import static org.eclipse.jgit.transport.ReceiveCommand.Result.NOT_ATTEMPTED;
+import static org.eclipse.jgit.transport.ReceiveCommand.Result.REJECTED_OTHER_REASON;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Collections;
+
+import org.eclipse.jgit.errors.MissingObjectException;
+import org.eclipse.jgit.internal.JGitText;
+import org.eclipse.jgit.internal.storage.dfs.DfsRepositoryDescription;
+import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository;
+import org.eclipse.jgit.junit.TestRepository;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.ObjectIdRef;
+import org.eclipse.jgit.lib.ObjectInserter;
+import org.eclipse.jgit.lib.ObjectReader;
+import org.eclipse.jgit.lib.Ref;
+import org.eclipse.jgit.lib.SymbolicRef;
+import org.eclipse.jgit.revwalk.RevBlob;
+import org.eclipse.jgit.revwalk.RevTag;
+import org.eclipse.jgit.revwalk.RevWalk;
+import org.eclipse.jgit.transport.ReceiveCommand;
+import org.junit.Before;
+import org.junit.Test;
+
+public class RefTreeTest {
+ private static final String R_MASTER = R_HEADS + "master";
+ private InMemoryRepository repo;
+ private TestRepository<InMemoryRepository> git;
+
+ @Before
+ public void setUp() throws IOException {
+ repo = new InMemoryRepository(new DfsRepositoryDescription("RefTree"));
+ git = new TestRepository<>(repo);
+ }
+
+ @Test
+ public void testEmptyTree() throws IOException {
+ RefTree tree = RefTree.newEmptyTree();
+ try (ObjectReader reader = repo.newObjectReader()) {
+ assertNull(HEAD, tree.exactRef(reader, HEAD));
+ assertNull("master", tree.exactRef(reader, R_MASTER));
+ }
+ }
+
+ @Test
+ public void testApplyThenReadMaster() throws Exception {
+ RefTree tree = RefTree.newEmptyTree();
+ RevBlob id = git.blob("A");
+ Command cmd = new Command(null, ref(R_MASTER, id));
+ assertTrue(tree.apply(Collections.singletonList(cmd)));
+ assertSame(NOT_ATTEMPTED, cmd.getResult());
+
+ try (ObjectReader reader = repo.newObjectReader()) {
+ Ref m = tree.exactRef(reader, R_MASTER);
+ assertNotNull(R_MASTER, m);
+ assertEquals(R_MASTER, m.getName());
+ assertEquals(id, m.getObjectId());
+ assertTrue("peeled", m.isPeeled());
+ }
+ }
+
+ @Test
+ public void testUpdateMaster() throws Exception {
+ RefTree tree = RefTree.newEmptyTree();
+ RevBlob id1 = git.blob("A");
+ Command cmd1 = new Command(null, ref(R_MASTER, id1));
+ assertTrue(tree.apply(Collections.singletonList(cmd1)));
+ assertSame(NOT_ATTEMPTED, cmd1.getResult());
+
+ RevBlob id2 = git.blob("B");
+ Command cmd2 = new Command(ref(R_MASTER, id1), ref(R_MASTER, id2));
+ assertTrue(tree.apply(Collections.singletonList(cmd2)));
+ assertSame(NOT_ATTEMPTED, cmd2.getResult());
+
+ try (ObjectReader reader = repo.newObjectReader()) {
+ Ref m = tree.exactRef(reader, R_MASTER);
+ assertNotNull(R_MASTER, m);
+ assertEquals(R_MASTER, m.getName());
+ assertEquals(id2, m.getObjectId());
+ assertTrue("peeled", m.isPeeled());
+ }
+ }
+
+ @Test
+ public void testHeadSymref() throws Exception {
+ RefTree tree = RefTree.newEmptyTree();
+ RevBlob id = git.blob("A");
+ Command cmd1 = new Command(null, ref(R_MASTER, id));
+ Command cmd2 = new Command(null, symref(HEAD, R_MASTER));
+ assertTrue(tree.apply(Arrays.asList(new Command[] { cmd1, cmd2 })));
+ assertSame(NOT_ATTEMPTED, cmd1.getResult());
+ assertSame(NOT_ATTEMPTED, cmd2.getResult());
+
+ try (ObjectReader reader = repo.newObjectReader()) {
+ Ref m = tree.exactRef(reader, HEAD);
+ assertNotNull(HEAD, m);
+ assertEquals(HEAD, m.getName());
+ assertTrue("symbolic", m.isSymbolic());
+ assertNotNull(m.getTarget());
+ assertEquals(R_MASTER, m.getTarget().getName());
+ assertEquals(id, m.getTarget().getObjectId());
+ }
+
+ // Writing flushes some buffers, re-read from blob.
+ ObjectId newId = write(tree);
+ try (ObjectReader reader = repo.newObjectReader();
+ RevWalk rw = new RevWalk(reader)) {
+ tree = RefTree.read(reader, rw.parseTree(newId));
+ Ref m = tree.exactRef(reader, HEAD);
+ assertEquals(R_MASTER, m.getTarget().getName());
+ }
+ }
+
+ @Test
+ public void testTagIsPeeled() throws Exception {
+ String name = "v1.0";
+ RefTree tree = RefTree.newEmptyTree();
+ RevBlob id = git.blob("A");
+ RevTag tag = git.tag(name, id);
+
+ String ref = R_TAGS + name;
+ Command cmd = create(ref, tag);
+ assertTrue(tree.apply(Collections.singletonList(cmd)));
+ assertSame(NOT_ATTEMPTED, cmd.getResult());
+
+ try (ObjectReader reader = repo.newObjectReader()) {
+ Ref m = tree.exactRef(reader, ref);
+ assertNotNull(ref, m);
+ assertEquals(ref, m.getName());
+ assertEquals(tag, m.getObjectId());
+ assertTrue("peeled", m.isPeeled());
+ assertEquals(id, m.getPeeledObjectId());
+ }
+ }
+
+ @Test
+ public void testApplyAlreadyExists() throws Exception {
+ RefTree tree = RefTree.newEmptyTree();
+ RevBlob a = git.blob("A");
+ Command cmd = new Command(null, ref(R_MASTER, a));
+ assertTrue(tree.apply(Collections.singletonList(cmd)));
+ ObjectId treeId = write(tree);
+
+ RevBlob b = git.blob("B");
+ Command cmd1 = create(R_MASTER, b);
+ Command cmd2 = create(R_MASTER, b);
+ assertFalse(tree.apply(Arrays.asList(new Command[] { cmd1, cmd2 })));
+ assertSame(LOCK_FAILURE, cmd1.getResult());
+ assertSame(REJECTED_OTHER_REASON, cmd2.getResult());
+ assertEquals(JGitText.get().transactionAborted, cmd2.getMessage());
+ assertEquals(treeId, write(tree));
+ }
+
+ @Test
+ public void testApplyWrongOldId() throws Exception {
+ RefTree tree = RefTree.newEmptyTree();
+ RevBlob a = git.blob("A");
+ Command cmd = new Command(null, ref(R_MASTER, a));
+ assertTrue(tree.apply(Collections.singletonList(cmd)));
+ ObjectId treeId = write(tree);
+
+ RevBlob b = git.blob("B");
+ RevBlob c = git.blob("C");
+ Command cmd1 = update(R_MASTER, b, c);
+ Command cmd2 = create(R_MASTER, b);
+ assertFalse(tree.apply(Arrays.asList(new Command[] { cmd1, cmd2 })));
+ assertSame(LOCK_FAILURE, cmd1.getResult());
+ assertSame(REJECTED_OTHER_REASON, cmd2.getResult());
+ assertEquals(JGitText.get().transactionAborted, cmd2.getMessage());
+ assertEquals(treeId, write(tree));
+ }
+
+ @Test
+ public void testApplyWrongOldIdButAlreadyCurrentIsNoOp() throws Exception {
+ RefTree tree = RefTree.newEmptyTree();
+ RevBlob a = git.blob("A");
+ Command cmd = new Command(null, ref(R_MASTER, a));
+ assertTrue(tree.apply(Collections.singletonList(cmd)));
+ ObjectId treeId = write(tree);
+
+ RevBlob b = git.blob("B");
+ cmd = update(R_MASTER, b, a);
+ assertTrue(tree.apply(Collections.singletonList(cmd)));
+ assertEquals(treeId, write(tree));
+ }
+
+ @Test
+ public void testApplyCannotCreateSubdirectory() throws Exception {
+ RefTree tree = RefTree.newEmptyTree();
+ RevBlob a = git.blob("A");
+ Command cmd = new Command(null, ref(R_MASTER, a));
+ assertTrue(tree.apply(Collections.singletonList(cmd)));
+ ObjectId treeId = write(tree);
+
+ RevBlob b = git.blob("B");
+ Command cmd1 = create(R_MASTER + "/fail", b);
+ assertFalse(tree.apply(Collections.singletonList(cmd1)));
+ assertSame(LOCK_FAILURE, cmd1.getResult());
+ assertEquals(treeId, write(tree));
+ }
+
+ @Test
+ public void testApplyCannotCreateParentRef() throws Exception {
+ RefTree tree = RefTree.newEmptyTree();
+ RevBlob a = git.blob("A");
+ Command cmd = new Command(null, ref(R_MASTER, a));
+ assertTrue(tree.apply(Collections.singletonList(cmd)));
+ ObjectId treeId = write(tree);
+
+ RevBlob b = git.blob("B");
+ Command cmd1 = create("refs/heads", b);
+ assertFalse(tree.apply(Collections.singletonList(cmd1)));
+ assertSame(LOCK_FAILURE, cmd1.getResult());
+ assertEquals(treeId, write(tree));
+ }
+
+ private static Ref ref(String name, ObjectId id) {
+ return new ObjectIdRef.PeeledNonTag(LOOSE, name, id);
+ }
+
+ private static Ref symref(String name, String dest) {
+ Ref d = new ObjectIdRef.PeeledNonTag(NEW, dest, null);
+ return new SymbolicRef(name, d);
+ }
+
+ private Command create(String name, ObjectId id)
+ throws MissingObjectException, IOException {
+ return update(name, ObjectId.zeroId(), id);
+ }
+
+ private Command update(String name, ObjectId oldId, ObjectId newId)
+ throws MissingObjectException, IOException {
+ try (RevWalk rw = new RevWalk(repo)) {
+ return new Command(rw, new ReceiveCommand(oldId, newId, name));
+ }
+ }
+
+ private ObjectId write(RefTree tree) throws IOException {
+ try (ObjectInserter ins = repo.newObjectInserter()) {
+ ObjectId id = tree.writeTree(ins);
+ ins.flush();
+ return id;
+ }
+ }
+}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/DirCacheCheckoutTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/DirCacheCheckoutTest.java
index d768e0fa0b..92901f826b 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/DirCacheCheckoutTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/DirCacheCheckoutTest.java
@@ -1084,7 +1084,7 @@ public class DirCacheCheckoutTest extends RepositoryTestCase {
assertWorkDir(mkmap(linkName, "a", fname, "a"));
Status st = git.status().call();
- assertFalse(st.isClean());
+ assertTrue(st.isClean());
}
@Test
@@ -1213,9 +1213,7 @@ public class DirCacheCheckoutTest extends RepositoryTestCase {
assertWorkDir(mkmap(fname, "a"));
Status st = git.status().call();
- assertFalse(st.isClean());
- assertEquals(1, st.getAdded().size());
- assertTrue(st.getAdded().contains(fname + "/dir/file1"));
+ assertTrue(st.isClean());
}
@Test
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 a5cd7b5c0b..7fcee3dc82 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
@@ -99,8 +99,7 @@ public class IndexDiffTest extends RepositoryTestCase {
public void testAdded() throws IOException {
writeTrashFile("file1", "file1");
writeTrashFile("dir/subfile", "dir/subfile");
- Tree tree = new Tree(db);
- tree.setId(insertTree(tree));
+ ObjectId tree = insertTree(new TreeFormatter());
DirCache index = db.lockDirCache();
DirCacheEditor editor = index.editor();
@@ -108,7 +107,7 @@ public class IndexDiffTest extends RepositoryTestCase {
editor.add(add(db, trash, "dir/subfile"));
editor.commit();
FileTreeIterator iterator = new FileTreeIterator(db);
- IndexDiff diff = new IndexDiff(db, tree.getId(), iterator);
+ IndexDiff diff = new IndexDiff(db, tree, iterator);
diff.diff();
assertEquals(2, diff.getAdded().size());
assertTrue(diff.getAdded().contains("file1"));
@@ -124,18 +123,16 @@ public class IndexDiffTest extends RepositoryTestCase {
writeTrashFile("file2", "file2");
writeTrashFile("dir/file3", "dir/file3");
- Tree tree = new Tree(db);
- tree.addFile("file2");
- tree.addFile("dir/file3");
- assertEquals(2, tree.memberCount());
- tree.findBlobMember("file2").setId(ObjectId.fromString("30d67d4672d5c05833b7192cc77a79eaafb5c7ad"));
- Tree tree2 = (Tree) tree.findTreeMember("dir");
- tree2.findBlobMember("file3").setId(ObjectId.fromString("873fb8d667d05436d728c52b1d7a09528e6eb59b"));
- tree2.setId(insertTree(tree2));
- tree.setId(insertTree(tree));
+ TreeFormatter dir = new TreeFormatter();
+ dir.append("file3", FileMode.REGULAR_FILE, ObjectId.fromString("873fb8d667d05436d728c52b1d7a09528e6eb59b"));
+
+ TreeFormatter tree = new TreeFormatter();
+ tree.append("file2", FileMode.REGULAR_FILE, ObjectId.fromString("30d67d4672d5c05833b7192cc77a79eaafb5c7ad"));
+ tree.append("dir", FileMode.TREE, insertTree(dir));
+ ObjectId treeId = insertTree(tree);
FileTreeIterator iterator = new FileTreeIterator(db);
- IndexDiff diff = new IndexDiff(db, tree.getId(), iterator);
+ IndexDiff diff = new IndexDiff(db, treeId, iterator);
diff.diff();
assertEquals(2, diff.getRemoved().size());
assertTrue(diff.getRemoved().contains("file2"));
@@ -157,16 +154,16 @@ public class IndexDiffTest extends RepositoryTestCase {
writeTrashFile("dir/file3", "changed");
- Tree tree = new Tree(db);
- tree.addFile("file2").setId(ObjectId.fromString("0123456789012345678901234567890123456789"));
- tree.addFile("dir/file3").setId(ObjectId.fromString("0123456789012345678901234567890123456789"));
- assertEquals(2, tree.memberCount());
+ TreeFormatter dir = new TreeFormatter();
+ dir.append("file3", FileMode.REGULAR_FILE, ObjectId.fromString("0123456789012345678901234567890123456789"));
+
+ TreeFormatter tree = new TreeFormatter();
+ tree.append("dir", FileMode.TREE, insertTree(dir));
+ tree.append("file2", FileMode.REGULAR_FILE, ObjectId.fromString("0123456789012345678901234567890123456789"));
+ ObjectId treeId = insertTree(tree);
- Tree tree2 = (Tree) tree.findTreeMember("dir");
- tree2.setId(insertTree(tree2));
- tree.setId(insertTree(tree));
FileTreeIterator iterator = new FileTreeIterator(db);
- IndexDiff diff = new IndexDiff(db, tree.getId(), iterator);
+ IndexDiff diff = new IndexDiff(db, treeId, iterator);
diff.diff();
assertEquals(2, diff.getChanged().size());
assertTrue(diff.getChanged().contains("file2"));
@@ -314,17 +311,16 @@ public class IndexDiffTest extends RepositoryTestCase {
git.add().addFilepattern("a=c").call();
git.add().addFilepattern("a=d").call();
- Tree tree = new Tree(db);
+ TreeFormatter tree = new TreeFormatter();
// got the hash id'd from the data using echo -n a.b|git hash-object -t blob --stdin
- tree.addFile("a.b").setId(ObjectId.fromString("f6f28df96c2b40c951164286e08be7c38ec74851"));
- tree.addFile("a.c").setId(ObjectId.fromString("6bc0e647512d2a0bef4f26111e484dc87df7f5ca"));
- tree.addFile("a=c").setId(ObjectId.fromString("06022365ddbd7fb126761319633bf73517770714"));
- tree.addFile("a=d").setId(ObjectId.fromString("fa6414df3da87840700e9eeb7fc261dd77ccd5c2"));
-
- tree.setId(insertTree(tree));
+ tree.append("a.b", FileMode.REGULAR_FILE, ObjectId.fromString("f6f28df96c2b40c951164286e08be7c38ec74851"));
+ tree.append("a.c", FileMode.REGULAR_FILE, ObjectId.fromString("6bc0e647512d2a0bef4f26111e484dc87df7f5ca"));
+ tree.append("a=c", FileMode.REGULAR_FILE, ObjectId.fromString("06022365ddbd7fb126761319633bf73517770714"));
+ tree.append("a=d", FileMode.REGULAR_FILE, ObjectId.fromString("fa6414df3da87840700e9eeb7fc261dd77ccd5c2"));
+ ObjectId treeId = insertTree(tree);
FileTreeIterator iterator = new FileTreeIterator(db);
- IndexDiff diff = new IndexDiff(db, tree.getId(), iterator);
+ IndexDiff diff = new IndexDiff(db, treeId, iterator);
diff.diff();
assertEquals(0, diff.getChanged().size());
assertEquals(0, diff.getAdded().size());
@@ -356,24 +352,27 @@ public class IndexDiffTest extends RepositoryTestCase {
.addFilepattern("a/c").addFilepattern("a=c")
.addFilepattern("a=d").call();
- Tree tree = new Tree(db);
+
// got the hash id'd from the data using echo -n a.b|git hash-object -t blob --stdin
- tree.addFile("a.b").setId(ObjectId.fromString("f6f28df96c2b40c951164286e08be7c38ec74851"));
- tree.addFile("a.c").setId(ObjectId.fromString("6bc0e647512d2a0bef4f26111e484dc87df7f5ca"));
- tree.addFile("a/b.b/b").setId(ObjectId.fromString("8d840bd4e2f3a48ff417c8e927d94996849933fd"));
- tree.addFile("a/b").setId(ObjectId.fromString("db89c972fc57862eae378f45b74aca228037d415"));
- tree.addFile("a/c").setId(ObjectId.fromString("52ad142a008aeb39694bafff8e8f1be75ed7f007"));
- tree.addFile("a=c").setId(ObjectId.fromString("06022365ddbd7fb126761319633bf73517770714"));
- tree.addFile("a=d").setId(ObjectId.fromString("fa6414df3da87840700e9eeb7fc261dd77ccd5c2"));
-
- Tree tree3 = (Tree) tree.findTreeMember("a/b.b");
- tree3.setId(insertTree(tree3));
- Tree tree2 = (Tree) tree.findTreeMember("a");
- tree2.setId(insertTree(tree2));
- tree.setId(insertTree(tree));
+ TreeFormatter bb = new TreeFormatter();
+ bb.append("b", FileMode.REGULAR_FILE, ObjectId.fromString("8d840bd4e2f3a48ff417c8e927d94996849933fd"));
+
+ TreeFormatter a = new TreeFormatter();
+ a.append("b", FileMode.REGULAR_FILE, ObjectId
+ .fromString("db89c972fc57862eae378f45b74aca228037d415"));
+ a.append("b.b", FileMode.TREE, insertTree(bb));
+ a.append("c", FileMode.REGULAR_FILE, ObjectId.fromString("52ad142a008aeb39694bafff8e8f1be75ed7f007"));
+
+ TreeFormatter tree = new TreeFormatter();
+ tree.append("a.b", FileMode.REGULAR_FILE, ObjectId.fromString("f6f28df96c2b40c951164286e08be7c38ec74851"));
+ tree.append("a.c", FileMode.REGULAR_FILE, ObjectId.fromString("6bc0e647512d2a0bef4f26111e484dc87df7f5ca"));
+ tree.append("a", FileMode.TREE, insertTree(a));
+ tree.append("a=c", FileMode.REGULAR_FILE, ObjectId.fromString("06022365ddbd7fb126761319633bf73517770714"));
+ tree.append("a=d", FileMode.REGULAR_FILE, ObjectId.fromString("fa6414df3da87840700e9eeb7fc261dd77ccd5c2"));
+ ObjectId treeId = insertTree(tree);
FileTreeIterator iterator = new FileTreeIterator(db);
- IndexDiff diff = new IndexDiff(db, tree.getId(), iterator);
+ IndexDiff diff = new IndexDiff(db, treeId, iterator);
diff.diff();
assertEquals(0, diff.getChanged().size());
assertEquals(0, diff.getAdded().size());
@@ -383,9 +382,9 @@ public class IndexDiffTest extends RepositoryTestCase {
assertEquals(Collections.EMPTY_SET, diff.getUntrackedFolders());
}
- private ObjectId insertTree(Tree tree) throws IOException {
+ private ObjectId insertTree(TreeFormatter tree) throws IOException {
try (ObjectInserter oi = db.newObjectInserter()) {
- ObjectId id = oi.insert(Constants.OBJ_TREE, tree.format());
+ ObjectId id = oi.insert(tree);
oi.flush();
return id;
}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ObjectCheckerTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ObjectCheckerTest.java
index 3abe81cf85..43160fb115 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ObjectCheckerTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ObjectCheckerTest.java
@@ -45,8 +45,25 @@
package org.eclipse.jgit.lib;
import static java.lang.Integer.valueOf;
-import static java.lang.Long.valueOf;
+import static org.eclipse.jgit.lib.Constants.OBJECT_ID_LENGTH;
+import static org.eclipse.jgit.lib.Constants.OBJ_BAD;
+import static org.eclipse.jgit.lib.Constants.OBJ_BLOB;
+import static org.eclipse.jgit.lib.Constants.OBJ_COMMIT;
+import static org.eclipse.jgit.lib.Constants.OBJ_TAG;
+import static org.eclipse.jgit.lib.Constants.OBJ_TREE;
+import static org.eclipse.jgit.lib.Constants.encode;
+import static org.eclipse.jgit.lib.Constants.encodeASCII;
+import static org.eclipse.jgit.lib.ObjectChecker.ErrorType.DUPLICATE_ENTRIES;
+import static org.eclipse.jgit.lib.ObjectChecker.ErrorType.EMPTY_NAME;
+import static org.eclipse.jgit.lib.ObjectChecker.ErrorType.FULL_PATHNAME;
+import static org.eclipse.jgit.lib.ObjectChecker.ErrorType.HAS_DOT;
+import static org.eclipse.jgit.lib.ObjectChecker.ErrorType.HAS_DOTDOT;
+import static org.eclipse.jgit.lib.ObjectChecker.ErrorType.HAS_DOTGIT;
+import static org.eclipse.jgit.lib.ObjectChecker.ErrorType.NULL_SHA1;
+import static org.eclipse.jgit.lib.ObjectChecker.ErrorType.TREE_NOT_SORTED;
+import static org.eclipse.jgit.lib.ObjectChecker.ErrorType.ZERO_PADDED_FILEMODE;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertSame;
import static org.junit.Assert.fail;
import java.io.UnsupportedEncodingException;
@@ -67,15 +84,10 @@ public class ObjectCheckerTest {
@Test
public void testInvalidType() {
- try {
- checker.check(Constants.OBJ_BAD, new byte[0]);
- fail("Did not throw CorruptObjectException");
- } catch (CorruptObjectException e) {
- final String m = e.getMessage();
- assertEquals(MessageFormat.format(
- JGitText.get().corruptObjectInvalidType2,
- valueOf(Constants.OBJ_BAD)), m);
- }
+ String msg = MessageFormat.format(
+ JGitText.get().corruptObjectInvalidType2,
+ valueOf(OBJ_BAD));
+ assertCorrupt(msg, OBJ_BAD, new byte[0]);
}
@Test
@@ -84,13 +96,13 @@ public class ObjectCheckerTest {
checker.checkBlob(new byte[0]);
checker.checkBlob(new byte[1]);
- checker.check(Constants.OBJ_BLOB, new byte[0]);
- checker.check(Constants.OBJ_BLOB, new byte[1]);
+ checker.check(OBJ_BLOB, new byte[0]);
+ checker.check(OBJ_BLOB, new byte[1]);
}
@Test
public void testValidCommitNoParent() throws CorruptObjectException {
- final StringBuilder b = new StringBuilder();
+ StringBuilder b = new StringBuilder();
b.append("tree ");
b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
@@ -99,14 +111,14 @@ public class ObjectCheckerTest {
b.append("author A. U. Thor <author@localhost> 1 +0000\n");
b.append("committer A. U. Thor <author@localhost> 1 +0000\n");
- final byte[] data = Constants.encodeASCII(b.toString());
+ byte[] data = encodeASCII(b.toString());
checker.checkCommit(data);
- checker.check(Constants.OBJ_COMMIT, data);
+ checker.check(OBJ_COMMIT, data);
}
@Test
public void testValidCommitBlankAuthor() throws CorruptObjectException {
- final StringBuilder b = new StringBuilder();
+ StringBuilder b = new StringBuilder();
b.append("tree ");
b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
@@ -115,9 +127,9 @@ public class ObjectCheckerTest {
b.append("author <> 0 +0000\n");
b.append("committer <> 0 +0000\n");
- final byte[] data = Constants.encodeASCII(b.toString());
+ byte[] data = encodeASCII(b.toString());
checker.checkCommit(data);
- checker.check(Constants.OBJ_COMMIT, data);
+ checker.check(OBJ_COMMIT, data);
}
@Test
@@ -127,15 +139,13 @@ public class ObjectCheckerTest {
b.append("author b <b@c> <b@c> 0 +0000\n");
b.append("committer <> 0 +0000\n");
- byte[] data = Constants.encodeASCII(b.toString());
- try {
- checker.checkCommit(data);
- fail("Did not catch corrupt object");
- } catch (CorruptObjectException e) {
- assertEquals("invalid author", e.getMessage());
- }
+ byte[] data = encodeASCII(b.toString());
+ assertCorrupt("bad date", OBJ_COMMIT, data);
checker.setAllowInvalidPersonIdent(true);
checker.checkCommit(data);
+
+ checker.setAllowInvalidPersonIdent(false);
+ assertSkipListAccepts(OBJ_COMMIT, data);
}
@Test
@@ -145,20 +155,18 @@ public class ObjectCheckerTest {
b.append("author <> 0 +0000\n");
b.append("committer b <b@c> <b@c> 0 +0000\n");
- byte[] data = Constants.encodeASCII(b.toString());
- try {
- checker.checkCommit(data);
- fail("Did not catch corrupt object");
- } catch (CorruptObjectException e) {
- assertEquals("invalid committer", e.getMessage());
- }
+ byte[] data = encodeASCII(b.toString());
+ assertCorrupt("bad date", OBJ_COMMIT, data);
checker.setAllowInvalidPersonIdent(true);
checker.checkCommit(data);
+
+ checker.setAllowInvalidPersonIdent(false);
+ assertSkipListAccepts(OBJ_COMMIT, data);
}
@Test
public void testValidCommit1Parent() throws CorruptObjectException {
- final StringBuilder b = new StringBuilder();
+ StringBuilder b = new StringBuilder();
b.append("tree ");
b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
@@ -171,14 +179,14 @@ public class ObjectCheckerTest {
b.append("author A. U. Thor <author@localhost> 1 +0000\n");
b.append("committer A. U. Thor <author@localhost> 1 +0000\n");
- final byte[] data = Constants.encodeASCII(b.toString());
+ byte[] data = encodeASCII(b.toString());
checker.checkCommit(data);
- checker.check(Constants.OBJ_COMMIT, data);
+ checker.check(OBJ_COMMIT, data);
}
@Test
public void testValidCommit2Parent() throws CorruptObjectException {
- final StringBuilder b = new StringBuilder();
+ StringBuilder b = new StringBuilder();
b.append("tree ");
b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
@@ -195,14 +203,14 @@ public class ObjectCheckerTest {
b.append("author A. U. Thor <author@localhost> 1 +0000\n");
b.append("committer A. U. Thor <author@localhost> 1 +0000\n");
- final byte[] data = Constants.encodeASCII(b.toString());
+ byte[] data = encodeASCII(b.toString());
checker.checkCommit(data);
- checker.check(Constants.OBJ_COMMIT, data);
+ checker.check(OBJ_COMMIT, data);
}
@Test
public void testValidCommit128Parent() throws CorruptObjectException {
- final StringBuilder b = new StringBuilder();
+ StringBuilder b = new StringBuilder();
b.append("tree ");
b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
@@ -217,15 +225,15 @@ public class ObjectCheckerTest {
b.append("author A. U. Thor <author@localhost> 1 +0000\n");
b.append("committer A. U. Thor <author@localhost> 1 +0000\n");
- final byte[] data = Constants.encodeASCII(b.toString());
+ byte[] data = encodeASCII(b.toString());
checker.checkCommit(data);
- checker.check(Constants.OBJ_COMMIT, data);
+ checker.check(OBJ_COMMIT, data);
}
@Test
public void testValidCommitNormalTime() throws CorruptObjectException {
- final StringBuilder b = new StringBuilder();
- final String when = "1222757360 -0730";
+ StringBuilder b = new StringBuilder();
+ String when = "1222757360 -0730";
b.append("tree ");
b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
@@ -234,843 +242,539 @@ public class ObjectCheckerTest {
b.append("author A. U. Thor <author@localhost> " + when + "\n");
b.append("committer A. U. Thor <author@localhost> " + when + "\n");
- final byte[] data = Constants.encodeASCII(b.toString());
+ byte[] data = encodeASCII(b.toString());
checker.checkCommit(data);
- checker.check(Constants.OBJ_COMMIT, data);
+ checker.check(OBJ_COMMIT, data);
}
@Test
public void testInvalidCommitNoTree1() {
- final StringBuilder b = new StringBuilder();
-
+ StringBuilder b = new StringBuilder();
b.append("parent ");
b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
b.append('\n');
-
- final byte[] data = Constants.encodeASCII(b.toString());
- try {
- checker.checkCommit(data);
- fail("Did not catch corrupt object");
- } catch (CorruptObjectException e) {
- assertEquals("no tree header", e.getMessage());
- }
+ assertCorrupt("no tree header", OBJ_COMMIT, b);
}
@Test
public void testInvalidCommitNoTree2() {
- final StringBuilder b = new StringBuilder();
-
+ StringBuilder b = new StringBuilder();
b.append("trie ");
b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
b.append('\n');
-
- final byte[] data = Constants.encodeASCII(b.toString());
- try {
- checker.checkCommit(data);
- fail("Did not catch corrupt object");
- } catch (CorruptObjectException e) {
- assertEquals("no tree header", e.getMessage());
- }
+ assertCorrupt("no tree header", OBJ_COMMIT, b);
}
@Test
public void testInvalidCommitNoTree3() {
- final StringBuilder b = new StringBuilder();
-
+ StringBuilder b = new StringBuilder();
b.append("tree");
b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
b.append('\n');
-
- final byte[] data = Constants.encodeASCII(b.toString());
- try {
- checker.checkCommit(data);
- fail("Did not catch corrupt object");
- } catch (CorruptObjectException e) {
- assertEquals("no tree header", e.getMessage());
- }
+ assertCorrupt("no tree header", OBJ_COMMIT, b);
}
@Test
public void testInvalidCommitNoTree4() {
- final StringBuilder b = new StringBuilder();
-
+ StringBuilder b = new StringBuilder();
b.append("tree\t");
b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
b.append('\n');
-
- final byte[] data = Constants.encodeASCII(b.toString());
- try {
- checker.checkCommit(data);
- fail("Did not catch corrupt object");
- } catch (CorruptObjectException e) {
- assertEquals("no tree header", e.getMessage());
- }
+ assertCorrupt("no tree header", OBJ_COMMIT, b);
}
@Test
public void testInvalidCommitInvalidTree1() {
- final StringBuilder b = new StringBuilder();
-
+ StringBuilder b = new StringBuilder();
b.append("tree ");
b.append("zzzzfa841874ccc9f2ef7c48d0c76226f89b7189");
b.append('\n');
-
- final byte[] data = Constants.encodeASCII(b.toString());
- try {
- checker.checkCommit(data);
- fail("Did not catch corrupt object");
- } catch (CorruptObjectException e) {
- assertEquals("invalid tree", e.getMessage());
- }
+ assertCorrupt("invalid tree", OBJ_COMMIT, b);
}
@Test
public void testInvalidCommitInvalidTree2() {
- final StringBuilder b = new StringBuilder();
-
+ StringBuilder b = new StringBuilder();
b.append("tree ");
b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
b.append("z\n");
-
- final byte[] data = Constants.encodeASCII(b.toString());
- try {
- checker.checkCommit(data);
- fail("Did not catch corrupt object");
- } catch (CorruptObjectException e) {
- assertEquals("invalid tree", e.getMessage());
- }
+ assertCorrupt("invalid tree", OBJ_COMMIT, b);
}
@Test
public void testInvalidCommitInvalidTree3() {
- final StringBuilder b = new StringBuilder();
-
+ StringBuilder b = new StringBuilder();
b.append("tree ");
b.append("be9b");
b.append("\n");
- final byte[] data = Constants.encodeASCII(b.toString());
- try {
- checker.checkCommit(data);
- fail("Did not catch corrupt object");
- } catch (CorruptObjectException e) {
- assertEquals("invalid tree", e.getMessage());
- }
+ byte[] data = encodeASCII(b.toString());
+ assertCorrupt("invalid tree", OBJ_COMMIT, data);
}
@Test
public void testInvalidCommitInvalidTree4() {
- final StringBuilder b = new StringBuilder();
-
+ StringBuilder b = new StringBuilder();
b.append("tree ");
b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
b.append('\n');
-
- final byte[] data = Constants.encodeASCII(b.toString());
- try {
- checker.checkCommit(data);
- fail("Did not catch corrupt object");
- } catch (CorruptObjectException e) {
- assertEquals("invalid tree", e.getMessage());
- }
+ assertCorrupt("invalid tree", OBJ_COMMIT, b);
}
@Test
public void testInvalidCommitInvalidParent1() {
- final StringBuilder b = new StringBuilder();
-
+ StringBuilder b = new StringBuilder();
b.append("tree ");
b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
b.append('\n');
-
b.append("parent ");
b.append("\n");
-
- final byte[] data = Constants.encodeASCII(b.toString());
- try {
- checker.checkCommit(data);
- fail("Did not catch corrupt object");
- } catch (CorruptObjectException e) {
- assertEquals("invalid parent", e.getMessage());
- }
+ assertCorrupt("invalid parent", OBJ_COMMIT, b);
}
@Test
public void testInvalidCommitInvalidParent2() {
- final StringBuilder b = new StringBuilder();
-
+ StringBuilder b = new StringBuilder();
b.append("tree ");
b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
b.append('\n');
-
b.append("parent ");
b.append("zzzzfa841874ccc9f2ef7c48d0c76226f89b7189");
b.append("\n");
-
- final byte[] data = Constants.encodeASCII(b.toString());
- try {
- checker.checkCommit(data);
- fail("Did not catch corrupt object");
- } catch (CorruptObjectException e) {
- assertEquals("invalid parent", e.getMessage());
- }
+ assertCorrupt("invalid parent", OBJ_COMMIT, b);
}
@Test
public void testInvalidCommitInvalidParent3() {
- final StringBuilder b = new StringBuilder();
-
+ StringBuilder b = new StringBuilder();
b.append("tree ");
b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
b.append('\n');
-
b.append("parent ");
b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
b.append("\n");
-
- final byte[] data = Constants.encodeASCII(b.toString());
- try {
- checker.checkCommit(data);
- fail("Did not catch corrupt object");
- } catch (CorruptObjectException e) {
- assertEquals("invalid parent", e.getMessage());
- }
+ assertCorrupt("invalid parent", OBJ_COMMIT, b);
}
@Test
public void testInvalidCommitInvalidParent4() {
- final StringBuilder b = new StringBuilder();
-
+ StringBuilder b = new StringBuilder();
b.append("tree ");
b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
b.append('\n');
-
b.append("parent ");
b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
b.append("z\n");
-
- final byte[] data = Constants.encodeASCII(b.toString());
- try {
- checker.checkCommit(data);
- fail("Did not catch corrupt object");
- } catch (CorruptObjectException e) {
- assertEquals("invalid parent", e.getMessage());
- }
+ assertCorrupt("invalid parent", OBJ_COMMIT, b);
}
@Test
public void testInvalidCommitInvalidParent5() {
- final StringBuilder b = new StringBuilder();
-
+ StringBuilder b = new StringBuilder();
b.append("tree ");
b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
b.append('\n');
-
b.append("parent\t");
b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
b.append("\n");
- final byte[] data = Constants.encodeASCII(b.toString());
- try {
- checker.checkCommit(data);
- fail("Did not catch corrupt object");
- } catch (CorruptObjectException e) {
- // Yes, really, we complain about author not being
- // found as the invalid parent line wasn't consumed.
- assertEquals("no author", e.getMessage());
- }
+ byte[] data = encodeASCII(b.toString());
+ // Yes, really, we complain about author not being
+ // found as the invalid parent line wasn't consumed.
+ assertCorrupt("no author", OBJ_COMMIT, data);
}
@Test
- public void testInvalidCommitNoAuthor() {
- final StringBuilder b = new StringBuilder();
-
+ public void testInvalidCommitNoAuthor() throws CorruptObjectException {
+ StringBuilder b = new StringBuilder();
b.append("tree ");
b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
b.append('\n');
-
b.append("committer A. U. Thor <author@localhost> 1 +0000\n");
- final byte[] data = Constants.encodeASCII(b.toString());
- try {
- checker.checkCommit(data);
- fail("Did not catch corrupt object");
- } catch (CorruptObjectException e) {
- // Yes, really, we complain about author not being
- // found as the invalid parent line wasn't consumed.
- assertEquals("no author", e.getMessage());
- }
+ byte[] data = encodeASCII(b.toString());
+ assertCorrupt("no author", OBJ_COMMIT, data);
+ assertSkipListAccepts(OBJ_COMMIT, data);
}
@Test
- public void testInvalidCommitNoCommitter1() {
- final StringBuilder b = new StringBuilder();
-
+ public void testInvalidCommitNoCommitter1() throws CorruptObjectException {
+ StringBuilder b = new StringBuilder();
b.append("tree ");
b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
b.append('\n');
-
b.append("author A. U. Thor <author@localhost> 1 +0000\n");
- final byte[] data = Constants.encodeASCII(b.toString());
- try {
- checker.checkCommit(data);
- fail("Did not catch corrupt object");
- } catch (CorruptObjectException e) {
- // Yes, really, we complain about author not being
- // found as the invalid parent line wasn't consumed.
- assertEquals("no committer", e.getMessage());
- }
+ byte[] data = encodeASCII(b.toString());
+ assertCorrupt("no committer", OBJ_COMMIT, data);
+ assertSkipListAccepts(OBJ_COMMIT, data);
}
@Test
- public void testInvalidCommitNoCommitter2() {
- final StringBuilder b = new StringBuilder();
-
+ public void testInvalidCommitNoCommitter2() throws CorruptObjectException {
+ StringBuilder b = new StringBuilder();
b.append("tree ");
b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
b.append('\n');
-
b.append("author A. U. Thor <author@localhost> 1 +0000\n");
b.append("\n");
- final byte[] data = Constants.encodeASCII(b.toString());
- try {
- checker.checkCommit(data);
- fail("Did not catch corrupt object");
- } catch (CorruptObjectException e) {
- // Yes, really, we complain about author not being
- // found as the invalid parent line wasn't consumed.
- assertEquals("no committer", e.getMessage());
- }
+ byte[] data = encodeASCII(b.toString());
+ assertCorrupt("no committer", OBJ_COMMIT, data);
+ assertSkipListAccepts(OBJ_COMMIT, data);
}
@Test
- public void testInvalidCommitInvalidAuthor1() {
- final StringBuilder b = new StringBuilder();
-
+ public void testInvalidCommitInvalidAuthor1()
+ throws CorruptObjectException {
+ StringBuilder b = new StringBuilder();
b.append("tree ");
b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
b.append('\n');
-
b.append("author A. U. Thor <foo 1 +0000\n");
- final byte[] data = Constants.encodeASCII(b.toString());
- try {
- checker.checkCommit(data);
- fail("Did not catch corrupt object");
- } catch (CorruptObjectException e) {
- // Yes, really, we complain about author not being
- // found as the invalid parent line wasn't consumed.
- assertEquals("invalid author", e.getMessage());
- }
+ byte[] data = encodeASCII(b.toString());
+ assertCorrupt("bad email", OBJ_COMMIT, data);
+ assertSkipListAccepts(OBJ_COMMIT, data);
}
@Test
- public void testInvalidCommitInvalidAuthor2() {
- final StringBuilder b = new StringBuilder();
-
+ public void testInvalidCommitInvalidAuthor2()
+ throws CorruptObjectException {
+ StringBuilder b = new StringBuilder();
b.append("tree ");
b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
b.append('\n');
-
b.append("author A. U. Thor foo> 1 +0000\n");
- final byte[] data = Constants.encodeASCII(b.toString());
- try {
- checker.checkCommit(data);
- fail("Did not catch corrupt object");
- } catch (CorruptObjectException e) {
- // Yes, really, we complain about author not being
- // found as the invalid parent line wasn't consumed.
- assertEquals("invalid author", e.getMessage());
- }
+ byte[] data = encodeASCII(b.toString());
+ assertCorrupt("missing email", OBJ_COMMIT, data);
+ assertSkipListAccepts(OBJ_COMMIT, data);
}
@Test
- public void testInvalidCommitInvalidAuthor3() {
- final StringBuilder b = new StringBuilder();
-
+ public void testInvalidCommitInvalidAuthor3()
+ throws CorruptObjectException {
+ StringBuilder b = new StringBuilder();
b.append("tree ");
b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
b.append('\n');
-
b.append("author 1 +0000\n");
- final byte[] data = Constants.encodeASCII(b.toString());
- try {
- checker.checkCommit(data);
- fail("Did not catch corrupt object");
- } catch (CorruptObjectException e) {
- // Yes, really, we complain about author not being
- // found as the invalid parent line wasn't consumed.
- assertEquals("invalid author", e.getMessage());
- }
+ byte[] data = encodeASCII(b.toString());
+ assertCorrupt("missing email", OBJ_COMMIT, data);
+ assertSkipListAccepts(OBJ_COMMIT, data);
}
@Test
- public void testInvalidCommitInvalidAuthor4() {
- final StringBuilder b = new StringBuilder();
-
+ public void testInvalidCommitInvalidAuthor4()
+ throws CorruptObjectException {
+ StringBuilder b = new StringBuilder();
b.append("tree ");
b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
b.append('\n');
-
b.append("author a <b> +0000\n");
- final byte[] data = Constants.encodeASCII(b.toString());
- try {
- checker.checkCommit(data);
- fail("Did not catch corrupt object");
- } catch (CorruptObjectException e) {
- // Yes, really, we complain about author not being
- // found as the invalid parent line wasn't consumed.
- assertEquals("invalid author", e.getMessage());
- }
+ byte[] data = encodeASCII(b.toString());
+ assertCorrupt("bad date", OBJ_COMMIT, data);
+ assertSkipListAccepts(OBJ_COMMIT, data);
}
@Test
- public void testInvalidCommitInvalidAuthor5() {
- final StringBuilder b = new StringBuilder();
-
+ public void testInvalidCommitInvalidAuthor5()
+ throws CorruptObjectException {
+ StringBuilder b = new StringBuilder();
b.append("tree ");
b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
b.append('\n');
-
b.append("author a <b>\n");
- final byte[] data = Constants.encodeASCII(b.toString());
- try {
- checker.checkCommit(data);
- fail("Did not catch corrupt object");
- } catch (CorruptObjectException e) {
- // Yes, really, we complain about author not being
- // found as the invalid parent line wasn't consumed.
- assertEquals("invalid author", e.getMessage());
- }
+ byte[] data = encodeASCII(b.toString());
+ assertCorrupt("bad date", OBJ_COMMIT, data);
+ assertSkipListAccepts(OBJ_COMMIT, data);
}
@Test
- public void testInvalidCommitInvalidAuthor6() {
- final StringBuilder b = new StringBuilder();
-
+ public void testInvalidCommitInvalidAuthor6()
+ throws CorruptObjectException {
+ StringBuilder b = new StringBuilder();
b.append("tree ");
b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
b.append('\n');
-
b.append("author a <b> z");
- final byte[] data = Constants.encodeASCII(b.toString());
- try {
- checker.checkCommit(data);
- fail("Did not catch corrupt object");
- } catch (CorruptObjectException e) {
- // Yes, really, we complain about author not being
- // found as the invalid parent line wasn't consumed.
- assertEquals("invalid author", e.getMessage());
- }
+ byte[] data = encodeASCII(b.toString());
+ assertCorrupt("bad date", OBJ_COMMIT, data);
+ assertSkipListAccepts(OBJ_COMMIT, data);
}
@Test
- public void testInvalidCommitInvalidAuthor7() {
- final StringBuilder b = new StringBuilder();
-
+ public void testInvalidCommitInvalidAuthor7()
+ throws CorruptObjectException {
+ StringBuilder b = new StringBuilder();
b.append("tree ");
b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
b.append('\n');
-
b.append("author a <b> 1 z");
- final byte[] data = Constants.encodeASCII(b.toString());
- try {
- checker.checkCommit(data);
- fail("Did not catch corrupt object");
- } catch (CorruptObjectException e) {
- // Yes, really, we complain about author not being
- // found as the invalid parent line wasn't consumed.
- assertEquals("invalid author", e.getMessage());
- }
+ byte[] data = encodeASCII(b.toString());
+ assertCorrupt("bad time zone", OBJ_COMMIT, data);
+ assertSkipListAccepts(OBJ_COMMIT, data);
}
@Test
- public void testInvalidCommitInvalidCommitter() {
- final StringBuilder b = new StringBuilder();
-
+ public void testInvalidCommitInvalidCommitter()
+ throws CorruptObjectException {
+ StringBuilder b = new StringBuilder();
b.append("tree ");
b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
b.append('\n');
-
b.append("author a <b> 1 +0000\n");
b.append("committer a <");
- final byte[] data = Constants.encodeASCII(b.toString());
- try {
- checker.checkCommit(data);
- fail("Did not catch corrupt object");
- } catch (CorruptObjectException e) {
- // Yes, really, we complain about author not being
- // found as the invalid parent line wasn't consumed.
- assertEquals("invalid committer", e.getMessage());
- }
+ byte[] data = encodeASCII(b.toString());
+ assertCorrupt("bad email", OBJ_COMMIT, data);
+ assertSkipListAccepts(OBJ_COMMIT, data);
}
@Test
public void testValidTag() throws CorruptObjectException {
- final StringBuilder b = new StringBuilder();
-
+ StringBuilder b = new StringBuilder();
b.append("object ");
b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
b.append('\n');
-
b.append("type commit\n");
b.append("tag test-tag\n");
b.append("tagger A. U. Thor <author@localhost> 1 +0000\n");
- final byte[] data = Constants.encodeASCII(b.toString());
+ byte[] data = encodeASCII(b.toString());
checker.checkTag(data);
- checker.check(Constants.OBJ_TAG, data);
+ checker.check(OBJ_TAG, data);
}
@Test
public void testInvalidTagNoObject1() {
- final StringBuilder b = new StringBuilder();
-
- final byte[] data = Constants.encodeASCII(b.toString());
- try {
- checker.checkTag(data);
- fail("incorrectly accepted invalid tag");
- } catch (CorruptObjectException e) {
- assertEquals("no object header", e.getMessage());
- }
+ assertCorrupt("no object header", OBJ_TAG, new byte[0]);
}
@Test
public void testInvalidTagNoObject2() {
- final StringBuilder b = new StringBuilder();
-
+ StringBuilder b = new StringBuilder();
b.append("object\t");
b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
b.append('\n');
-
- final byte[] data = Constants.encodeASCII(b.toString());
- try {
- checker.checkTag(data);
- fail("incorrectly accepted invalid tag");
- } catch (CorruptObjectException e) {
- assertEquals("no object header", e.getMessage());
- }
+ assertCorrupt("no object header", OBJ_TAG, b);
}
@Test
public void testInvalidTagNoObject3() {
- final StringBuilder b = new StringBuilder();
-
+ StringBuilder b = new StringBuilder();
b.append("obejct ");
b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
b.append('\n');
-
- final byte[] data = Constants.encodeASCII(b.toString());
- try {
- checker.checkTag(data);
- fail("incorrectly accepted invalid tag");
- } catch (CorruptObjectException e) {
- assertEquals("no object header", e.getMessage());
- }
+ assertCorrupt("no object header", OBJ_TAG, b);
}
@Test
public void testInvalidTagNoObject4() {
- final StringBuilder b = new StringBuilder();
-
+ StringBuilder b = new StringBuilder();
b.append("object ");
b.append("zz9bfa841874ccc9f2ef7c48d0c76226f89b7189");
b.append('\n');
-
- final byte[] data = Constants.encodeASCII(b.toString());
- try {
- checker.checkTag(data);
- fail("incorrectly accepted invalid tag");
- } catch (CorruptObjectException e) {
- assertEquals("invalid object", e.getMessage());
- }
+ assertCorrupt("invalid object", OBJ_TAG, b);
}
@Test
public void testInvalidTagNoObject5() {
- final StringBuilder b = new StringBuilder();
-
+ StringBuilder b = new StringBuilder();
b.append("object ");
b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
b.append(" \n");
-
- final byte[] data = Constants.encodeASCII(b.toString());
- try {
- checker.checkTag(data);
- fail("incorrectly accepted invalid tag");
- } catch (CorruptObjectException e) {
- assertEquals("invalid object", e.getMessage());
- }
+ assertCorrupt("invalid object", OBJ_TAG, b);
}
@Test
public void testInvalidTagNoObject6() {
- final StringBuilder b = new StringBuilder();
-
+ StringBuilder b = new StringBuilder();
b.append("object ");
b.append("be9");
-
- final byte[] data = Constants.encodeASCII(b.toString());
- try {
- checker.checkTag(data);
- fail("incorrectly accepted invalid tag");
- } catch (CorruptObjectException e) {
- assertEquals("invalid object", e.getMessage());
- }
+ assertCorrupt("invalid object", OBJ_TAG, b);
}
@Test
public void testInvalidTagNoType1() {
- final StringBuilder b = new StringBuilder();
-
+ StringBuilder b = new StringBuilder();
b.append("object ");
b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
b.append('\n');
-
- final byte[] data = Constants.encodeASCII(b.toString());
- try {
- checker.checkTag(data);
- fail("incorrectly accepted invalid tag");
- } catch (CorruptObjectException e) {
- assertEquals("no type header", e.getMessage());
- }
+ assertCorrupt("no type header", OBJ_TAG, b);
}
@Test
public void testInvalidTagNoType2() {
- final StringBuilder b = new StringBuilder();
-
+ StringBuilder b = new StringBuilder();
b.append("object ");
b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
b.append('\n');
-
b.append("type\tcommit\n");
-
- final byte[] data = Constants.encodeASCII(b.toString());
- try {
- checker.checkTag(data);
- fail("incorrectly accepted invalid tag");
- } catch (CorruptObjectException e) {
- assertEquals("no type header", e.getMessage());
- }
+ assertCorrupt("no type header", OBJ_TAG, b);
}
@Test
public void testInvalidTagNoType3() {
- final StringBuilder b = new StringBuilder();
-
+ StringBuilder b = new StringBuilder();
b.append("object ");
b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
b.append('\n');
-
b.append("tpye commit\n");
-
- final byte[] data = Constants.encodeASCII(b.toString());
- try {
- checker.checkTag(data);
- fail("incorrectly accepted invalid tag");
- } catch (CorruptObjectException e) {
- assertEquals("no type header", e.getMessage());
- }
+ assertCorrupt("no type header", OBJ_TAG, b);
}
@Test
public void testInvalidTagNoType4() {
- final StringBuilder b = new StringBuilder();
-
+ StringBuilder b = new StringBuilder();
b.append("object ");
b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
b.append('\n');
-
b.append("type commit");
-
- final byte[] data = Constants.encodeASCII(b.toString());
- try {
- checker.checkTag(data);
- fail("incorrectly accepted invalid tag");
- } catch (CorruptObjectException e) {
- assertEquals("no tag header", e.getMessage());
- }
+ assertCorrupt("no tag header", OBJ_TAG, b);
}
@Test
public void testInvalidTagNoTagHeader1() {
- final StringBuilder b = new StringBuilder();
-
+ StringBuilder b = new StringBuilder();
b.append("object ");
b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
b.append('\n');
-
b.append("type commit\n");
-
- final byte[] data = Constants.encodeASCII(b.toString());
- try {
- checker.checkTag(data);
- fail("incorrectly accepted invalid tag");
- } catch (CorruptObjectException e) {
- assertEquals("no tag header", e.getMessage());
- }
+ assertCorrupt("no tag header", OBJ_TAG, b);
}
@Test
public void testInvalidTagNoTagHeader2() {
- final StringBuilder b = new StringBuilder();
-
+ StringBuilder b = new StringBuilder();
b.append("object ");
b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
b.append('\n');
-
b.append("type commit\n");
b.append("tag\tfoo\n");
-
- final byte[] data = Constants.encodeASCII(b.toString());
- try {
- checker.checkTag(data);
- fail("incorrectly accepted invalid tag");
- } catch (CorruptObjectException e) {
- assertEquals("no tag header", e.getMessage());
- }
+ assertCorrupt("no tag header", OBJ_TAG, b);
}
@Test
public void testInvalidTagNoTagHeader3() {
- final StringBuilder b = new StringBuilder();
-
+ StringBuilder b = new StringBuilder();
b.append("object ");
b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
b.append('\n');
-
b.append("type commit\n");
b.append("tga foo\n");
-
- final byte[] data = Constants.encodeASCII(b.toString());
- try {
- checker.checkTag(data);
- fail("incorrectly accepted invalid tag");
- } catch (CorruptObjectException e) {
- assertEquals("no tag header", e.getMessage());
- }
+ assertCorrupt("no tag header", OBJ_TAG, b);
}
@Test
public void testValidTagHasNoTaggerHeader() throws CorruptObjectException {
- final StringBuilder b = new StringBuilder();
-
+ StringBuilder b = new StringBuilder();
b.append("object ");
b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
b.append('\n');
-
b.append("type commit\n");
b.append("tag foo\n");
-
- checker.checkTag(Constants.encodeASCII(b.toString()));
+ checker.checkTag(encodeASCII(b.toString()));
}
@Test
public void testInvalidTagInvalidTaggerHeader1()
throws CorruptObjectException {
- final StringBuilder b = new StringBuilder();
-
+ StringBuilder b = new StringBuilder();
b.append("object ");
b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
b.append('\n');
-
b.append("type commit\n");
b.append("tag foo\n");
b.append("tagger \n");
- final byte[] data = Constants.encodeASCII(b.toString());
- try {
- checker.checkTag(data);
- fail("incorrectly accepted invalid tag");
- } catch (CorruptObjectException e) {
- assertEquals("invalid tagger", e.getMessage());
- }
+ byte[] data = encodeASCII(b.toString());
+ assertCorrupt("missing email", OBJ_TAG, data);
checker.setAllowInvalidPersonIdent(true);
checker.checkTag(data);
+
+ checker.setAllowInvalidPersonIdent(false);
+ assertSkipListAccepts(OBJ_TAG, data);
}
@Test
- public void testInvalidTagInvalidTaggerHeader3() {
- final StringBuilder b = new StringBuilder();
-
+ public void testInvalidTagInvalidTaggerHeader3()
+ throws CorruptObjectException {
+ StringBuilder b = new StringBuilder();
b.append("object ");
b.append("be9bfa841874ccc9f2ef7c48d0c76226f89b7189");
b.append('\n');
-
b.append("type commit\n");
b.append("tag foo\n");
b.append("tagger a < 1 +000\n");
- final byte[] data = Constants.encodeASCII(b.toString());
- try {
- checker.checkTag(data);
- fail("incorrectly accepted invalid tag");
- } catch (CorruptObjectException e) {
- assertEquals("invalid tagger", e.getMessage());
- }
+ byte[] data = encodeASCII(b.toString());
+ assertCorrupt("bad email", OBJ_TAG, data);
+ assertSkipListAccepts(OBJ_TAG, data);
}
@Test
public void testValidEmptyTree() throws CorruptObjectException {
checker.checkTree(new byte[0]);
- checker.check(Constants.OBJ_TREE, new byte[0]);
+ checker.check(OBJ_TREE, new byte[0]);
}
@Test
public void testValidTree1() throws CorruptObjectException {
- final StringBuilder b = new StringBuilder();
+ StringBuilder b = new StringBuilder();
entry(b, "100644 regular-file");
- final byte[] data = Constants.encodeASCII(b.toString());
- checker.checkTree(data);
+ checker.checkTree(encodeASCII(b.toString()));
}
@Test
public void testValidTree2() throws CorruptObjectException {
- final StringBuilder b = new StringBuilder();
+ StringBuilder b = new StringBuilder();
entry(b, "100755 executable");
- final byte[] data = Constants.encodeASCII(b.toString());
- checker.checkTree(data);
+ checker.checkTree(encodeASCII(b.toString()));
}
@Test
public void testValidTree3() throws CorruptObjectException {
- final StringBuilder b = new StringBuilder();
+ StringBuilder b = new StringBuilder();
entry(b, "40000 tree");
- final byte[] data = Constants.encodeASCII(b.toString());
- checker.checkTree(data);
+ checker.checkTree(encodeASCII(b.toString()));
}
@Test
public void testValidTree4() throws CorruptObjectException {
- final StringBuilder b = new StringBuilder();
+ StringBuilder b = new StringBuilder();
entry(b, "120000 symlink");
- final byte[] data = Constants.encodeASCII(b.toString());
- checker.checkTree(data);
+ checker.checkTree(encodeASCII(b.toString()));
}
@Test
public void testValidTree5() throws CorruptObjectException {
- final StringBuilder b = new StringBuilder();
+ StringBuilder b = new StringBuilder();
entry(b, "160000 git link");
- final byte[] data = Constants.encodeASCII(b.toString());
- checker.checkTree(data);
+ checker.checkTree(encodeASCII(b.toString()));
}
@Test
public void testValidTree6() throws CorruptObjectException {
- final StringBuilder b = new StringBuilder();
+ StringBuilder b = new StringBuilder();
entry(b, "100644 .a");
- final byte[] data = Constants.encodeASCII(b.toString());
+ checker.checkTree(encodeASCII(b.toString()));
+ }
+
+ @Test
+ public void testNullSha1InTreeEntry() throws CorruptObjectException {
+ byte[] data = concat(
+ encodeASCII("100644 A"), new byte[] { '\0' },
+ new byte[OBJECT_ID_LENGTH]);
+ assertCorrupt("entry points to null SHA-1", OBJ_TREE, data);
+ assertSkipListAccepts(OBJ_TREE, data);
+ checker.setIgnore(NULL_SHA1, true);
checker.checkTree(data);
}
@@ -1084,357 +788,326 @@ public class ObjectCheckerTest {
@Test
public void testValidTreeSorting1() throws CorruptObjectException {
- final StringBuilder b = new StringBuilder();
+ StringBuilder b = new StringBuilder();
entry(b, "100644 fooaaa");
entry(b, "100755 foobar");
- final byte[] data = Constants.encodeASCII(b.toString());
- checker.checkTree(data);
+ checker.checkTree(encodeASCII(b.toString()));
}
@Test
public void testValidTreeSorting2() throws CorruptObjectException {
- final StringBuilder b = new StringBuilder();
+ StringBuilder b = new StringBuilder();
entry(b, "100755 fooaaa");
entry(b, "100644 foobar");
- final byte[] data = Constants.encodeASCII(b.toString());
- checker.checkTree(data);
+ checker.checkTree(encodeASCII(b.toString()));
}
@Test
public void testValidTreeSorting3() throws CorruptObjectException {
- final StringBuilder b = new StringBuilder();
+ StringBuilder b = new StringBuilder();
entry(b, "40000 a");
entry(b, "100644 b");
- final byte[] data = Constants.encodeASCII(b.toString());
- checker.checkTree(data);
+ checker.checkTree(encodeASCII(b.toString()));
}
@Test
public void testValidTreeSorting4() throws CorruptObjectException {
- final StringBuilder b = new StringBuilder();
+ StringBuilder b = new StringBuilder();
entry(b, "100644 a");
entry(b, "40000 b");
- final byte[] data = Constants.encodeASCII(b.toString());
- checker.checkTree(data);
+ checker.checkTree(encodeASCII(b.toString()));
}
@Test
public void testValidTreeSorting5() throws CorruptObjectException {
- final StringBuilder b = new StringBuilder();
+ StringBuilder b = new StringBuilder();
entry(b, "100644 a.c");
entry(b, "40000 a");
entry(b, "100644 a0c");
- final byte[] data = Constants.encodeASCII(b.toString());
- checker.checkTree(data);
+ checker.checkTree(encodeASCII(b.toString()));
}
@Test
public void testValidTreeSorting6() throws CorruptObjectException {
- final StringBuilder b = new StringBuilder();
+ StringBuilder b = new StringBuilder();
entry(b, "40000 a");
entry(b, "100644 apple");
- final byte[] data = Constants.encodeASCII(b.toString());
- checker.checkTree(data);
+ checker.checkTree(encodeASCII(b.toString()));
}
@Test
public void testValidTreeSorting7() throws CorruptObjectException {
- final StringBuilder b = new StringBuilder();
+ StringBuilder b = new StringBuilder();
entry(b, "40000 an orang");
entry(b, "40000 an orange");
- final byte[] data = Constants.encodeASCII(b.toString());
- checker.checkTree(data);
+ checker.checkTree(encodeASCII(b.toString()));
}
@Test
public void testValidTreeSorting8() throws CorruptObjectException {
- final StringBuilder b = new StringBuilder();
+ StringBuilder b = new StringBuilder();
entry(b, "100644 a");
entry(b, "100644 a0c");
entry(b, "100644 b");
- final byte[] data = Constants.encodeASCII(b.toString());
- checker.checkTree(data);
+ checker.checkTree(encodeASCII(b.toString()));
}
@Test
public void testAcceptTreeModeWithZero() throws CorruptObjectException {
StringBuilder b = new StringBuilder();
entry(b, "040000 a");
+ byte[] data = encodeASCII(b.toString());
checker.setAllowLeadingZeroFileMode(true);
- checker.checkTree(Constants.encodeASCII(b.toString()));
+ checker.checkTree(data);
+
+ checker.setAllowLeadingZeroFileMode(false);
+ assertSkipListAccepts(OBJ_TREE, data);
+
+ checker.setIgnore(ZERO_PADDED_FILEMODE, true);
+ checker.checkTree(data);
}
@Test
public void testInvalidTreeModeStartsWithZero1() {
- final StringBuilder b = new StringBuilder();
+ StringBuilder b = new StringBuilder();
entry(b, "0 a");
- final byte[] data = Constants.encodeASCII(b.toString());
- try {
- checker.checkTree(data);
- fail("incorrectly accepted an invalid tree");
- } catch (CorruptObjectException e) {
- assertEquals("mode starts with '0'", e.getMessage());
- }
+ assertCorrupt("mode starts with '0'", OBJ_TREE, b);
}
@Test
public void testInvalidTreeModeStartsWithZero2() {
- final StringBuilder b = new StringBuilder();
+ StringBuilder b = new StringBuilder();
entry(b, "0100644 a");
- final byte[] data = Constants.encodeASCII(b.toString());
- try {
- checker.checkTree(data);
- fail("incorrectly accepted an invalid tree");
- } catch (CorruptObjectException e) {
- assertEquals("mode starts with '0'", e.getMessage());
- }
+ assertCorrupt("mode starts with '0'", OBJ_TREE, b);
}
@Test
public void testInvalidTreeModeStartsWithZero3() {
- final StringBuilder b = new StringBuilder();
+ StringBuilder b = new StringBuilder();
entry(b, "040000 a");
- final byte[] data = Constants.encodeASCII(b.toString());
- try {
- checker.checkTree(data);
- fail("incorrectly accepted an invalid tree");
- } catch (CorruptObjectException e) {
- assertEquals("mode starts with '0'", e.getMessage());
- }
+ assertCorrupt("mode starts with '0'", OBJ_TREE, b);
}
@Test
public void testInvalidTreeModeNotOctal1() {
- final StringBuilder b = new StringBuilder();
+ StringBuilder b = new StringBuilder();
entry(b, "8 a");
- final byte[] data = Constants.encodeASCII(b.toString());
- try {
- checker.checkTree(data);
- fail("incorrectly accepted an invalid tree");
- } catch (CorruptObjectException e) {
- assertEquals("invalid mode character", e.getMessage());
- }
+ assertCorrupt("invalid mode character", OBJ_TREE, b);
}
@Test
public void testInvalidTreeModeNotOctal2() {
- final StringBuilder b = new StringBuilder();
+ StringBuilder b = new StringBuilder();
entry(b, "Z a");
- final byte[] data = Constants.encodeASCII(b.toString());
- try {
- checker.checkTree(data);
- fail("incorrectly accepted an invalid tree");
- } catch (CorruptObjectException e) {
- assertEquals("invalid mode character", e.getMessage());
- }
+ byte[] data = encodeASCII(b.toString());
+ assertCorrupt("invalid mode character", OBJ_TREE, data);
+ assertSkipListRejects("invalid mode character", OBJ_TREE, data);
}
@Test
public void testInvalidTreeModeNotSupportedMode1() {
- final StringBuilder b = new StringBuilder();
+ StringBuilder b = new StringBuilder();
entry(b, "1 a");
- final byte[] data = Constants.encodeASCII(b.toString());
- try {
- checker.checkTree(data);
- fail("incorrectly accepted an invalid tree");
- } catch (CorruptObjectException e) {
- assertEquals("invalid mode 1", e.getMessage());
- }
+ byte[] data = encodeASCII(b.toString());
+ assertCorrupt("invalid mode 1", OBJ_TREE, data);
+ assertSkipListRejects("invalid mode 1", OBJ_TREE, data);
}
@Test
public void testInvalidTreeModeNotSupportedMode2() {
- final StringBuilder b = new StringBuilder();
+ StringBuilder b = new StringBuilder();
entry(b, "170000 a");
- final byte[] data = Constants.encodeASCII(b.toString());
- try {
- checker.checkTree(data);
- fail("incorrectly accepted an invalid tree");
- } catch (CorruptObjectException e) {
- assertEquals("invalid mode " + 0170000, e.getMessage());
- }
+ assertCorrupt("invalid mode " + 0170000, OBJ_TREE, b);
}
@Test
public void testInvalidTreeModeMissingName() {
- final StringBuilder b = new StringBuilder();
+ StringBuilder b = new StringBuilder();
b.append("100644");
- final byte[] data = Constants.encodeASCII(b.toString());
- try {
- checker.checkTree(data);
- fail("incorrectly accepted an invalid tree");
- } catch (CorruptObjectException e) {
- assertEquals("truncated in mode", e.getMessage());
- }
+ assertCorrupt("truncated in mode", OBJ_TREE, b);
}
@Test
- public void testInvalidTreeNameContainsSlash() {
- final StringBuilder b = new StringBuilder();
+ public void testInvalidTreeNameContainsSlash()
+ throws CorruptObjectException {
+ StringBuilder b = new StringBuilder();
entry(b, "100644 a/b");
- final byte[] data = Constants.encodeASCII(b.toString());
- try {
- checker.checkTree(data);
- fail("incorrectly accepted an invalid tree");
- } catch (CorruptObjectException e) {
- assertEquals("name contains '/'", e.getMessage());
- }
+ byte[] data = encodeASCII(b.toString());
+ assertCorrupt("name contains '/'", OBJ_TREE, data);
+ assertSkipListAccepts(OBJ_TREE, data);
+ checker.setIgnore(FULL_PATHNAME, true);
+ checker.checkTree(data);
}
@Test
- public void testInvalidTreeNameIsEmpty() {
- final StringBuilder b = new StringBuilder();
+ public void testInvalidTreeNameIsEmpty() throws CorruptObjectException {
+ StringBuilder b = new StringBuilder();
entry(b, "100644 ");
- final byte[] data = Constants.encodeASCII(b.toString());
- try {
- checker.checkTree(data);
- fail("incorrectly accepted an invalid tree");
- } catch (CorruptObjectException e) {
- assertEquals("zero length name", e.getMessage());
- }
+ byte[] data = encodeASCII(b.toString());
+ assertCorrupt("zero length name", OBJ_TREE, data);
+ assertSkipListAccepts(OBJ_TREE, data);
+ checker.setIgnore(EMPTY_NAME, true);
+ checker.checkTree(data);
}
@Test
- public void testInvalidTreeNameIsDot() {
- final StringBuilder b = new StringBuilder();
+ public void testInvalidTreeNameIsDot() throws CorruptObjectException {
+ StringBuilder b = new StringBuilder();
entry(b, "100644 .");
- final byte[] data = Constants.encodeASCII(b.toString());
- try {
- checker.checkTree(data);
- fail("incorrectly accepted an invalid tree");
- } catch (CorruptObjectException e) {
- assertEquals("invalid name '.'", e.getMessage());
- }
+ byte[] data = encodeASCII(b.toString());
+ assertCorrupt("invalid name '.'", OBJ_TREE, data);
+ assertSkipListAccepts(OBJ_TREE, data);
+ checker.setIgnore(HAS_DOT, true);
+ checker.checkTree(data);
}
@Test
- public void testInvalidTreeNameIsDotDot() {
- final StringBuilder b = new StringBuilder();
+ public void testInvalidTreeNameIsDotDot() throws CorruptObjectException {
+ StringBuilder b = new StringBuilder();
entry(b, "100644 ..");
- final byte[] data = Constants.encodeASCII(b.toString());
- try {
- checker.checkTree(data);
- fail("incorrectly accepted an invalid tree");
- } catch (CorruptObjectException e) {
- assertEquals("invalid name '..'", e.getMessage());
- }
+ byte[] data = encodeASCII(b.toString());
+ assertCorrupt("invalid name '..'", OBJ_TREE, data);
+ assertSkipListAccepts(OBJ_TREE, data);
+ checker.setIgnore(HAS_DOTDOT, true);
+ checker.checkTree(data);
}
@Test
- public void testInvalidTreeNameIsGit() {
+ public void testInvalidTreeNameIsGit() throws CorruptObjectException {
StringBuilder b = new StringBuilder();
entry(b, "100644 .git");
- byte[] data = Constants.encodeASCII(b.toString());
- try {
- checker.checkTree(data);
- fail("incorrectly accepted an invalid tree");
- } catch (CorruptObjectException e) {
- assertEquals("invalid name '.git'", e.getMessage());
- }
+ byte[] data = encodeASCII(b.toString());
+ assertCorrupt("invalid name '.git'", OBJ_TREE, data);
+ assertSkipListAccepts(OBJ_TREE, data);
+ checker.setIgnore(HAS_DOTGIT, true);
+ checker.checkTree(data);
}
@Test
- public void testInvalidTreeNameIsMixedCaseGit() {
+ public void testInvalidTreeNameIsMixedCaseGit()
+ throws CorruptObjectException {
StringBuilder b = new StringBuilder();
entry(b, "100644 .GiT");
- byte[] data = Constants.encodeASCII(b.toString());
- try {
- checker.checkTree(data);
- fail("incorrectly accepted an invalid tree");
- } catch (CorruptObjectException e) {
- assertEquals("invalid name '.GiT'", e.getMessage());
- }
+ byte[] data = encodeASCII(b.toString());
+ assertCorrupt("invalid name '.GiT'", OBJ_TREE, data);
+ assertSkipListAccepts(OBJ_TREE, data);
+ checker.setIgnore(HAS_DOTGIT, true);
+ checker.checkTree(data);
}
@Test
- public void testInvalidTreeNameIsMacHFSGit() {
+ public void testInvalidTreeNameIsMacHFSGit() throws CorruptObjectException {
StringBuilder b = new StringBuilder();
entry(b, "100644 .gi\u200Ct");
- byte[] data = Constants.encode(b.toString());
- try {
- checker.setSafeForMacOS(true);
- checker.checkTree(data);
- fail("incorrectly accepted an invalid tree");
- } catch (CorruptObjectException e) {
- assertEquals(
- "invalid name '.gi\u200Ct' contains ignorable Unicode characters",
- e.getMessage());
- }
+ byte[] data = encode(b.toString());
+
+ // Fine on POSIX.
+ checker.checkTree(data);
+
+ // Rejected on Mac OS.
+ checker.setSafeForMacOS(true);
+ assertCorrupt(
+ "invalid name '.gi\u200Ct' contains ignorable Unicode characters",
+ OBJ_TREE, data);
+ assertSkipListAccepts(OBJ_TREE, data);
+ checker.setIgnore(HAS_DOTGIT, true);
+ checker.checkTree(data);
}
@Test
- public void testInvalidTreeNameIsMacHFSGit2() {
+ public void testInvalidTreeNameIsMacHFSGit2()
+ throws CorruptObjectException {
StringBuilder b = new StringBuilder();
entry(b, "100644 \u206B.git");
- byte[] data = Constants.encode(b.toString());
- try {
- checker.setSafeForMacOS(true);
- checker.checkTree(data);
- fail("incorrectly accepted an invalid tree");
- } catch (CorruptObjectException e) {
- assertEquals(
- "invalid name '\u206B.git' contains ignorable Unicode characters",
- e.getMessage());
- }
+ byte[] data = encode(b.toString());
+
+ // Fine on POSIX.
+ checker.checkTree(data);
+
+ // Rejected on Mac OS.
+ checker.setSafeForMacOS(true);
+ assertCorrupt(
+ "invalid name '\u206B.git' contains ignorable Unicode characters",
+ OBJ_TREE, data);
+ assertSkipListAccepts(OBJ_TREE, data);
+ checker.setIgnore(HAS_DOTGIT, true);
+ checker.checkTree(data);
}
@Test
- public void testInvalidTreeNameIsMacHFSGit3() {
+ public void testInvalidTreeNameIsMacHFSGit3()
+ throws CorruptObjectException {
StringBuilder b = new StringBuilder();
entry(b, "100644 .git\uFEFF");
- byte[] data = Constants.encode(b.toString());
- try {
- checker.setSafeForMacOS(true);
- checker.checkTree(data);
- fail("incorrectly accepted an invalid tree");
- } catch (CorruptObjectException e) {
- assertEquals(
- "invalid name '.git\uFEFF' contains ignorable Unicode characters",
- e.getMessage());
- }
+ byte[] data = encode(b.toString());
+
+ // Fine on POSIX.
+ checker.checkTree(data);
+
+ // Rejected on Mac OS.
+ checker.setSafeForMacOS(true);
+ assertCorrupt(
+ "invalid name '.git\uFEFF' contains ignorable Unicode characters",
+ OBJ_TREE, data);
+ assertSkipListAccepts(OBJ_TREE, data);
+ checker.setIgnore(HAS_DOTGIT, true);
+ checker.checkTree(data);
}
- private static byte[] concat(byte[] b1, byte[] b2) {
- byte[] data = new byte[b1.length + b2.length];
- System.arraycopy(b1, 0, data, 0, b1.length);
- System.arraycopy(b2, 0, data, b1.length, b2.length);
+ private static byte[] concat(byte[]... b) {
+ int n = 0;
+ for (byte[] a : b) {
+ n += a.length;
+ }
+
+ byte[] data = new byte[n];
+ n = 0;
+ for (byte[] a : b) {
+ System.arraycopy(a, 0, data, n, a.length);
+ n += a.length;
+ }
return data;
}
@Test
- public void testInvalidTreeNameIsMacHFSGitCorruptUTF8AtEnd() {
- byte[] data = concat(Constants.encode("100644 .git"),
+ public void testInvalidTreeNameIsMacHFSGitCorruptUTF8AtEnd()
+ throws CorruptObjectException {
+ byte[] data = concat(encode("100644 .git"),
new byte[] { (byte) 0xef });
StringBuilder b = new StringBuilder();
entry(b, "");
- data = concat(data, Constants.encode(b.toString()));
- try {
- checker.setSafeForMacOS(true);
- checker.checkTree(data);
- fail("incorrectly accepted an invalid tree");
- } catch (CorruptObjectException e) {
- assertEquals(
- "invalid name contains byte sequence '0xef' which is not a valid UTF-8 character",
- e.getMessage());
- }
+ data = concat(data, encode(b.toString()));
+
+ // Fine on POSIX.
+ checker.checkTree(data);
+
+ // Rejected on Mac OS.
+ checker.setSafeForMacOS(true);
+ assertCorrupt(
+ "invalid name contains byte sequence '0xef' which is not a valid UTF-8 character",
+ OBJ_TREE, data);
+ assertSkipListAccepts(OBJ_TREE, data);
}
@Test
- public void testInvalidTreeNameIsMacHFSGitCorruptUTF8AtEnd2() {
- byte[] data = concat(Constants.encode("100644 .git"), new byte[] {
+ public void testInvalidTreeNameIsMacHFSGitCorruptUTF8AtEnd2()
+ throws CorruptObjectException {
+ byte[] data = concat(encode("100644 .git"),
+ new byte[] {
(byte) 0xe2, (byte) 0xab });
StringBuilder b = new StringBuilder();
entry(b, "");
- data = concat(data, Constants.encode(b.toString()));
- try {
- checker.setSafeForMacOS(true);
- checker.checkTree(data);
- fail("incorrectly accepted an invalid tree");
- } catch (CorruptObjectException e) {
- assertEquals(
- "invalid name contains byte sequence '0xe2ab' which is not a valid UTF-8 character",
- e.getMessage());
- }
+ data = concat(data, encode(b.toString()));
+
+ // Fine on POSIX.
+ checker.checkTree(data);
+
+ // Rejected on Mac OS.
+ checker.setSafeForMacOS(true);
+ assertCorrupt(
+ "invalid name contains byte sequence '0xe2ab' which is not a valid UTF-8 character",
+ OBJ_TREE, data);
+ assertSkipListAccepts(OBJ_TREE, data);
}
@Test
@@ -1442,7 +1115,7 @@ public class ObjectCheckerTest {
throws CorruptObjectException {
StringBuilder b = new StringBuilder();
entry(b, "100644 .git\u200Cx");
- byte[] data = Constants.encode(b.toString());
+ byte[] data = encode(b.toString());
checker.setSafeForMacOS(true);
checker.checkTree(data);
}
@@ -1452,7 +1125,7 @@ public class ObjectCheckerTest {
throws CorruptObjectException {
StringBuilder b = new StringBuilder();
entry(b, "100644 .kit\u200C");
- byte[] data = Constants.encode(b.toString());
+ byte[] data = encode(b.toString());
checker.setSafeForMacOS(true);
checker.checkTree(data);
}
@@ -1462,21 +1135,19 @@ public class ObjectCheckerTest {
throws CorruptObjectException {
StringBuilder b = new StringBuilder();
entry(b, "100644 .git\u200C");
- byte[] data = Constants.encode(b.toString());
+ byte[] data = encode(b.toString());
checker.checkTree(data);
}
@Test
- public void testInvalidTreeNameIsDotGitDot() {
+ public void testInvalidTreeNameIsDotGitDot() throws CorruptObjectException {
StringBuilder b = new StringBuilder();
entry(b, "100644 .git.");
- byte[] data = Constants.encodeASCII(b.toString());
- try {
- checker.checkTree(data);
- fail("incorrectly accepted an invalid tree");
- } catch (CorruptObjectException e) {
- assertEquals("invalid name '.git.'", e.getMessage());
- }
+ byte[] data = encodeASCII(b.toString());
+ assertCorrupt("invalid name '.git.'", OBJ_TREE, data);
+ assertSkipListAccepts(OBJ_TREE, data);
+ checker.setIgnore(HAS_DOTGIT, true);
+ checker.checkTree(data);
}
@Test
@@ -1484,20 +1155,19 @@ public class ObjectCheckerTest {
throws CorruptObjectException {
StringBuilder b = new StringBuilder();
entry(b, "100644 .git..");
- checker.checkTree(Constants.encodeASCII(b.toString()));
+ checker.checkTree(encodeASCII(b.toString()));
}
@Test
- public void testInvalidTreeNameIsDotGitSpace() {
+ public void testInvalidTreeNameIsDotGitSpace()
+ throws CorruptObjectException {
StringBuilder b = new StringBuilder();
entry(b, "100644 .git ");
- byte[] data = Constants.encodeASCII(b.toString());
- try {
- checker.checkTree(data);
- fail("incorrectly accepted an invalid tree");
- } catch (CorruptObjectException e) {
- assertEquals("invalid name '.git '", e.getMessage());
- }
+ byte[] data = encodeASCII(b.toString());
+ assertCorrupt("invalid name '.git '", OBJ_TREE, data);
+ assertSkipListAccepts(OBJ_TREE, data);
+ checker.setIgnore(HAS_DOTGIT, true);
+ checker.checkTree(data);
}
@Test
@@ -1505,7 +1175,7 @@ public class ObjectCheckerTest {
throws CorruptObjectException {
StringBuilder b = new StringBuilder();
entry(b, "100644 .gitfoobar");
- byte[] data = Constants.encodeASCII(b.toString());
+ byte[] data = encodeASCII(b.toString());
checker.checkTree(data);
}
@@ -1514,7 +1184,7 @@ public class ObjectCheckerTest {
throws CorruptObjectException {
StringBuilder b = new StringBuilder();
entry(b, "100644 .gitfoo bar");
- byte[] data = Constants.encodeASCII(b.toString());
+ byte[] data = encodeASCII(b.toString());
checker.checkTree(data);
}
@@ -1523,7 +1193,7 @@ public class ObjectCheckerTest {
throws CorruptObjectException {
StringBuilder b = new StringBuilder();
entry(b, "100644 .gitfoobar.");
- byte[] data = Constants.encodeASCII(b.toString());
+ byte[] data = encodeASCII(b.toString());
checker.checkTree(data);
}
@@ -1532,251 +1202,236 @@ public class ObjectCheckerTest {
throws CorruptObjectException {
StringBuilder b = new StringBuilder();
entry(b, "100644 .gitfoobar..");
- byte[] data = Constants.encodeASCII(b.toString());
+ byte[] data = encodeASCII(b.toString());
checker.checkTree(data);
}
@Test
- public void testInvalidTreeNameIsDotGitDotSpace() {
+ public void testInvalidTreeNameIsDotGitDotSpace()
+ throws CorruptObjectException {
StringBuilder b = new StringBuilder();
entry(b, "100644 .git. ");
- byte[] data = Constants.encodeASCII(b.toString());
- try {
- checker.checkTree(data);
- fail("incorrectly accepted an invalid tree");
- } catch (CorruptObjectException e) {
- assertEquals("invalid name '.git. '", e.getMessage());
- }
+ byte[] data = encodeASCII(b.toString());
+ assertCorrupt("invalid name '.git. '", OBJ_TREE, data);
+ assertSkipListAccepts(OBJ_TREE, data);
+ checker.setIgnore(HAS_DOTGIT, true);
+ checker.checkTree(data);
}
@Test
- public void testInvalidTreeNameIsDotGitSpaceDot() {
+ public void testInvalidTreeNameIsDotGitSpaceDot()
+ throws CorruptObjectException {
StringBuilder b = new StringBuilder();
entry(b, "100644 .git . ");
- byte[] data = Constants.encodeASCII(b.toString());
- try {
- checker.checkTree(data);
- fail("incorrectly accepted an invalid tree");
- } catch (CorruptObjectException e) {
- assertEquals("invalid name '.git . '", e.getMessage());
- }
+ byte[] data = encodeASCII(b.toString());
+ assertCorrupt("invalid name '.git . '", OBJ_TREE, data);
+ assertSkipListAccepts(OBJ_TREE, data);
+ checker.setIgnore(HAS_DOTGIT, true);
+ checker.checkTree(data);
}
@Test
- public void testInvalidTreeNameIsGITTilde1() {
+ public void testInvalidTreeNameIsGITTilde1() throws CorruptObjectException {
StringBuilder b = new StringBuilder();
entry(b, "100644 GIT~1");
- byte[] data = Constants.encodeASCII(b.toString());
- try {
- checker.checkTree(data);
- fail("incorrectly accepted an invalid tree");
- } catch (CorruptObjectException e) {
- assertEquals("invalid name 'GIT~1'", e.getMessage());
- }
+ byte[] data = encodeASCII(b.toString());
+ assertCorrupt("invalid name 'GIT~1'", OBJ_TREE, data);
+ assertSkipListAccepts(OBJ_TREE, data);
+ checker.setIgnore(HAS_DOTGIT, true);
+ checker.checkTree(data);
}
@Test
- public void testInvalidTreeNameIsGiTTilde1() {
+ public void testInvalidTreeNameIsGiTTilde1() throws CorruptObjectException {
StringBuilder b = new StringBuilder();
entry(b, "100644 GiT~1");
- byte[] data = Constants.encodeASCII(b.toString());
- try {
- checker.checkTree(data);
- fail("incorrectly accepted an invalid tree");
- } catch (CorruptObjectException e) {
- assertEquals("invalid name 'GiT~1'", e.getMessage());
- }
+ byte[] data = encodeASCII(b.toString());
+ assertCorrupt("invalid name 'GiT~1'", OBJ_TREE, data);
+ assertSkipListAccepts(OBJ_TREE, data);
+ checker.setIgnore(HAS_DOTGIT, true);
+ checker.checkTree(data);
}
@Test
public void testValidTreeNameIsGitTilde11() throws CorruptObjectException {
StringBuilder b = new StringBuilder();
entry(b, "100644 GIT~11");
- byte[] data = Constants.encodeASCII(b.toString());
+ byte[] data = encodeASCII(b.toString());
checker.checkTree(data);
}
@Test
public void testInvalidTreeTruncatedInName() {
- final StringBuilder b = new StringBuilder();
+ StringBuilder b = new StringBuilder();
b.append("100644 b");
- final byte[] data = Constants.encodeASCII(b.toString());
- try {
- checker.checkTree(data);
- fail("incorrectly accepted an invalid tree");
- } catch (CorruptObjectException e) {
- assertEquals("truncated in name", e.getMessage());
- }
+ byte[] data = encodeASCII(b.toString());
+ assertCorrupt("truncated in name", OBJ_TREE, data);
+ assertSkipListRejects("truncated in name", OBJ_TREE, data);
}
@Test
public void testInvalidTreeTruncatedInObjectId() {
- final StringBuilder b = new StringBuilder();
+ StringBuilder b = new StringBuilder();
b.append("100644 b\0\1\2");
- final byte[] data = Constants.encodeASCII(b.toString());
- try {
- checker.checkTree(data);
- fail("incorrectly accepted an invalid tree");
- } catch (CorruptObjectException e) {
- assertEquals("truncated in object id", e.getMessage());
- }
+ byte[] data = encodeASCII(b.toString());
+ assertCorrupt("truncated in object id", OBJ_TREE, data);
+ assertSkipListRejects("truncated in object id", OBJ_TREE, data);
}
@Test
- public void testInvalidTreeBadSorting1() {
- final StringBuilder b = new StringBuilder();
+ public void testInvalidTreeBadSorting1() throws CorruptObjectException {
+ StringBuilder b = new StringBuilder();
entry(b, "100644 foobar");
entry(b, "100644 fooaaa");
- final byte[] data = Constants.encodeASCII(b.toString());
+ byte[] data = encodeASCII(b.toString());
+
+ assertCorrupt("incorrectly sorted", OBJ_TREE, data);
+
+ ObjectId id = idFor(OBJ_TREE, data);
try {
- checker.checkTree(data);
- fail("incorrectly accepted an invalid tree");
+ checker.check(id, OBJ_TREE, data);
+ fail("Did not throw CorruptObjectException");
} catch (CorruptObjectException e) {
- assertEquals("incorrectly sorted", e.getMessage());
+ assertSame(TREE_NOT_SORTED, e.getErrorType());
+ assertEquals("treeNotSorted: object " + id.name()
+ + ": incorrectly sorted", e.getMessage());
}
+
+ assertSkipListAccepts(OBJ_TREE, data);
+ checker.setIgnore(TREE_NOT_SORTED, true);
+ checker.checkTree(data);
}
@Test
- public void testInvalidTreeBadSorting2() {
- final StringBuilder b = new StringBuilder();
+ public void testInvalidTreeBadSorting2() throws CorruptObjectException {
+ StringBuilder b = new StringBuilder();
entry(b, "40000 a");
entry(b, "100644 a.c");
- final byte[] data = Constants.encodeASCII(b.toString());
- try {
- checker.checkTree(data);
- fail("incorrectly accepted an invalid tree");
- } catch (CorruptObjectException e) {
- assertEquals("incorrectly sorted", e.getMessage());
- }
+ byte[] data = encodeASCII(b.toString());
+ assertCorrupt("incorrectly sorted", OBJ_TREE, data);
+ assertSkipListAccepts(OBJ_TREE, data);
+ checker.setIgnore(TREE_NOT_SORTED, true);
+ checker.checkTree(data);
}
@Test
- public void testInvalidTreeBadSorting3() {
- final StringBuilder b = new StringBuilder();
+ public void testInvalidTreeBadSorting3() throws CorruptObjectException {
+ StringBuilder b = new StringBuilder();
entry(b, "100644 a0c");
entry(b, "40000 a");
- final byte[] data = Constants.encodeASCII(b.toString());
- try {
- checker.checkTree(data);
- fail("incorrectly accepted an invalid tree");
- } catch (CorruptObjectException e) {
- assertEquals("incorrectly sorted", e.getMessage());
- }
+ byte[] data = encodeASCII(b.toString());
+ assertCorrupt("incorrectly sorted", OBJ_TREE, data);
+ assertSkipListAccepts(OBJ_TREE, data);
+ checker.setIgnore(TREE_NOT_SORTED, true);
+ checker.checkTree(data);
}
@Test
- public void testInvalidTreeDuplicateNames1() {
- final StringBuilder b = new StringBuilder();
+ public void testInvalidTreeDuplicateNames1_File()
+ throws CorruptObjectException {
+ StringBuilder b = new StringBuilder();
entry(b, "100644 a");
entry(b, "100644 a");
- final byte[] data = Constants.encodeASCII(b.toString());
- try {
- checker.checkTree(data);
- fail("incorrectly accepted an invalid tree");
- } catch (CorruptObjectException e) {
- assertEquals("duplicate entry names", e.getMessage());
- }
+ byte[] data = encodeASCII(b.toString());
+ assertCorrupt("duplicate entry names", OBJ_TREE, data);
+ assertSkipListAccepts(OBJ_TREE, data);
+ checker.setIgnore(DUPLICATE_ENTRIES, true);
+ checker.checkTree(data);
+ }
+
+ @Test
+ public void testInvalidTreeDuplicateNames1_Tree()
+ throws CorruptObjectException {
+ StringBuilder b = new StringBuilder();
+ entry(b, "40000 a");
+ entry(b, "40000 a");
+ byte[] data = encodeASCII(b.toString());
+ assertCorrupt("duplicate entry names", OBJ_TREE, data);
+ assertSkipListAccepts(OBJ_TREE, data);
+ checker.setIgnore(DUPLICATE_ENTRIES, true);
+ checker.checkTree(data);
}
@Test
- public void testInvalidTreeDuplicateNames2() {
- final StringBuilder b = new StringBuilder();
+ public void testInvalidTreeDuplicateNames2() throws CorruptObjectException {
+ StringBuilder b = new StringBuilder();
entry(b, "100644 a");
entry(b, "100755 a");
- final byte[] data = Constants.encodeASCII(b.toString());
- try {
- checker.checkTree(data);
- fail("incorrectly accepted an invalid tree");
- } catch (CorruptObjectException e) {
- assertEquals("duplicate entry names", e.getMessage());
- }
+ byte[] data = encodeASCII(b.toString());
+ assertCorrupt("duplicate entry names", OBJ_TREE, data);
+ assertSkipListAccepts(OBJ_TREE, data);
+ checker.setIgnore(DUPLICATE_ENTRIES, true);
+ checker.checkTree(data);
}
@Test
- public void testInvalidTreeDuplicateNames3() {
- final StringBuilder b = new StringBuilder();
+ public void testInvalidTreeDuplicateNames3() throws CorruptObjectException {
+ StringBuilder b = new StringBuilder();
entry(b, "100644 a");
entry(b, "40000 a");
- final byte[] data = Constants.encodeASCII(b.toString());
- try {
- checker.checkTree(data);
- fail("incorrectly accepted an invalid tree");
- } catch (CorruptObjectException e) {
- assertEquals("duplicate entry names", e.getMessage());
- }
+ byte[] data = encodeASCII(b.toString());
+ assertCorrupt("duplicate entry names", OBJ_TREE, data);
+ assertSkipListAccepts(OBJ_TREE, data);
+ checker.setIgnore(DUPLICATE_ENTRIES, true);
+ checker.checkTree(data);
}
@Test
- public void testInvalidTreeDuplicateNames4() {
- final StringBuilder b = new StringBuilder();
+ public void testInvalidTreeDuplicateNames4() throws CorruptObjectException {
+ StringBuilder b = new StringBuilder();
entry(b, "100644 a");
entry(b, "100644 a.c");
entry(b, "100644 a.d");
entry(b, "100644 a.e");
entry(b, "40000 a");
entry(b, "100644 zoo");
- final byte[] data = Constants.encodeASCII(b.toString());
- try {
- checker.checkTree(data);
- fail("incorrectly accepted an invalid tree");
- } catch (CorruptObjectException e) {
- assertEquals("duplicate entry names", e.getMessage());
- }
+ byte[] data = encodeASCII(b.toString());
+ assertCorrupt("duplicate entry names", OBJ_TREE, data);
+ assertSkipListAccepts(OBJ_TREE, data);
+ checker.setIgnore(DUPLICATE_ENTRIES, true);
+ checker.checkTree(data);
}
@Test
public void testInvalidTreeDuplicateNames5()
- throws UnsupportedEncodingException {
+ throws UnsupportedEncodingException, CorruptObjectException {
StringBuilder b = new StringBuilder();
- entry(b, "100644 a");
entry(b, "100644 A");
+ entry(b, "100644 a");
byte[] data = b.toString().getBytes("UTF-8");
- try {
- checker.setSafeForWindows(true);
- checker.checkTree(data);
- fail("incorrectly accepted an invalid tree");
- } catch (CorruptObjectException e) {
- assertEquals("duplicate entry names", e.getMessage());
- }
+ checker.setSafeForWindows(true);
+ assertCorrupt("duplicate entry names", OBJ_TREE, data);
+ assertSkipListAccepts(OBJ_TREE, data);
+ checker.setIgnore(DUPLICATE_ENTRIES, true);
+ checker.checkTree(data);
}
@Test
public void testInvalidTreeDuplicateNames6()
- throws UnsupportedEncodingException {
+ throws UnsupportedEncodingException, CorruptObjectException {
StringBuilder b = new StringBuilder();
- entry(b, "100644 a");
entry(b, "100644 A");
+ entry(b, "100644 a");
byte[] data = b.toString().getBytes("UTF-8");
- try {
- checker.setSafeForMacOS(true);
- checker.checkTree(data);
- fail("incorrectly accepted an invalid tree");
- } catch (CorruptObjectException e) {
- assertEquals("duplicate entry names", e.getMessage());
- }
+ checker.setSafeForMacOS(true);
+ assertCorrupt("duplicate entry names", OBJ_TREE, data);
+ assertSkipListAccepts(OBJ_TREE, data);
+ checker.setIgnore(DUPLICATE_ENTRIES, true);
+ checker.checkTree(data);
}
@Test
public void testInvalidTreeDuplicateNames7()
- throws UnsupportedEncodingException {
- try {
- Class.forName("java.text.Normalizer");
- } catch (ClassNotFoundException e) {
- // Ignore this test on Java 5 platform.
- return;
- }
-
+ throws UnsupportedEncodingException, CorruptObjectException {
StringBuilder b = new StringBuilder();
entry(b, "100644 \u0065\u0301");
entry(b, "100644 \u00e9");
byte[] data = b.toString().getBytes("UTF-8");
- try {
- checker.setSafeForMacOS(true);
- checker.checkTree(data);
- fail("incorrectly accepted an invalid tree");
- } catch (CorruptObjectException e) {
- assertEquals("duplicate entry names", e.getMessage());
- }
+ checker.setSafeForMacOS(true);
+ assertCorrupt("duplicate entry names", OBJ_TREE, data);
+ assertSkipListAccepts(OBJ_TREE, data);
+ checker.setIgnore(DUPLICATE_ENTRIES, true);
+ checker.checkTree(data);
}
@Test
@@ -1791,7 +1446,7 @@ public class ObjectCheckerTest {
@Test
public void testRejectNulInPathSegment() {
try {
- checker.checkPathSegment(Constants.encodeASCII("a\u0000b"), 0, 3);
+ checker.checkPathSegment(encodeASCII("a\u0000b"), 0, 3);
fail("incorrectly accepted NUL in middle of name");
} catch (CorruptObjectException e) {
assertEquals("name contains byte 0x00", e.getMessage());
@@ -1893,13 +1548,65 @@ public class ObjectCheckerTest {
private void checkOneName(String name) throws CorruptObjectException {
StringBuilder b = new StringBuilder();
entry(b, "100644 " + name);
- checker.checkTree(Constants.encodeASCII(b.toString()));
+ checker.checkTree(encodeASCII(b.toString()));
}
- private static void entry(final StringBuilder b, final String modeName) {
+ private static void entry(StringBuilder b, final String modeName) {
b.append(modeName);
b.append('\0');
- for (int i = 0; i < Constants.OBJECT_ID_LENGTH; i++)
+ for (int i = 0; i < OBJECT_ID_LENGTH; i++)
b.append((char) i);
}
+
+ private void assertCorrupt(String msg, int type, StringBuilder b) {
+ assertCorrupt(msg, type, encodeASCII(b.toString()));
+ }
+
+ private void assertCorrupt(String msg, int type, byte[] data) {
+ try {
+ checker.check(type, data);
+ fail("Did not throw CorruptObjectException");
+ } catch (CorruptObjectException e) {
+ assertEquals(msg, e.getMessage());
+ }
+ }
+
+ private void assertSkipListAccepts(int type, byte[] data)
+ throws CorruptObjectException {
+ ObjectId id = idFor(type, data);
+ checker.setSkipList(set(id));
+ checker.check(id, type, data);
+ checker.setSkipList(null);
+ }
+
+ private void assertSkipListRejects(String msg, int type, byte[] data) {
+ ObjectId id = idFor(type, data);
+ checker.setSkipList(set(id));
+ try {
+ checker.check(id, type, data);
+ fail("Did not throw CorruptObjectException");
+ } catch (CorruptObjectException e) {
+ assertEquals(msg, e.getMessage());
+ }
+ checker.setSkipList(null);
+ }
+
+ private static ObjectIdSet set(final ObjectId... ids) {
+ return new ObjectIdSet() {
+ @Override
+ public boolean contains(AnyObjectId objectId) {
+ for (ObjectId id : ids) {
+ if (id.equals(objectId)) {
+ return true;
+ }
+ }
+ return false;
+ }
+ };
+ }
+
+ @SuppressWarnings("resource")
+ private static ObjectId idFor(int type, byte[] raw) {
+ return new ObjectInserter.Formatter().idFor(type, raw);
+ }
}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/T0002_TreeTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/T0002_TreeTest.java
deleted file mode 100644
index 651e62c9ca..0000000000
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/T0002_TreeTest.java
+++ /dev/null
@@ -1,319 +0,0 @@
-/*
- * Copyright (C) 2008, Robin Rosenberg <robin.rosenberg@dewire.com>
- * Copyright (C) 2006-2008, Shawn O. Pearce <spearce@spearce.org>
- * and other copyright owners as documented in the project's IP log.
- *
- * This program and the accompanying materials are made available
- * under the terms of the Eclipse Distribution License v1.0 which
- * accompanies this distribution, is reproduced below, and is
- * available at http://www.eclipse.org/org/documents/edl-v10.php
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- *
- * - Neither the name of the Eclipse Foundation, Inc. nor the
- * names of its contributors may be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package org.eclipse.jgit.lib;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertSame;
-import static org.junit.Assert.assertTrue;
-
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.eclipse.jgit.test.resources.SampleDataRepositoryTestCase;
-import org.junit.Test;
-
-@SuppressWarnings("deprecation")
-public class T0002_TreeTest extends SampleDataRepositoryTestCase {
- private static final ObjectId SOME_FAKE_ID = ObjectId.fromString(
- "0123456789abcdef0123456789abcdef01234567");
-
- private static int compareNamesUsingSpecialCompare(String a, String b)
- throws UnsupportedEncodingException {
- char lasta = '\0';
- byte[] abytes;
- if (a.length() > 0 && a.charAt(a.length()-1) == '/') {
- lasta = '/';
- a = a.substring(0, a.length() - 1);
- }
- abytes = a.getBytes("ISO-8859-1");
- char lastb = '\0';
- byte[] bbytes;
- if (b.length() > 0 && b.charAt(b.length()-1) == '/') {
- lastb = '/';
- b = b.substring(0, b.length() - 1);
- }
- bbytes = b.getBytes("ISO-8859-1");
- return Tree.compareNames(abytes, bbytes, lasta, lastb);
- }
-
- @Test
- public void test000_sort_01() throws UnsupportedEncodingException {
- assertEquals(0, compareNamesUsingSpecialCompare("a","a"));
- }
-
- @Test
- public void test000_sort_02() throws UnsupportedEncodingException {
- assertEquals(-1, compareNamesUsingSpecialCompare("a","b"));
- assertEquals(1, compareNamesUsingSpecialCompare("b","a"));
- }
-
- @Test
- public void test000_sort_03() throws UnsupportedEncodingException {
- assertEquals(1, compareNamesUsingSpecialCompare("a:","a"));
- assertEquals(1, compareNamesUsingSpecialCompare("a/","a"));
- assertEquals(-1, compareNamesUsingSpecialCompare("a","a/"));
- assertEquals(-1, compareNamesUsingSpecialCompare("a","a:"));
- assertEquals(1, compareNamesUsingSpecialCompare("a:","a/"));
- assertEquals(-1, compareNamesUsingSpecialCompare("a/","a:"));
- }
-
- @Test
- public void test000_sort_04() throws UnsupportedEncodingException {
- assertEquals(-1, compareNamesUsingSpecialCompare("a.a","a/a"));
- assertEquals(1, compareNamesUsingSpecialCompare("a/a","a.a"));
- }
-
- @Test
- public void test000_sort_05() throws UnsupportedEncodingException {
- assertEquals(-1, compareNamesUsingSpecialCompare("a.","a/"));
- assertEquals(1, compareNamesUsingSpecialCompare("a/","a."));
-
- }
-
- @Test
- public void test001_createEmpty() throws IOException {
- final Tree t = new Tree(db);
- assertTrue("isLoaded", t.isLoaded());
- assertTrue("isModified", t.isModified());
- assertTrue("no parent", t.getParent() == null);
- assertTrue("isRoot", t.isRoot());
- assertTrue("no name", t.getName() == null);
- assertTrue("no nameUTF8", t.getNameUTF8() == null);
- assertTrue("has entries array", t.members() != null);
- assertEquals("entries is empty", 0, t.members().length);
- assertEquals("full name is empty", "", t.getFullName());
- assertTrue("no id", t.getId() == null);
- assertTrue("database is r", t.getRepository() == db);
- assertTrue("no foo child", t.findTreeMember("foo") == null);
- assertTrue("no foo child", t.findBlobMember("foo") == null);
- }
-
- @Test
- public void test002_addFile() throws IOException {
- final Tree t = new Tree(db);
- t.setId(SOME_FAKE_ID);
- assertTrue("has id", t.getId() != null);
- assertFalse("not modified", t.isModified());
-
- final String n = "bob";
- final FileTreeEntry f = t.addFile(n);
- assertNotNull("have file", f);
- assertEquals("name matches", n, f.getName());
- assertEquals("name matches", f.getName(), new String(f.getNameUTF8(),
- "UTF-8"));
- assertEquals("full name matches", n, f.getFullName());
- assertTrue("no id", f.getId() == null);
- assertTrue("is modified", t.isModified());
- assertTrue("has no id", t.getId() == null);
- assertTrue("found bob", t.findBlobMember(f.getName()) == f);
-
- final TreeEntry[] i = t.members();
- assertNotNull("members array not null", i);
- assertTrue("iterator is not empty", i != null && i.length > 0);
- assertTrue("iterator returns file", i != null && i[0] == f);
- assertTrue("iterator is empty", i != null && i.length == 1);
- }
-
- @Test
- public void test004_addTree() throws IOException {
- final Tree t = new Tree(db);
- t.setId(SOME_FAKE_ID);
- assertTrue("has id", t.getId() != null);
- assertFalse("not modified", t.isModified());
-
- final String n = "bob";
- final Tree f = t.addTree(n);
- assertNotNull("have tree", f);
- assertEquals("name matches", n, f.getName());
- assertEquals("name matches", f.getName(), new String(f.getNameUTF8(),
- "UTF-8"));
- assertEquals("full name matches", n, f.getFullName());
- assertTrue("no id", f.getId() == null);
- assertTrue("parent matches", f.getParent() == t);
- assertTrue("repository matches", f.getRepository() == db);
- assertTrue("isLoaded", f.isLoaded());
- assertFalse("has items", f.members().length > 0);
- assertFalse("is root", f.isRoot());
- assertTrue("parent is modified", t.isModified());
- assertTrue("parent has no id", t.getId() == null);
- assertTrue("found bob child", t.findTreeMember(f.getName()) == f);
-
- final TreeEntry[] i = t.members();
- assertTrue("iterator is not empty", i.length > 0);
- assertTrue("iterator returns file", i[0] == f);
- assertEquals("iterator is empty", 1, i.length);
- }
-
- @Test
- public void test005_addRecursiveFile() throws IOException {
- final Tree t = new Tree(db);
- final FileTreeEntry f = t.addFile("a/b/c");
- assertNotNull("created f", f);
- assertEquals("c", f.getName());
- assertEquals("b", f.getParent().getName());
- assertEquals("a", f.getParent().getParent().getName());
- assertTrue("t is great-grandparent", t == f.getParent().getParent()
- .getParent());
- }
-
- @Test
- public void test005_addRecursiveTree() throws IOException {
- final Tree t = new Tree(db);
- final Tree f = t.addTree("a/b/c");
- assertNotNull("created f", f);
- assertEquals("c", f.getName());
- assertEquals("b", f.getParent().getName());
- assertEquals("a", f.getParent().getParent().getName());
- assertTrue("t is great-grandparent", t == f.getParent().getParent()
- .getParent());
- }
-
- @Test
- public void test006_addDeepTree() throws IOException {
- final Tree t = new Tree(db);
-
- final Tree e = t.addTree("e");
- assertNotNull("have e", e);
- assertTrue("e.parent == t", e.getParent() == t);
- final Tree f = t.addTree("f");
- assertNotNull("have f", f);
- assertTrue("f.parent == t", f.getParent() == t);
- final Tree g = f.addTree("g");
- assertNotNull("have g", g);
- assertTrue("g.parent == f", g.getParent() == f);
- final Tree h = g.addTree("h");
- assertNotNull("have h", h);
- assertTrue("h.parent = g", h.getParent() == g);
-
- h.setId(SOME_FAKE_ID);
- assertTrue("h not modified", !h.isModified());
- g.setId(SOME_FAKE_ID);
- assertTrue("g not modified", !g.isModified());
- f.setId(SOME_FAKE_ID);
- assertTrue("f not modified", !f.isModified());
- e.setId(SOME_FAKE_ID);
- assertTrue("e not modified", !e.isModified());
- t.setId(SOME_FAKE_ID);
- assertTrue("t not modified.", !t.isModified());
-
- assertEquals("full path of h ok", "f/g/h", h.getFullName());
- assertTrue("Can find h", t.findTreeMember(h.getFullName()) == h);
- assertTrue("Can't find f/z", t.findBlobMember("f/z") == null);
- assertTrue("Can't find y/z", t.findBlobMember("y/z") == null);
-
- final FileTreeEntry i = h.addFile("i");
- assertNotNull(i);
- assertEquals("full path of i ok", "f/g/h/i", i.getFullName());
- assertTrue("Can find i", t.findBlobMember(i.getFullName()) == i);
- assertTrue("h modified", h.isModified());
- assertTrue("g modified", g.isModified());
- assertTrue("f modified", f.isModified());
- assertTrue("e not modified", !e.isModified());
- assertTrue("t modified", t.isModified());
-
- assertTrue("h no id", h.getId() == null);
- assertTrue("g no id", g.getId() == null);
- assertTrue("f no id", f.getId() == null);
- assertTrue("e has id", e.getId() != null);
- assertTrue("t no id", t.getId() == null);
- }
-
- @Test
- public void test007_manyFileLookup() throws IOException {
- final Tree t = new Tree(db);
- final List<FileTreeEntry> files = new ArrayList<FileTreeEntry>(26 * 26);
- for (char level1 = 'a'; level1 <= 'z'; level1++) {
- for (char level2 = 'a'; level2 <= 'z'; level2++) {
- final String n = "." + level1 + level2 + "9";
- final FileTreeEntry f = t.addFile(n);
- assertNotNull("File " + n + " added.", f);
- assertEquals(n, f.getName());
- files.add(f);
- }
- }
- assertEquals(files.size(), t.memberCount());
- final TreeEntry[] ents = t.members();
- assertNotNull(ents);
- assertEquals(files.size(), ents.length);
- for (int k = 0; k < ents.length; k++) {
- assertTrue("File " + files.get(k).getName()
- + " is at " + k + ".", files.get(k) == ents[k]);
- }
- }
-
- @Test
- public void test008_SubtreeInternalSorting() throws IOException {
- final Tree t = new Tree(db);
- final FileTreeEntry e0 = t.addFile("a-b");
- final FileTreeEntry e1 = t.addFile("a-");
- final FileTreeEntry e2 = t.addFile("a=b");
- final Tree e3 = t.addTree("a");
- final FileTreeEntry e4 = t.addFile("a=");
-
- final TreeEntry[] ents = t.members();
- assertSame(e1, ents[0]);
- assertSame(e0, ents[1]);
- assertSame(e3, ents[2]);
- assertSame(e4, ents[3]);
- assertSame(e2, ents[4]);
- }
-
- @Test
- public void test009_SymlinkAndGitlink() throws IOException {
- final Tree symlinkTree = mapTree("symlink");
- assertTrue("Symlink entry exists", symlinkTree.existsBlob("symlink.txt"));
- final Tree gitlinkTree = mapTree("gitlink");
- assertTrue("Gitlink entry exists", gitlinkTree.existsBlob("submodule"));
- }
-
- private Tree mapTree(String name) throws IOException {
- ObjectId id = db.resolve(name + "^{tree}");
- return new Tree(db, id, db.open(id).getCachedBytes());
- }
-}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/ObjectWalkTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/ObjectWalkTest.java
index 2a59f58c66..9c9edc1476 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/ObjectWalkTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/ObjectWalkTest.java
@@ -47,11 +47,10 @@ import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
-import org.eclipse.jgit.lib.Constants;
-import org.eclipse.jgit.lib.FileTreeEntry;
+import org.eclipse.jgit.lib.FileMode;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectInserter;
-import org.eclipse.jgit.lib.Tree;
+import org.eclipse.jgit.lib.TreeFormatter;
import org.junit.Test;
@SuppressWarnings("deprecation")
@@ -220,28 +219,24 @@ public class ObjectWalkTest extends RevWalkTestCase {
.fromString("abbbfafe3129f85747aba7bfac992af77134c607");
final RevTree tree_root, tree_A, tree_AB;
final RevCommit b;
- {
- Tree root = new Tree(db);
- Tree A = root.addTree("A");
- FileTreeEntry B = root.addFile("B");
- B.setId(bId);
-
- Tree A_A = A.addTree("A");
- Tree A_B = A.addTree("B");
-
- try (final ObjectInserter inserter = db.newObjectInserter()) {
- A_A.setId(inserter.insert(Constants.OBJ_TREE, A_A.format()));
- A_B.setId(inserter.insert(Constants.OBJ_TREE, A_B.format()));
- A.setId(inserter.insert(Constants.OBJ_TREE, A.format()));
- root.setId(inserter.insert(Constants.OBJ_TREE, root.format()));
- inserter.flush();
- }
-
- tree_root = rw.parseTree(root.getId());
- tree_A = rw.parseTree(A.getId());
- tree_AB = rw.parseTree(A_A.getId());
- assertSame(tree_AB, rw.parseTree(A_B.getId()));
- b = commit(rw.parseTree(root.getId()));
+ try (ObjectInserter inserter = db.newObjectInserter()) {
+ ObjectId empty = inserter.insert(new TreeFormatter());
+
+ TreeFormatter A = new TreeFormatter();
+ A.append("A", FileMode.TREE, empty);
+ A.append("B", FileMode.TREE, empty);
+ ObjectId idA = inserter.insert(A);
+
+ TreeFormatter root = new TreeFormatter();
+ root.append("A", FileMode.TREE, idA);
+ root.append("B", FileMode.REGULAR_FILE, bId);
+ ObjectId idRoot = inserter.insert(root);
+ inserter.flush();
+
+ tree_root = objw.parseTree(idRoot);
+ tree_A = objw.parseTree(idA);
+ tree_AB = objw.parseTree(empty);
+ b = commit(tree_root);
}
markStart(b);
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevCommitParseTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevCommitParseTest.java
index beda2a7b97..885c1b5b2d 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevCommitParseTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevCommitParseTest.java
@@ -43,13 +43,18 @@
package org.eclipse.jgit.revwalk;
+import static java.nio.charset.StandardCharsets.UTF_8;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
import java.io.ByteArrayOutputStream;
import java.io.UnsupportedEncodingException;
+import java.nio.charset.IllegalCharsetNameException;
+import java.nio.charset.UnsupportedCharsetException;
import java.util.TimeZone;
import org.eclipse.jgit.junit.RepositoryTestCase;
@@ -304,6 +309,86 @@ public class RevCommitParseTest extends RepositoryTestCase {
}
@Test
+ public void testParse_incorrectUtf8Name() throws Exception {
+ ByteArrayOutputStream b = new ByteArrayOutputStream();
+ b.write("tree 9788669ad918b6fcce64af8882fc9a81cb6aba67\n"
+ .getBytes(UTF_8));
+ b.write("author au <a@example.com> 1218123387 +0700\n".getBytes(UTF_8));
+ b.write("committer co <c@example.com> 1218123390 -0500\n"
+ .getBytes(UTF_8));
+ b.write("encoding 'utf8'\n".getBytes(UTF_8));
+ b.write("\n".getBytes(UTF_8));
+ b.write("Sm\u00f6rg\u00e5sbord\n".getBytes(UTF_8));
+
+ RevCommit c = new RevCommit(
+ id("9473095c4cb2f12aefe1db8a355fe3fafba42f67"));
+ c.parseCanonical(new RevWalk(db), b.toByteArray());
+ assertEquals("'utf8'", c.getEncodingName());
+ assertEquals("Sm\u00f6rg\u00e5sbord\n", c.getFullMessage());
+
+ try {
+ c.getEncoding();
+ fail("Expected " + IllegalCharsetNameException.class);
+ } catch (IllegalCharsetNameException badName) {
+ assertEquals("'utf8'", badName.getMessage());
+ }
+ }
+
+ @Test
+ public void testParse_illegalEncoding() throws Exception {
+ ByteArrayOutputStream b = new ByteArrayOutputStream();
+ b.write("tree 9788669ad918b6fcce64af8882fc9a81cb6aba67\n".getBytes(UTF_8));
+ b.write("author au <a@example.com> 1218123387 +0700\n".getBytes(UTF_8));
+ b.write("committer co <c@example.com> 1218123390 -0500\n".getBytes(UTF_8));
+ b.write("encoding utf-8logoutputencoding=gbk\n".getBytes(UTF_8));
+ b.write("\n".getBytes(UTF_8));
+ b.write("message\n".getBytes(UTF_8));
+
+ RevCommit c = new RevCommit(
+ id("9473095c4cb2f12aefe1db8a355fe3fafba42f67"));
+ c.parseCanonical(new RevWalk(db), b.toByteArray());
+ assertEquals("utf-8logoutputencoding=gbk", c.getEncodingName());
+ assertEquals("message\n", c.getFullMessage());
+ assertEquals("message", c.getShortMessage());
+ assertTrue(c.getFooterLines().isEmpty());
+ assertEquals("au", c.getAuthorIdent().getName());
+
+ try {
+ c.getEncoding();
+ fail("Expected " + IllegalCharsetNameException.class);
+ } catch (IllegalCharsetNameException badName) {
+ assertEquals("utf-8logoutputencoding=gbk", badName.getMessage());
+ }
+ }
+
+ @Test
+ public void testParse_unsupportedEncoding() throws Exception {
+ ByteArrayOutputStream b = new ByteArrayOutputStream();
+ b.write("tree 9788669ad918b6fcce64af8882fc9a81cb6aba67\n".getBytes(UTF_8));
+ b.write("author au <a@example.com> 1218123387 +0700\n".getBytes(UTF_8));
+ b.write("committer co <c@example.com> 1218123390 -0500\n".getBytes(UTF_8));
+ b.write("encoding it_IT.UTF8\n".getBytes(UTF_8));
+ b.write("\n".getBytes(UTF_8));
+ b.write("message\n".getBytes(UTF_8));
+
+ RevCommit c = new RevCommit(
+ id("9473095c4cb2f12aefe1db8a355fe3fafba42f67"));
+ c.parseCanonical(new RevWalk(db), b.toByteArray());
+ assertEquals("it_IT.UTF8", c.getEncodingName());
+ assertEquals("message\n", c.getFullMessage());
+ assertEquals("message", c.getShortMessage());
+ assertTrue(c.getFooterLines().isEmpty());
+ assertEquals("au", c.getAuthorIdent().getName());
+
+ try {
+ c.getEncoding();
+ fail("Expected " + UnsupportedCharsetException.class);
+ } catch (UnsupportedCharsetException badName) {
+ assertEquals("it_IT.UTF8", badName.getMessage());
+ }
+ }
+
+ @Test
public void testParse_NoMessage() throws Exception {
final String msg = "";
final RevCommit c = create(msg);
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevTagParseTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevTagParseTest.java
index 614f49bf03..82505caf22 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevTagParseTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevTagParseTest.java
@@ -43,6 +43,7 @@
package org.eclipse.jgit.revwalk;
+import static java.nio.charset.StandardCharsets.UTF_8;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
@@ -362,6 +363,44 @@ public class RevTagParseTest extends RepositoryTestCase {
}
@Test
+ public void testParse_illegalEncoding() throws Exception {
+ ByteArrayOutputStream b = new ByteArrayOutputStream();
+ b.write("object 9788669ad918b6fcce64af8882fc9a81cb6aba67\n".getBytes(UTF_8));
+ b.write("type tree\n".getBytes(UTF_8));
+ b.write("tag v1.0\n".getBytes(UTF_8));
+ b.write("tagger t <t@example.com> 1218123387 +0700\n".getBytes(UTF_8));
+ b.write("encoding utf-8logoutputencoding=gbk\n".getBytes(UTF_8));
+ b.write("\n".getBytes(UTF_8));
+ b.write("message\n".getBytes(UTF_8));
+
+ RevTag t = new RevTag(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67"));
+ t.parseCanonical(new RevWalk(db), b.toByteArray());
+
+ assertEquals("t", t.getTaggerIdent().getName());
+ assertEquals("message", t.getShortMessage());
+ assertEquals("message\n", t.getFullMessage());
+ }
+
+ @Test
+ public void testParse_unsupportedEncoding() throws Exception {
+ ByteArrayOutputStream b = new ByteArrayOutputStream();
+ b.write("object 9788669ad918b6fcce64af8882fc9a81cb6aba67\n".getBytes(UTF_8));
+ b.write("type tree\n".getBytes(UTF_8));
+ b.write("tag v1.0\n".getBytes(UTF_8));
+ b.write("tagger t <t@example.com> 1218123387 +0700\n".getBytes(UTF_8));
+ b.write("encoding it_IT.UTF8\n".getBytes(UTF_8));
+ b.write("\n".getBytes(UTF_8));
+ b.write("message\n".getBytes(UTF_8));
+
+ RevTag t = new RevTag(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67"));
+ t.parseCanonical(new RevWalk(db), b.toByteArray());
+
+ assertEquals("t", t.getTaggerIdent().getName());
+ assertEquals("message", t.getShortMessage());
+ assertEquals("message\n", t.getFullMessage());
+ }
+
+ @Test
public void testParse_NoMessage() throws Exception {
final String msg = "";
final RevTag c = create(msg);
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/AtomicPushTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/AtomicPushTest.java
index 782e414b62..c1e078d10d 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/AtomicPushTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/AtomicPushTest.java
@@ -112,12 +112,9 @@ public class AtomicPushTest {
public void pushNonAtomic() throws Exception {
PushResult r;
server.setPerformsAtomicTransactions(false);
- Transport tn = testProtocol.open(uri, client, "server");
- try {
+ try (Transport tn = testProtocol.open(uri, client, "server")) {
tn.setPushAtomic(false);
r = tn.push(NullProgressMonitor.INSTANCE, commands());
- } finally {
- tn.close();
}
RemoteRefUpdate one = r.getRemoteUpdate("refs/heads/one");
@@ -131,12 +128,9 @@ public class AtomicPushTest {
@Test
public void pushAtomicClientGivesUpEarly() throws Exception {
PushResult r;
- Transport tn = testProtocol.open(uri, client, "server");
- try {
+ try (Transport tn = testProtocol.open(uri, client, "server")) {
tn.setPushAtomic(true);
r = tn.push(NullProgressMonitor.INSTANCE, commands());
- } finally {
- tn.close();
}
RemoteRefUpdate one = r.getRemoteUpdate("refs/heads/one");
@@ -167,8 +161,7 @@ public class AtomicPushTest {
ObjectId.zeroId()));
server.setPerformsAtomicTransactions(false);
- Transport tn = testProtocol.open(uri, client, "server");
- try {
+ try (Transport tn = testProtocol.open(uri, client, "server")) {
tn.setPushAtomic(true);
tn.push(NullProgressMonitor.INSTANCE, cmds);
fail("did not throw TransportException");
@@ -176,8 +169,6 @@ public class AtomicPushTest {
assertEquals(
uri + ": " + JGitText.get().atomicPushNotSupported,
e.getMessage());
- } finally {
- tn.close();
}
}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/BundleWriterTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/BundleWriterTest.java
index 461530896d..a83a993330 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/BundleWriterTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/BundleWriterTest.java
@@ -168,8 +168,10 @@ public class BundleWriterTest extends SampleDataRepositoryTestCase {
final ByteArrayInputStream in = new ByteArrayInputStream(bundle);
final RefSpec rs = new RefSpec("refs/heads/*:refs/heads/*");
final Set<RefSpec> refs = Collections.singleton(rs);
- return new TransportBundleStream(newRepo, uri, in).fetch(
- NullProgressMonitor.INSTANCE, refs);
+ try (TransportBundleStream transport = new TransportBundleStream(
+ newRepo, uri, in)) {
+ return transport.fetch(NullProgressMonitor.INSTANCE, refs);
+ }
}
private byte[] makeBundle(final String name,
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/ReceivePackAdvertiseRefsHookTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/ReceivePackAdvertiseRefsHookTest.java
index aa5914fe03..94bc383db7 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/ReceivePackAdvertiseRefsHookTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/ReceivePackAdvertiseRefsHookTest.java
@@ -116,12 +116,9 @@ public class ReceivePackAdvertiseRefsHookTest extends LocalDiskRepositoryTestCas
// Clone from dst into src
//
- Transport t = Transport.open(src, uriOf(dst));
- try {
+ try (Transport t = Transport.open(src, uriOf(dst))) {
t.fetch(PM, Collections.singleton(new RefSpec("+refs/*:refs/*")));
assertEquals(B, src.resolve(R_MASTER));
- } finally {
- t.close();
}
// Now put private stuff into dst.
@@ -144,7 +141,8 @@ public class ReceivePackAdvertiseRefsHookTest extends LocalDiskRepositoryTestCas
@Test
public void testFilterHidesPrivate() throws Exception {
Map<String, Ref> refs;
- TransportLocal t = new TransportLocal(src, uriOf(dst), dst.getDirectory()) {
+ try (TransportLocal t = new TransportLocal(src, uriOf(dst),
+ dst.getDirectory()) {
@Override
ReceivePack createReceivePack(final Repository db) {
db.close();
@@ -154,16 +152,10 @@ public class ReceivePackAdvertiseRefsHookTest extends LocalDiskRepositoryTestCas
rp.setAdvertiseRefsHook(new HidePrivateHook());
return rp;
}
- };
- try {
- PushConnection c = t.openPush();
- try {
+ }) {
+ try (PushConnection c = t.openPush()) {
refs = c.getRefsMap();
- } finally {
- c.close();
}
- } finally {
- t.close();
}
assertNotNull(refs);
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/RefSpecTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/RefSpecTest.java
index 3f5fcbbf07..4f833509d9 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/RefSpecTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/RefSpecTest.java
@@ -341,6 +341,41 @@ public class RefSpecTest {
}
@Test
+ public void testWildcardAfterText1() {
+ RefSpec a = new RefSpec("refs/heads/*/for-linus:refs/remotes/mine/*-blah");
+ assertTrue(a.isWildcard());
+ assertTrue(a.matchDestination("refs/remotes/mine/x-blah"));
+ assertTrue(a.matchDestination("refs/remotes/mine/foo-blah"));
+ assertTrue(a.matchDestination("refs/remotes/mine/foo/x-blah"));
+ assertFalse(a.matchDestination("refs/remotes/origin/foo/x-blah"));
+
+ RefSpec b = a.expandFromSource("refs/heads/foo/for-linus");
+ assertEquals("refs/remotes/mine/foo-blah", b.getDestination());
+ RefSpec c = a.expandFromDestination("refs/remotes/mine/foo-blah");
+ assertEquals("refs/heads/foo/for-linus", c.getSource());
+ }
+
+ @Test
+ public void testWildcardAfterText2() {
+ RefSpec a = new RefSpec("refs/heads*/for-linus:refs/remotes/mine/*");
+ assertTrue(a.isWildcard());
+ assertTrue(a.matchSource("refs/headsx/for-linus"));
+ assertTrue(a.matchSource("refs/headsfoo/for-linus"));
+ assertTrue(a.matchSource("refs/headsx/foo/for-linus"));
+ assertFalse(a.matchSource("refs/headx/for-linus"));
+
+ RefSpec b = a.expandFromSource("refs/headsx/for-linus");
+ assertEquals("refs/remotes/mine/x", b.getDestination());
+ RefSpec c = a.expandFromDestination("refs/remotes/mine/x");
+ assertEquals("refs/headsx/for-linus", c.getSource());
+
+ RefSpec d = a.expandFromSource("refs/headsx/foo/for-linus");
+ assertEquals("refs/remotes/mine/x/foo", d.getDestination());
+ RefSpec e = a.expandFromDestination("refs/remotes/mine/x/foo");
+ assertEquals("refs/headsx/foo/for-linus", e.getSource());
+ }
+
+ @Test
public void testWildcardMirror() {
RefSpec a = new RefSpec("*:*");
assertTrue(a.isWildcard());
@@ -404,21 +439,6 @@ public class RefSpecTest {
}
@Test(expected = IllegalArgumentException.class)
- public void invalidWhenWildcardAfterText() {
- assertNotNull(new RefSpec("refs/heads/wrong*:refs/heads/right/*"));
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void invalidWhenWildcardBeforeText() {
- assertNotNull(new RefSpec("*wrong:right/*"));
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void invalidWhenWildcardBeforeTextAtEnd() {
- assertNotNull(new RefSpec("refs/heads/*wrong:right/*"));
- }
-
- @Test(expected = IllegalArgumentException.class)
public void invalidSourceDoubleSlashes() {
assertNotNull(new RefSpec("refs/heads//wrong"));
}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/TransportTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/TransportTest.java
index 55e1e44206..5519f61ac2 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/TransportTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/TransportTest.java
@@ -61,13 +61,10 @@ import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.test.resources.SampleDataRepositoryTestCase;
-import org.junit.After;
import org.junit.Before;
import org.junit.Test;
public class TransportTest extends SampleDataRepositoryTestCase {
- private Transport transport;
-
private RemoteConfig remoteConfig;
@Override
@@ -77,17 +74,6 @@ public class TransportTest extends SampleDataRepositoryTestCase {
final Config config = db.getConfig();
remoteConfig = new RemoteConfig(config, "test");
remoteConfig.addURI(new URIish("http://everyones.loves.git/u/2"));
- transport = null;
- }
-
- @Override
- @After
- public void tearDown() throws Exception {
- if (transport != null) {
- transport.close();
- transport = null;
- }
- super.tearDown();
}
/**
@@ -99,10 +85,11 @@ public class TransportTest extends SampleDataRepositoryTestCase {
@Test
public void testFindRemoteRefUpdatesNoWildcardNoTracking()
throws IOException {
- transport = Transport.open(db, remoteConfig);
- final Collection<RemoteRefUpdate> result = transport
- .findRemoteRefUpdatesFor(Collections.nCopies(1, new RefSpec(
- "refs/heads/master:refs/heads/x")));
+ Collection<RemoteRefUpdate> result;
+ try (Transport transport = Transport.open(db, remoteConfig)) {
+ result = transport.findRemoteRefUpdatesFor(Collections.nCopies(1,
+ new RefSpec("refs/heads/master:refs/heads/x")));
+ }
assertEquals(1, result.size());
final RemoteRefUpdate rru = result.iterator().next();
@@ -122,10 +109,11 @@ public class TransportTest extends SampleDataRepositoryTestCase {
@Test
public void testFindRemoteRefUpdatesNoWildcardNoDestination()
throws IOException {
- transport = Transport.open(db, remoteConfig);
- final Collection<RemoteRefUpdate> result = transport
- .findRemoteRefUpdatesFor(Collections.nCopies(1, new RefSpec(
- "+refs/heads/master")));
+ Collection<RemoteRefUpdate> result;
+ try (Transport transport = Transport.open(db, remoteConfig)) {
+ result = transport.findRemoteRefUpdatesFor(
+ Collections.nCopies(1, new RefSpec("+refs/heads/master")));
+ }
assertEquals(1, result.size());
final RemoteRefUpdate rru = result.iterator().next();
@@ -143,10 +131,11 @@ public class TransportTest extends SampleDataRepositoryTestCase {
*/
@Test
public void testFindRemoteRefUpdatesWildcardNoTracking() throws IOException {
- transport = Transport.open(db, remoteConfig);
- final Collection<RemoteRefUpdate> result = transport
- .findRemoteRefUpdatesFor(Collections.nCopies(1, new RefSpec(
- "+refs/heads/*:refs/heads/test/*")));
+ Collection<RemoteRefUpdate> result;
+ try (Transport transport = Transport.open(db, remoteConfig)) {
+ result = transport.findRemoteRefUpdatesFor(Collections.nCopies(1,
+ new RefSpec("+refs/heads/*:refs/heads/test/*")));
+ }
assertEquals(12, result.size());
boolean foundA = false;
@@ -171,12 +160,14 @@ public class TransportTest extends SampleDataRepositoryTestCase {
*/
@Test
public void testFindRemoteRefUpdatesTwoRefSpecs() throws IOException {
- transport = Transport.open(db, remoteConfig);
final RefSpec specA = new RefSpec("+refs/heads/a:refs/heads/b");
final RefSpec specC = new RefSpec("+refs/heads/c:refs/heads/d");
final Collection<RefSpec> specs = Arrays.asList(specA, specC);
- final Collection<RemoteRefUpdate> result = transport
- .findRemoteRefUpdatesFor(specs);
+
+ Collection<RemoteRefUpdate> result;
+ try (Transport transport = Transport.open(db, remoteConfig)) {
+ result = transport.findRemoteRefUpdatesFor(specs);
+ }
assertEquals(2, result.size());
boolean foundA = false;
@@ -202,10 +193,12 @@ public class TransportTest extends SampleDataRepositoryTestCase {
public void testFindRemoteRefUpdatesTrackingRef() throws IOException {
remoteConfig.addFetchRefSpec(new RefSpec(
"refs/heads/*:refs/remotes/test/*"));
- transport = Transport.open(db, remoteConfig);
- final Collection<RemoteRefUpdate> result = transport
- .findRemoteRefUpdatesFor(Collections.nCopies(1, new RefSpec(
- "+refs/heads/a:refs/heads/a")));
+
+ Collection<RemoteRefUpdate> result;
+ try (Transport transport = Transport.open(db, remoteConfig)) {
+ result = transport.findRemoteRefUpdatesFor(Collections.nCopies(1,
+ new RefSpec("+refs/heads/a:refs/heads/a")));
+ }
assertEquals(1, result.size());
final TrackingRefUpdate tru = result.iterator().next()
@@ -225,20 +218,18 @@ public class TransportTest extends SampleDataRepositoryTestCase {
config.addURI(new URIish("../" + otherDir));
// Should not throw NoRemoteRepositoryException
- transport = Transport.open(db, config);
+ Transport.open(db, config).close();
}
@Test
public void testLocalTransportFetchWithoutLocalRepository()
throws Exception {
URIish uri = new URIish("file://" + db.getWorkTree().getAbsolutePath());
- transport = Transport.open(uri);
- FetchConnection fetchConnection = transport.openFetch();
- try {
- Ref head = fetchConnection.getRef(Constants.HEAD);
- assertNotNull(head);
- } finally {
- fetchConnection.close();
+ try (Transport transport = Transport.open(uri)) {
+ try (FetchConnection fetchConnection = transport.openFetch()) {
+ Ref head = fetchConnection.getRef(Constants.HEAD);
+ assertNotNull(head);
+ }
}
}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/URIishTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/URIishTest.java
index 2078dd337b..e55d373347 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/URIishTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/URIishTest.java
@@ -460,6 +460,48 @@ public class URIishTest {
}
@Test
+ public void testSshProtoWithEmailUserAndPort() throws Exception {
+ final String str = "ssh://user.name@email.com@example.com:33/some/p ath";
+ URIish u = new URIish(str);
+ assertEquals("ssh", u.getScheme());
+ assertTrue(u.isRemote());
+ assertEquals("/some/p ath", u.getRawPath());
+ assertEquals("/some/p ath", u.getPath());
+ assertEquals("example.com", u.getHost());
+ assertEquals("user.name@email.com", u.getUser());
+ assertNull(u.getPass());
+ assertEquals(33, u.getPort());
+ assertEquals("ssh://user.name%40email.com@example.com:33/some/p ath",
+ u.toPrivateString());
+ assertEquals("ssh://user.name%40email.com@example.com:33/some/p%20ath",
+ u.toPrivateASCIIString());
+ assertEquals(u.setPass(null).toPrivateString(), u.toString());
+ assertEquals(u.setPass(null).toPrivateASCIIString(), u.toASCIIString());
+ assertEquals(u, new URIish(str));
+ }
+
+ @Test
+ public void testSshProtoWithEmailUserPassAndPort() throws Exception {
+ final String str = "ssh://user.name@email.com:pass@wor:d@example.com:33/some/p ath";
+ URIish u = new URIish(str);
+ assertEquals("ssh", u.getScheme());
+ assertTrue(u.isRemote());
+ assertEquals("/some/p ath", u.getRawPath());
+ assertEquals("/some/p ath", u.getPath());
+ assertEquals("example.com", u.getHost());
+ assertEquals("user.name@email.com", u.getUser());
+ assertEquals("pass@wor:d", u.getPass());
+ assertEquals(33, u.getPort());
+ assertEquals("ssh://user.name%40email.com:pass%40wor%3ad@example.com:33/some/p ath",
+ u.toPrivateString());
+ assertEquals("ssh://user.name%40email.com:pass%40wor%3ad@example.com:33/some/p%20ath",
+ u.toPrivateASCIIString());
+ assertEquals(u.setPass(null).toPrivateString(), u.toString());
+ assertEquals(u.setPass(null).toPrivateASCIIString(), u.toASCIIString());
+ assertEquals(u, new URIish(str));
+ }
+
+ @Test
public void testSshProtoWithADUserPassAndPort() throws Exception {
final String str = "ssh://DOMAIN\\user:pass@example.com:33/some/p ath";
URIish u = new URIish(str);
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/TreeWalkBasicDiffTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/TreeWalkBasicDiffTest.java
index aca7c80fd7..c3ff7df8f2 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/TreeWalkBasicDiffTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/TreeWalkBasicDiffTest.java
@@ -44,7 +44,6 @@
package org.eclipse.jgit.treewalk;
import static org.eclipse.jgit.lib.Constants.OBJ_BLOB;
-import static org.eclipse.jgit.lib.Constants.OBJ_TREE;
import static org.eclipse.jgit.lib.Constants.encode;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -54,11 +53,10 @@ import org.eclipse.jgit.junit.RepositoryTestCase;
import org.eclipse.jgit.lib.FileMode;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectInserter;
-import org.eclipse.jgit.lib.Tree;
+import org.eclipse.jgit.lib.TreeFormatter;
import org.eclipse.jgit.treewalk.filter.TreeFilter;
import org.junit.Test;
-@SuppressWarnings("deprecation")
public class TreeWalkBasicDiffTest extends RepositoryTestCase {
@Test
public void testMissingSubtree_DetectFileAdded_FileModified()
@@ -72,62 +70,63 @@ public class TreeWalkBasicDiffTest extends RepositoryTestCase {
// Create sub-a/empty, sub-c/empty = hello.
{
- final Tree root = new Tree(db);
+ TreeFormatter root = new TreeFormatter();
{
- final Tree subA = root.addTree("sub-a");
- subA.addFile("empty").setId(aFileId);
- subA.setId(inserter.insert(OBJ_TREE, subA.format()));
+ TreeFormatter subA = new TreeFormatter();
+ subA.append("empty", FileMode.REGULAR_FILE, aFileId);
+ root.append("sub-a", FileMode.TREE, inserter.insert(subA));
}
{
- final Tree subC = root.addTree("sub-c");
- subC.addFile("empty").setId(cFileId1);
- subC.setId(inserter.insert(OBJ_TREE, subC.format()));
+ TreeFormatter subC = new TreeFormatter();
+ subC.append("empty", FileMode.REGULAR_FILE, cFileId1);
+ root.append("sub-c", FileMode.TREE, inserter.insert(subC));
}
- oldTree = inserter.insert(OBJ_TREE, root.format());
+ oldTree = inserter.insert(root);
}
// Create sub-a/empty, sub-b/empty, sub-c/empty.
{
- final Tree root = new Tree(db);
+ TreeFormatter root = new TreeFormatter();
{
- final Tree subA = root.addTree("sub-a");
- subA.addFile("empty").setId(aFileId);
- subA.setId(inserter.insert(OBJ_TREE, subA.format()));
+ TreeFormatter subA = new TreeFormatter();
+ subA.append("empty", FileMode.REGULAR_FILE, aFileId);
+ root.append("sub-a", FileMode.TREE, inserter.insert(subA));
}
{
- final Tree subB = root.addTree("sub-b");
- subB.addFile("empty").setId(bFileId);
- subB.setId(inserter.insert(OBJ_TREE, subB.format()));
+ TreeFormatter subB = new TreeFormatter();
+ subB.append("empty", FileMode.REGULAR_FILE, bFileId);
+ root.append("sub-b", FileMode.TREE, inserter.insert(subB));
}
{
- final Tree subC = root.addTree("sub-c");
- subC.addFile("empty").setId(cFileId2);
- subC.setId(inserter.insert(OBJ_TREE, subC.format()));
+ TreeFormatter subC = new TreeFormatter();
+ subC.append("empty", FileMode.REGULAR_FILE, cFileId2);
+ root.append("sub-c", FileMode.TREE, inserter.insert(subC));
}
- newTree = inserter.insert(OBJ_TREE, root.format());
+ newTree = inserter.insert(root);
}
inserter.flush();
}
- final TreeWalk tw = new TreeWalk(db);
- tw.reset(oldTree, newTree);
- tw.setRecursive(true);
- tw.setFilter(TreeFilter.ANY_DIFF);
+ try (TreeWalk tw = new TreeWalk(db)) {
+ tw.reset(oldTree, newTree);
+ tw.setRecursive(true);
+ tw.setFilter(TreeFilter.ANY_DIFF);
- assertTrue(tw.next());
- assertEquals("sub-b/empty", tw.getPathString());
- assertEquals(FileMode.MISSING, tw.getFileMode(0));
- assertEquals(FileMode.REGULAR_FILE, tw.getFileMode(1));
- assertEquals(ObjectId.zeroId(), tw.getObjectId(0));
- assertEquals(bFileId, tw.getObjectId(1));
+ assertTrue(tw.next());
+ assertEquals("sub-b/empty", tw.getPathString());
+ assertEquals(FileMode.MISSING, tw.getFileMode(0));
+ assertEquals(FileMode.REGULAR_FILE, tw.getFileMode(1));
+ assertEquals(ObjectId.zeroId(), tw.getObjectId(0));
+ assertEquals(bFileId, tw.getObjectId(1));
- assertTrue(tw.next());
- assertEquals("sub-c/empty", tw.getPathString());
- assertEquals(FileMode.REGULAR_FILE, tw.getFileMode(0));
- assertEquals(FileMode.REGULAR_FILE, tw.getFileMode(1));
- assertEquals(cFileId1, tw.getObjectId(0));
- assertEquals(cFileId2, tw.getObjectId(1));
+ assertTrue(tw.next());
+ assertEquals("sub-c/empty", tw.getPathString());
+ assertEquals(FileMode.REGULAR_FILE, tw.getFileMode(0));
+ assertEquals(FileMode.REGULAR_FILE, tw.getFileMode(1));
+ assertEquals(cFileId1, tw.getObjectId(0));
+ assertEquals(cFileId2, tw.getObjectId(1));
- assertFalse(tw.next());
+ assertFalse(tw.next());
+ }
}
}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/filter/PathFilterGroupTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/filter/PathFilterGroupTest.java
index d0062e1990..5edc1924f2 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/filter/PathFilterGroupTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/filter/PathFilterGroupTest.java
@@ -43,11 +43,18 @@
package org.eclipse.jgit.treewalk.filter;
+import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
import org.eclipse.jgit.dircache.DirCache;
import org.eclipse.jgit.dircache.DirCacheEditor;
@@ -58,6 +65,7 @@ import org.eclipse.jgit.errors.MissingObjectException;
import org.eclipse.jgit.errors.StopWalkException;
import org.eclipse.jgit.lib.FileMode;
import org.eclipse.jgit.lib.ObjectReader;
+import org.eclipse.jgit.lib.Sets;
import org.eclipse.jgit.treewalk.TreeWalk;
import org.junit.Before;
import org.junit.Test;
@@ -66,6 +74,8 @@ public class PathFilterGroupTest {
private TreeFilter filter;
+ private Map<String, TreeFilter> singles;
+
@Before
public void setup() {
// @formatter:off
@@ -81,64 +91,75 @@ public class PathFilterGroupTest {
};
// @formatter:on
filter = PathFilterGroup.createFromStrings(paths);
+ singles = new HashMap<>();
+ for (String path : paths) {
+ singles.put(path, PathFilterGroup.createFromStrings(path));
+ }
}
@Test
public void testExact() throws MissingObjectException,
IncorrectObjectTypeException, IOException {
- assertTrue(filter.include(fakeWalk("a")));
- assertTrue(filter.include(fakeWalk("b/c")));
- assertTrue(filter.include(fakeWalk("c/d/e")));
- assertTrue(filter.include(fakeWalk("c/d/f")));
- assertTrue(filter.include(fakeWalk("d/e/f/g")));
- assertTrue(filter.include(fakeWalk("d/e/f/g.x")));
+ assertMatches(Sets.of("a"), fakeWalk("a"));
+ assertMatches(Sets.of("b/c"), fakeWalk("b/c"));
+ assertMatches(Sets.of("c/d/e"), fakeWalk("c/d/e"));
+ assertMatches(Sets.of("c/d/f"), fakeWalk("c/d/f"));
+ assertMatches(Sets.of("d/e/f/g"), fakeWalk("d/e/f/g"));
+ assertMatches(Sets.of("d/e/f/g.x"), fakeWalk("d/e/f/g.x"));
}
@Test
public void testNoMatchButClose() throws MissingObjectException,
IncorrectObjectTypeException, IOException {
- assertFalse(filter.include(fakeWalk("a+")));
- assertFalse(filter.include(fakeWalk("b+/c")));
- assertFalse(filter.include(fakeWalk("c+/d/e")));
- assertFalse(filter.include(fakeWalk("c+/d/f")));
- assertFalse(filter.include(fakeWalk("c/d.a")));
- assertFalse(filter.include(fakeWalk("d+/e/f/g")));
+ assertNoMatches(fakeWalk("a+"));
+ assertNoMatches(fakeWalk("b+/c"));
+ assertNoMatches(fakeWalk("c+/d/e"));
+ assertNoMatches(fakeWalk("c+/d/f"));
+ assertNoMatches(fakeWalk("c/d.a"));
+ assertNoMatches(fakeWalk("d+/e/f/g"));
}
@Test
public void testJustCommonPrefixIsNotMatch() throws MissingObjectException,
IncorrectObjectTypeException, IOException {
- assertFalse(filter.include(fakeWalk("b/a")));
- assertFalse(filter.include(fakeWalk("b/d")));
- assertFalse(filter.include(fakeWalk("c/d/a")));
- assertFalse(filter.include(fakeWalk("d/e/e")));
+ assertNoMatches(fakeWalk("b/a"));
+ assertNoMatches(fakeWalk("b/d"));
+ assertNoMatches(fakeWalk("c/d/a"));
+ assertNoMatches(fakeWalk("d/e/e"));
+ assertNoMatches(fakeWalk("d/e/f/g.y"));
}
@Test
public void testKeyIsPrefixOfFilter() throws MissingObjectException,
IncorrectObjectTypeException, IOException {
- assertTrue(filter.include(fakeWalk("b")));
- assertTrue(filter.include(fakeWalk("c/d")));
- assertTrue(filter.include(fakeWalk("c/d")));
- assertTrue(filter.include(fakeWalk("c")));
- assertTrue(filter.include(fakeWalk("d/e/f")));
- assertTrue(filter.include(fakeWalk("d/e")));
- assertTrue(filter.include(fakeWalk("d")));
+ assertMatches(Sets.of("b/c"), fakeWalkAtSubtree("b"));
+ assertMatches(Sets.of("c/d/e", "c/d/f"), fakeWalkAtSubtree("c/d"));
+ assertMatches(Sets.of("c/d/e", "c/d/f"), fakeWalkAtSubtree("c"));
+ assertMatches(Sets.of("d/e/f/g", "d/e/f/g.x"),
+ fakeWalkAtSubtree("d/e/f"));
+ assertMatches(Sets.of("d/e/f/g", "d/e/f/g.x"),
+ fakeWalkAtSubtree("d/e"));
+ assertMatches(Sets.of("d/e/f/g", "d/e/f/g.x"), fakeWalkAtSubtree("d"));
+
+ assertNoMatches(fakeWalk("b"));
+ assertNoMatches(fakeWalk("c/d"));
+ assertNoMatches(fakeWalk("c"));
+ assertNoMatches(fakeWalk("d/e/f"));
+ assertNoMatches(fakeWalk("d/e"));
+ assertNoMatches(fakeWalk("d"));
+
}
@Test
public void testFilterIsPrefixOfKey() throws MissingObjectException,
IncorrectObjectTypeException, IOException {
- assertTrue(filter.include(fakeWalk("a/b")));
- assertTrue(filter.include(fakeWalk("b/c/d")));
- assertTrue(filter.include(fakeWalk("c/d/e/f")));
- assertTrue(filter.include(fakeWalk("c/d/f/g")));
- assertTrue(filter.include(fakeWalk("d/e/f/g/h")));
- assertTrue(filter.include(fakeWalk("d/e/f/g/y")));
- assertTrue(filter.include(fakeWalk("d/e/f/g.x/h")));
- // listed before g/y, so can't StopWalk here, but it's not included
- // either
- assertFalse(filter.include(fakeWalk("d/e/f/g.y")));
+ assertMatches(Sets.of("a"), fakeWalk("a/b"));
+ assertMatches(Sets.of("b/c"), fakeWalk("b/c/d"));
+ assertMatches(Sets.of("c/d/e"), fakeWalk("c/d/e/f"));
+ assertMatches(Sets.of("c/d/f"), fakeWalk("c/d/f/g"));
+ assertMatches(Sets.of("d/e/f/g"), fakeWalk("d/e/f/g/h"));
+ assertMatches(Sets.of("d/e/f/g"), fakeWalk("d/e/f/g/y"));
+ assertMatches(Sets.of("d/e/f/g.x"), fakeWalk("d/e/f/g.x/h"));
}
@Test
@@ -182,6 +203,10 @@ public class PathFilterGroupTest {
// less obvious #2 due to git sorting order
filter.include(fakeWalk("d/e/f/g/h.txt"));
+ // listed before g/y, so can't StopWalk here
+ filter.include(fakeWalk("d/e/f/g.y"));
+ singles.get("d/e/f/g").include(fakeWalk("d/e/f/g.y"));
+
// non-ascii
try {
filter.include(fakeWalk("\u00C0"));
@@ -191,6 +216,44 @@ public class PathFilterGroupTest {
}
}
+ private void assertNoMatches(TreeWalk tw) throws MissingObjectException,
+ IncorrectObjectTypeException, IOException {
+ assertMatches(Sets.<String> of(), tw);
+ }
+
+ private void assertMatches(Set<String> expect, TreeWalk tw)
+ throws MissingObjectException, IncorrectObjectTypeException,
+ IOException {
+ List<String> actual = new ArrayList<>();
+ for (String path : singles.keySet()) {
+ if (includes(singles.get(path), tw)) {
+ actual.add(path);
+ }
+ }
+
+ String[] e = expect.toArray(new String[expect.size()]);
+ String[] a = actual.toArray(new String[actual.size()]);
+ Arrays.sort(e);
+ Arrays.sort(a);
+ assertArrayEquals(e, a);
+
+ if (expect.isEmpty()) {
+ assertFalse(includes(filter, tw));
+ } else {
+ assertTrue(includes(filter, tw));
+ }
+ }
+
+ private static boolean includes(TreeFilter f, TreeWalk tw)
+ throws MissingObjectException, IncorrectObjectTypeException,
+ IOException {
+ try {
+ return f.include(tw);
+ } catch (StopWalkException e) {
+ return false;
+ }
+ }
+
TreeWalk fakeWalk(final String path) throws IOException {
DirCache dc = DirCache.newInCore();
DirCacheEditor dce = dc.editor();
@@ -210,4 +273,25 @@ public class PathFilterGroupTest {
return ret;
}
+ TreeWalk fakeWalkAtSubtree(final String path) throws IOException {
+ DirCache dc = DirCache.newInCore();
+ DirCacheEditor dce = dc.editor();
+ dce.add(new DirCacheEditor.PathEdit(path + "/README") {
+ public void apply(DirCacheEntry ent) {
+ ent.setFileMode(FileMode.REGULAR_FILE);
+ }
+ });
+ dce.finish();
+
+ TreeWalk ret = new TreeWalk((ObjectReader) null);
+ ret.addTree(new DirCacheIterator(dc));
+ ret.next();
+ while (!path.equals(ret.getPathString())) {
+ if (ret.isSubtree()) {
+ ret.enterSubtree();
+ }
+ ret.next();
+ }
+ return ret;
+ }
}
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/ChangeIdUtilTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/ChangeIdUtilTest.java
index 7273cdbabc..aaeb79c64a 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/ChangeIdUtilTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/ChangeIdUtilTest.java
@@ -45,7 +45,6 @@ package org.eclipse.jgit.util;
import static org.junit.Assert.assertEquals;
-import java.io.IOException;
import java.util.concurrent.TimeUnit;
import org.eclipse.jgit.junit.MockSystemReader;
@@ -113,7 +112,7 @@ public class ChangeIdUtilTest {
}
@Test
- public void testId() throws IOException {
+ public void testId() {
String msg = "A\nMessage\n";
ObjectId id = ChangeIdUtil.computeChangeId(treeId, parentId, p, q, msg);
assertEquals("73f3751208ac92cbb76f9a26ac4a0d9d472e381b", ObjectId
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/FileUtilTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/FileUtilTest.java
index 0d7d31b3ad..1f78e02087 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/FileUtilTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/FileUtilTest.java
@@ -54,6 +54,7 @@ import java.util.regex.Matcher;
import org.eclipse.jgit.junit.JGitTestUtil;
import org.junit.After;
+import org.junit.Assume;
import org.junit.Before;
import org.junit.Test;
@@ -424,19 +425,28 @@ public class FileUtilTest {
@Test
public void testCreateSymlink() throws IOException {
FS fs = FS.DETECTED;
- try {
- fs.createSymLink(new File(trash, "x"), "y");
- } catch (IOException e) {
- if (fs.supportsSymlinks())
- fail("FS claims to support symlinks but attempt to create symlink failed");
- return;
- }
- assertTrue(fs.supportsSymlinks());
+ // show test as ignored if the FS doesn't support symlinks
+ Assume.assumeTrue(fs.supportsSymlinks());
+ fs.createSymLink(new File(trash, "x"), "y");
String target = fs.readSymLink(new File(trash, "x"));
assertEquals("y", target);
}
@Test
+ public void testCreateSymlinkOverrideExisting() throws IOException {
+ FS fs = FS.DETECTED;
+ // show test as ignored if the FS doesn't support symlinks
+ Assume.assumeTrue(fs.supportsSymlinks());
+ File file = new File(trash, "x");
+ fs.createSymLink(file, "y");
+ String target = fs.readSymLink(file);
+ assertEquals("y", target);
+ fs.createSymLink(file, "z");
+ target = fs.readSymLink(file);
+ assertEquals("z", target);
+ }
+
+ @Test
public void testRelativize_doc() {
// This is the javadoc example
String base = toOSPathString("c:\\Users\\jdoe\\eclipse\\git\\project");
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
new file mode 100644
index 0000000000..7542ec8910
--- /dev/null
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/PathsTest.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2016, Google Inc.
+ * and other copyright owners as documented in the project's IP log.
+ *
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Distribution License v1.0 which
+ * accompanies this distribution, is reproduced below, and is
+ * available at http://www.eclipse.org/org/documents/edl-v10.php
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * - Neither the name of the Eclipse Foundation, Inc. nor the
+ * names of its contributors may be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.eclipse.jgit.util;
+
+import static org.eclipse.jgit.util.Paths.compare;
+import static org.eclipse.jgit.util.Paths.compareSameName;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.FileMode;
+import org.junit.Test;
+
+public class PathsTest {
+ @Test
+ public void testStripTrailingSeparator() {
+ assertNull(Paths.stripTrailingSeparator(null));
+ assertEquals("", Paths.stripTrailingSeparator(""));
+ assertEquals("a", Paths.stripTrailingSeparator("a"));
+ assertEquals("a/boo", Paths.stripTrailingSeparator("a/boo"));
+ assertEquals("a/boo", Paths.stripTrailingSeparator("a/boo/"));
+ assertEquals("a/boo", Paths.stripTrailingSeparator("a/boo//"));
+ assertEquals("a/boo", Paths.stripTrailingSeparator("a/boo///"));
+ }
+
+ @Test
+ public void testPathCompare() {
+ byte[] a = Constants.encode("afoo/bar.c");
+ byte[] b = Constants.encode("bfoo/bar.c");
+
+ assertEquals(0, compare(a, 1, a.length, 0, b, 1, b.length, 0));
+ assertEquals(-1, compare(a, 0, a.length, 0, b, 0, b.length, 0));
+ assertEquals(1, compare(b, 0, b.length, 0, a, 0, a.length, 0));
+
+ a = Constants.encode("a");
+ b = Constants.encode("aa");
+ assertEquals(-97, compare(a, 0, a.length, 0, b, 0, b.length, 0));
+ assertEquals(0, compare(a, 0, a.length, 0, b, 0, 1, 0));
+ assertEquals(0, compare(a, 0, a.length, 0, b, 1, 2, 0));
+ assertEquals(0, compareSameName(a, 0, a.length, b, 1, b.length, 0));
+ assertEquals(0, compareSameName(a, 0, a.length, b, 0, 1, 0));
+ assertEquals(-50, compareSameName(a, 0, a.length, b, 0, b.length, 0));
+ assertEquals(97, compareSameName(b, 0, b.length, a, 0, a.length, 0));
+
+ a = Constants.encode("a");
+ b = Constants.encode("a");
+ 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.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(47, compare(
+ a, 0, a.length, FileMode.TREE.getBits(),
+ b, 0, b.length, FileMode.REGULAR_FILE.getBits()));
+
+ assertEquals(0, compareSameName(
+ a, 0, a.length,
+ b, 0, b.length, FileMode.TREE.getBits()));
+ assertEquals(0, compareSameName(
+ a, 0, a.length,
+ b, 0, b.length, FileMode.REGULAR_FILE.getBits()));
+
+ a = Constants.encode("a.c");
+ b = Constants.encode("a");
+ byte[] c = Constants.encode("a0c");
+ assertEquals(-1, compare(
+ a, 0, a.length, FileMode.REGULAR_FILE.getBits(),
+ b, 0, b.length, FileMode.TREE.getBits()));
+ assertEquals(-1, compare(
+ b, 0, b.length, FileMode.TREE.getBits(),
+ c, 0, c.length, FileMode.REGULAR_FILE.getBits()));
+ }
+}