diff options
Diffstat (limited to 'org.eclipse.jgit.test/tst')
76 files changed, 5220 insertions, 2469 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 b28e26a639..52a9dfa3e2 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 @@ -700,26 +700,26 @@ public class AddCommandTest extends RepositoryTestCase { writer.print("content b"); } - ObjectInserter newObjectInserter = db.newObjectInserter(); DirCache dc = db.lockDirCache(); - DirCacheBuilder builder = dc.builder(); + try (ObjectInserter newObjectInserter = db.newObjectInserter()) { + DirCacheBuilder builder = dc.builder(); - addEntryToBuilder("b.txt", file2, newObjectInserter, builder, 0); - addEntryToBuilder("a.txt", file, newObjectInserter, builder, 1); + addEntryToBuilder("b.txt", file2, newObjectInserter, builder, 0); + addEntryToBuilder("a.txt", file, newObjectInserter, builder, 1); - try (PrintWriter writer = new PrintWriter(file, UTF_8.name())) { - writer.print("other content"); - } - addEntryToBuilder("a.txt", file, newObjectInserter, builder, 3); - - try (PrintWriter writer = new PrintWriter(file, UTF_8.name())) { - writer.print("our content"); - } - addEntryToBuilder("a.txt", file, newObjectInserter, builder, 2) - .getObjectId(); + try (PrintWriter writer = new PrintWriter(file, UTF_8.name())) { + writer.print("other content"); + } + addEntryToBuilder("a.txt", file, newObjectInserter, builder, 3); - builder.commit(); + try (PrintWriter writer = new PrintWriter(file, UTF_8.name())) { + writer.print("our content"); + } + addEntryToBuilder("a.txt", file, newObjectInserter, builder, 2) + .getObjectId(); + builder.commit(); + } assertEquals( "[a.txt, mode:100644, stage:1, content:content]" + "[a.txt, mode:100644, stage:2, content:our content]" + @@ -1132,41 +1132,42 @@ public class AddCommandTest extends RepositoryTestCase { } }; - Git git = Git.open(db.getDirectory(), executableFs); String path = "a.txt"; String path2 = "a.sh"; writeTrashFile(path, "content"); writeTrashFile(path2, "binary: content"); - git.add().addFilepattern(path).addFilepattern(path2).call(); - RevCommit commit1 = git.commit().setMessage("commit").call(); - try (TreeWalk walk = new TreeWalk(db)) { - walk.addTree(commit1.getTree()); - walk.next(); - assertEquals(path2, walk.getPathString()); - assertEquals(FileMode.EXECUTABLE_FILE, walk.getFileMode(0)); - walk.next(); - assertEquals(path, walk.getPathString()); - assertEquals(FileMode.REGULAR_FILE, walk.getFileMode(0)); + try (Git git = Git.open(db.getDirectory(), executableFs)) { + git.add().addFilepattern(path).addFilepattern(path2).call(); + RevCommit commit1 = git.commit().setMessage("commit").call(); + try (TreeWalk walk = new TreeWalk(db)) { + walk.addTree(commit1.getTree()); + walk.next(); + assertEquals(path2, walk.getPathString()); + assertEquals(FileMode.EXECUTABLE_FILE, walk.getFileMode(0)); + walk.next(); + assertEquals(path, walk.getPathString()); + assertEquals(FileMode.REGULAR_FILE, walk.getFileMode(0)); + } } - config = db.getConfig(); config.setBoolean(ConfigConstants.CONFIG_CORE_SECTION, null, ConfigConstants.CONFIG_KEY_FILEMODE, false); config.save(); - Git git2 = Git.open(db.getDirectory(), executableFs); writeTrashFile(path2, "content2"); writeTrashFile(path, "binary: content2"); - git2.add().addFilepattern(path).addFilepattern(path2).call(); - RevCommit commit2 = git2.commit().setMessage("commit2").call(); - try (TreeWalk walk = new TreeWalk(db)) { - walk.addTree(commit2.getTree()); - walk.next(); - assertEquals(path2, walk.getPathString()); - assertEquals(FileMode.EXECUTABLE_FILE, walk.getFileMode(0)); - walk.next(); - assertEquals(path, walk.getPathString()); - assertEquals(FileMode.REGULAR_FILE, walk.getFileMode(0)); + try (Git git2 = Git.open(db.getDirectory(), executableFs)) { + git2.add().addFilepattern(path).addFilepattern(path2).call(); + RevCommit commit2 = git2.commit().setMessage("commit2").call(); + try (TreeWalk walk = new TreeWalk(db)) { + walk.addTree(commit2.getTree()); + walk.next(); + assertEquals(path2, walk.getPathString()); + assertEquals(FileMode.EXECUTABLE_FILE, walk.getFileMode(0)); + walk.next(); + assertEquals(path, walk.getPathString()); + assertEquals(FileMode.REGULAR_FILE, walk.getFileMode(0)); + } } } @@ -1291,18 +1292,19 @@ public class AddCommandTest extends RepositoryTestCase { FileRepositoryBuilder nestedBuilder = new FileRepositoryBuilder(); nestedBuilder.setWorkTree(gitLinkDir); - Repository nestedRepo = nestedBuilder.build(); - nestedRepo.create(); + try (Repository nestedRepo = nestedBuilder.build()) { + nestedRepo.create(); - writeTrashFile(path, "README1.md", "content"); - writeTrashFile(path, "README2.md", "content"); + writeTrashFile(path, "README1.md", "content"); + writeTrashFile(path, "README2.md", "content"); - // Commit these changes in the subrepo - try (Git git = new Git(nestedRepo)) { - git.add().addFilepattern(".").call(); - git.commit().setMessage("subrepo commit").call(); - } catch (GitAPIException e) { - throw new RuntimeException(e); + // Commit these changes in the subrepo + try (Git git = new Git(nestedRepo)) { + git.add().addFilepattern(".").call(); + git.commit().setMessage("subrepo commit").call(); + } catch (GitAPIException e) { + throw new RuntimeException(e); + } } } } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/BlameCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/BlameCommandTest.java index 7e73084e8e..4d1375a2f5 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/BlameCommandTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/BlameCommandTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011, GitHub Inc. + * Copyright (C) 2011, 2019 GitHub Inc. * and other copyright owners as documented in the project's IP log. * * This program and the accompanying materials are made available @@ -44,6 +44,7 @@ package org.eclipse.jgit.api; 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 java.io.File; @@ -462,6 +463,39 @@ public class BlameCommandTest extends RepositoryTestCase { } @Test + public void testUnresolvedMergeConflict() throws Exception { + try (Git git = new Git(db)) { + RevCommit base = commitFile("file.txt", "Origin\n", "master"); + + RevCommit master = commitFile("file.txt", + "Change on master branch\n", "master"); + + git.checkout().setName("side").setCreateBranch(true) + .setStartPoint(base).call(); + RevCommit side = commitFile("file.txt", + "Conflicting change on side\n", "side"); + + checkoutBranch("refs/heads/master"); + MergeResult result = git.merge().include(side).call(); + + // The merge results in a conflict, which we do not resolve + assertTrue("Expected a conflict", + result.getConflicts().containsKey("file.txt")); + + BlameCommand command = new BlameCommand(db); + command.setFilePath("file.txt"); + BlameResult lines = command.call(); + + assertEquals(5, lines.getResultContents().size()); + assertNull(lines.getSourceCommit(0)); + assertEquals(master, lines.getSourceCommit(1)); + assertNull(lines.getSourceCommit(2)); + assertEquals(side, lines.getSourceCommit(3)); + assertNull(lines.getSourceCommit(4)); + } + } + + @Test public void testWhitespaceMerge() throws Exception { try (Git git = new Git(db)) { RevCommit base = commitFile("file.txt", join("0", "1", "2"), "master"); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CherryPickCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CherryPickCommandTest.java index fbc2cf67e1..76958f1ddf 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CherryPickCommandTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CherryPickCommandTest.java @@ -58,6 +58,8 @@ import org.eclipse.jgit.api.errors.GitAPIException; import org.eclipse.jgit.api.errors.JGitInternalException; import org.eclipse.jgit.api.errors.MultipleParentsNotAllowedException; import org.eclipse.jgit.dircache.DirCache; +import org.eclipse.jgit.events.ChangeRecorder; +import org.eclipse.jgit.events.ListenerHandle; import org.eclipse.jgit.junit.RepositoryTestCase; import org.eclipse.jgit.lib.ConfigConstants; import org.eclipse.jgit.lib.Constants; @@ -325,6 +327,59 @@ public class CherryPickCommandTest extends RepositoryTestCase { } @Test + public void testCherryPickConflictFiresModifiedEvent() throws Exception { + ListenerHandle listener = null; + try (Git git = new Git(db)) { + RevCommit sideCommit = prepareCherryPick(git); + ChangeRecorder recorder = new ChangeRecorder(); + listener = db.getListenerList() + .addWorkingTreeModifiedListener(recorder); + CherryPickResult result = git.cherryPick() + .include(sideCommit.getId()).call(); + assertEquals(CherryPickStatus.CONFLICTING, result.getStatus()); + recorder.assertEvent(new String[] { "a" }, ChangeRecorder.EMPTY); + } finally { + if (listener != null) { + listener.remove(); + } + } + } + + @Test + public void testCherryPickNewFileFiresModifiedEvent() throws Exception { + ListenerHandle listener = null; + try (Git git = new Git(db)) { + writeTrashFile("test.txt", "a"); + git.add().addFilepattern("test.txt").call(); + git.commit().setMessage("commit1").call(); + git.checkout().setCreateBranch(true).setName("a").call(); + + writeTrashFile("side.txt", "side"); + git.add().addFilepattern("side.txt").call(); + RevCommit side = git.commit().setMessage("side").call(); + assertNotNull(side); + + assertNotNull(git.checkout().setName(Constants.MASTER).call()); + writeTrashFile("test.txt", "b"); + assertNotNull(git.add().addFilepattern("test.txt").call()); + assertNotNull(git.commit().setMessage("commit2").call()); + + ChangeRecorder recorder = new ChangeRecorder(); + listener = db.getListenerList() + .addWorkingTreeModifiedListener(recorder); + CherryPickResult result = git.cherryPick() + .include(side.getId()).call(); + assertEquals(CherryPickStatus.OK, result.getStatus()); + recorder.assertEvent(new String[] { "side.txt" }, + ChangeRecorder.EMPTY); + } finally { + if (listener != null) { + listener.remove(); + } + } + } + + @Test public void testCherryPickOurCommitName() throws Exception { try (Git git = new Git(db)) { RevCommit sideCommit = prepareCherryPick(git); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CloneCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CloneCommandTest.java index 2270a6a8be..3224bbb784 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CloneCommandTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CloneCommandTest.java @@ -67,6 +67,7 @@ import org.eclipse.jgit.lib.ConfigConstants; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.Ref; +import org.eclipse.jgit.lib.RefUpdate; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.lib.StoredConfig; import org.eclipse.jgit.revwalk.RevBlob; @@ -96,10 +97,15 @@ public class CloneCommandTest extends RepositoryTestCase { writeTrashFile("Test.txt", "Hello world"); git.add().addFilepattern("Test.txt").call(); git.commit().setMessage("Initial commit").call(); - git.tag().setName("tag-initial").setMessage("Tag initial").call(); + Ref head = git.tag().setName("tag-initial").setMessage("Tag initial") + .call(); // create a test branch and switch to it git.checkout().setCreateBranch(true).setName("test").call(); + // create a non-standard ref + RefUpdate ru = db.updateRef("refs/meta/foo/bar"); + ru.setNewObjectId(head.getObjectId()); + ru.update(); // commit something on the test branch writeTrashFile("Test.txt", "Some change"); @@ -397,7 +403,6 @@ public class CloneCommandTest extends RepositoryTestCase { @Test public void testBareCloneRepositoryOnlyOneBranch() throws Exception { - // Same thing, but now test with bare repo File directory = createTempDirectory( "testCloneRepositoryWithBranch_bare"); CloneCommand command = Git.cloneRepository(); @@ -425,6 +430,32 @@ public class CloneCommandTest extends RepositoryTestCase { } @Test + public void testBareCloneRepositoryMirror() throws Exception { + File directory = createTempDirectory( + "testCloneRepositoryWithBranch_mirror"); + CloneCommand command = Git.cloneRepository(); + command.setBranch("refs/heads/master"); + command.setMirror(true); // implies bare repository + command.setDirectory(directory); + command.setURI(fileUri()); + Git git2 = command.call(); + addRepoToClose(git2.getRepository()); + assertNotNull(git2); + assertNotNull(git2.getRepository().resolve("tag-for-blob")); + assertNotNull(git2.getRepository().resolve("tag-initial")); + assertEquals(git2.getRepository().getFullBranch(), "refs/heads/master"); + assertEquals("refs/heads/master, refs/heads/test", allRefNames( + git2.branchList().setListMode(ListMode.ALL).call())); + assertNotNull(git2.getRepository().exactRef("refs/meta/foo/bar")); + RemoteConfig cfg = new RemoteConfig(git2.getRepository().getConfig(), + Constants.DEFAULT_REMOTE_NAME); + List<RefSpec> specs = cfg.getFetchRefSpecs(); + assertEquals(1, specs.size()); + assertEquals(new RefSpec("+refs/*:refs/*"), + specs.get(0)); + } + + @Test public void testCloneRepositoryOnlyOneTag() throws Exception { File directory = createTempDirectory("testCloneRepositoryWithBranch"); CloneCommand command = Git.cloneRepository(); @@ -646,25 +677,27 @@ public class CloneCommandTest extends RepositoryTestCase { assertEquals(sub1Head, pathStatus.getHeadId()); assertEquals(sub1Head, pathStatus.getIndexId()); - SubmoduleWalk walk = SubmoduleWalk.forIndex(git2.getRepository()); - assertTrue(walk.next()); - try (Repository clonedSub1 = walk.getRepository()) { - assertNotNull(clonedSub1); - assertEquals(new File(git2.getRepository().getWorkTree(), - walk.getPath()), clonedSub1.getWorkTree()); - assertEquals( - new File(new File(git2.getRepository().getDirectory(), - "modules"), walk.getPath()), - clonedSub1.getDirectory()); - status = new SubmoduleStatusCommand(clonedSub1); - statuses = status.call(); + try (SubmoduleWalk walk = SubmoduleWalk + .forIndex(git2.getRepository())) { + assertTrue(walk.next()); + try (Repository clonedSub1 = walk.getRepository()) { + assertNotNull(clonedSub1); + assertEquals(new File(git2.getRepository().getWorkTree(), + walk.getPath()), clonedSub1.getWorkTree()); + assertEquals( + new File(new File(git2.getRepository().getDirectory(), + "modules"), walk.getPath()), + clonedSub1.getDirectory()); + status = new SubmoduleStatusCommand(clonedSub1); + statuses = status.call(); + } + assertFalse(walk.next()); } pathStatus = statuses.get(path); assertNotNull(pathStatus); assertEquals(SubmoduleStatusType.INITIALIZED, pathStatus.getType()); assertEquals(sub2Head, pathStatus.getHeadId()); assertEquals(sub2Head, pathStatus.getIndexId()); - assertFalse(walk.next()); } @Test diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CommitAndLogCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CommitAndLogCommandTest.java index c028ca300c..2c51f7b9b7 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CommitAndLogCommandTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CommitAndLogCommandTest.java @@ -40,6 +40,7 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + package org.eclipse.jgit.api; import static java.nio.charset.StandardCharsets.UTF_8; @@ -50,14 +51,10 @@ import static org.junit.Assert.fail; import static org.junit.Assume.assumeFalse; import java.io.File; -import java.io.IOException; import java.io.PrintWriter; import org.eclipse.jgit.api.errors.GitAPIException; -import org.eclipse.jgit.api.errors.JGitInternalException; import org.eclipse.jgit.api.errors.NoMessageException; -import org.eclipse.jgit.errors.IncorrectObjectTypeException; -import org.eclipse.jgit.errors.MissingObjectException; import org.eclipse.jgit.junit.RepositoryTestCase; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.ObjectId; @@ -76,13 +73,12 @@ import org.junit.Test; */ public class CommitAndLogCommandTest extends RepositoryTestCase { @Test - public void testSomeCommits() throws JGitInternalException, IOException, - GitAPIException { - + public void testSomeCommits() throws Exception { // do 4 commits try (Git git = new Git(db)) { git.commit().setMessage("initial commit").call(); - git.commit().setMessage("second commit").setCommitter(committer).call(); + git.commit().setMessage("second commit").setCommitter(committer) + .call(); git.commit().setMessage("third commit").setAuthor(author).call(); git.commit().setMessage("fourth commit").setAuthor(author) .setCommitter(committer).call(); @@ -90,79 +86,28 @@ public class CommitAndLogCommandTest extends RepositoryTestCase { // check that all commits came in correctly PersonIdent defaultCommitter = new PersonIdent(db); - PersonIdent expectedAuthors[] = new PersonIdent[] { defaultCommitter, - committer, author, author }; + PersonIdent expectedAuthors[] = new PersonIdent[] { + defaultCommitter, committer, author, author }; PersonIdent expectedCommitters[] = new PersonIdent[] { defaultCommitter, committer, defaultCommitter, committer }; String expectedMessages[] = new String[] { "initial commit", "second commit", "third commit", "fourth commit" }; int l = expectedAuthors.length - 1; for (RevCommit c : commits) { - assertEquals(expectedAuthors[l].getName(), c.getAuthorIdent() - .getName()); - assertEquals(expectedCommitters[l].getName(), c.getCommitterIdent() - .getName()); + assertEquals(expectedAuthors[l].getName(), + c.getAuthorIdent().getName()); + assertEquals(expectedCommitters[l].getName(), + c.getCommitterIdent().getName()); assertEquals(c.getFullMessage(), expectedMessages[l]); l--; } assertEquals(l, -1); ReflogReader reader = db.getReflogReader(Constants.HEAD); - assertTrue(reader.getLastEntry().getComment().startsWith("commit:")); + assertTrue( + reader.getLastEntry().getComment().startsWith("commit:")); reader = db.getReflogReader(db.getBranch()); - assertTrue(reader.getLastEntry().getComment().startsWith("commit:")); - } - } - - @Test - public void testLogWithFilter() throws IOException, JGitInternalException, - GitAPIException { - - try (Git git = new Git(db)) { - // create first file - File file = new File(db.getWorkTree(), "a.txt"); - FileUtils.createNewFile(file); - try (PrintWriter writer = new PrintWriter(file, UTF_8.name())) { - writer.print("content1"); - } - - // First commit - a.txt file - git.add().addFilepattern("a.txt").call(); - git.commit().setMessage("commit1").setCommitter(committer).call(); - - // create second file - file = new File(db.getWorkTree(), "b.txt"); - FileUtils.createNewFile(file); - try (PrintWriter writer = new PrintWriter(file, UTF_8.name())) { - writer.print("content2"); - } - - // Second commit - b.txt file - git.add().addFilepattern("b.txt").call(); - git.commit().setMessage("commit2").setCommitter(committer).call(); - - // First log - a.txt filter - int count = 0; - for (RevCommit c : git.log().addPath("a.txt").call()) { - assertEquals("commit1", c.getFullMessage()); - count++; - } - assertEquals(1, count); - - // Second log - b.txt filter - count = 0; - for (RevCommit c : git.log().addPath("b.txt").call()) { - assertEquals("commit2", c.getFullMessage()); - count++; - } - assertEquals(1, count); - - // Third log - without filter - count = 0; - for (RevCommit c : git.log().call()) { - assertEquals(committer, c.getCommitterIdent()); - count++; - } - assertEquals(2, count); + assertTrue( + reader.getLastEntry().getComment().startsWith("commit:")); } } @@ -204,19 +149,20 @@ public class CommitAndLogCommandTest extends RepositoryTestCase { } @Test - public void testMergeEmptyBranches() throws IOException, - JGitInternalException, GitAPIException { + public void testMergeEmptyBranches() throws Exception { try (Git git = new Git(db)) { git.commit().setMessage("initial commit").call(); RefUpdate r = db.updateRef("refs/heads/side"); r.setNewObjectId(db.resolve(Constants.HEAD)); assertEquals(r.forceUpdate(), RefUpdate.Result.NEW); - RevCommit second = git.commit().setMessage("second commit").setCommitter(committer).call(); + RevCommit second = git.commit().setMessage("second commit") + .setCommitter(committer).call(); db.updateRef(Constants.HEAD).link("refs/heads/side"); - RevCommit firstSide = git.commit().setMessage("first side commit").setAuthor(author).call(); + RevCommit firstSide = git.commit().setMessage("first side commit") + .setAuthor(author).call(); - write(new File(db.getDirectory(), Constants.MERGE_HEAD), ObjectId - .toString(db.resolve("refs/heads/master"))); + write(new File(db.getDirectory(), Constants.MERGE_HEAD), + ObjectId.toString(db.resolve("refs/heads/master"))); write(new File(db.getDirectory(), Constants.MERGE_MSG), "merging"); RevCommit commit = git.commit().call(); @@ -228,8 +174,7 @@ public class CommitAndLogCommandTest extends RepositoryTestCase { } @Test - public void testAddUnstagedChanges() throws IOException, - JGitInternalException, GitAPIException { + public void testAddUnstagedChanges() throws Exception { File file = new File(db.getWorkTree(), "a.txt"); FileUtils.createNewFile(file); try (PrintWriter writer = new PrintWriter(file, UTF_8.name())) { @@ -260,7 +205,7 @@ public class CommitAndLogCommandTest extends RepositoryTestCase { } @Test - public void testModeChange() throws IOException, GitAPIException { + public void testModeChange() throws Exception { assumeFalse(System.getProperty("os.name").startsWith("Windows"));// SKIP try (Git git = new Git(db)) { // create file @@ -278,7 +223,8 @@ public class CommitAndLogCommandTest extends RepositoryTestCase { FS fs = db.getFS(); fs.setExecute(file, true); git.add().addFilepattern("a.txt").call(); - git.commit().setMessage("mode change").setCommitter(committer).call(); + git.commit().setMessage("mode change").setCommitter(committer) + .call(); // pure mode change should be committable with -o option fs.setExecute(file, false); @@ -289,34 +235,32 @@ public class CommitAndLogCommandTest extends RepositoryTestCase { } @Test - public void testCommitRange() throws GitAPIException, - JGitInternalException, MissingObjectException, - IncorrectObjectTypeException { + public void testCommitRange() throws Exception { // do 4 commits and set the range to the second and fourth one try (Git git = new Git(db)) { git.commit().setMessage("first commit").call(); RevCommit second = git.commit().setMessage("second commit") .setCommitter(committer).call(); git.commit().setMessage("third commit").setAuthor(author).call(); - RevCommit last = git.commit().setMessage("fourth commit").setAuthor( - author) - .setCommitter(committer).call(); - Iterable<RevCommit> commits = git.log().addRange(second.getId(), - last.getId()).call(); + RevCommit last = git.commit().setMessage("fourth commit") + .setAuthor(author).setCommitter(committer).call(); + Iterable<RevCommit> commits = git.log() + .addRange(second.getId(), last.getId()).call(); // check that we have the third and fourth commit PersonIdent defaultCommitter = new PersonIdent(db); - PersonIdent expectedAuthors[] = new PersonIdent[] { author, author }; + PersonIdent expectedAuthors[] = new PersonIdent[] { author, + author }; PersonIdent expectedCommitters[] = new PersonIdent[] { defaultCommitter, committer }; String expectedMessages[] = new String[] { "third commit", "fourth commit" }; int l = expectedAuthors.length - 1; for (RevCommit c : commits) { - assertEquals(expectedAuthors[l].getName(), c.getAuthorIdent() - .getName()); - assertEquals(expectedCommitters[l].getName(), c.getCommitterIdent() - .getName()); + assertEquals(expectedAuthors[l].getName(), + c.getAuthorIdent().getName()); + assertEquals(expectedCommitters[l].getName(), + c.getCommitterIdent().getName()); assertEquals(c.getFullMessage(), expectedMessages[l]); l--; } @@ -325,8 +269,7 @@ public class CommitAndLogCommandTest extends RepositoryTestCase { } @Test - public void testCommitAmend() throws JGitInternalException, IOException, - GitAPIException { + public void testCommitAmend() throws Exception { try (Git git = new Git(db)) { git.commit().setMessage("first comit").call(); // typo git.commit().setAmend(true).setMessage("first commit").call(); @@ -348,15 +291,14 @@ public class CommitAndLogCommandTest extends RepositoryTestCase { } @Test - public void testInsertChangeId() throws JGitInternalException, - GitAPIException { + public void testInsertChangeId() throws Exception { try (Git git = new Git(db)) { String messageHeader = "Some header line\n\nSome detail explanation\n"; String changeIdTemplate = "\nChange-Id: I" + ObjectId.zeroId().getName() + "\n"; String messageFooter = "Some foooter lines\nAnother footer line\n"; - RevCommit commit = git.commit().setMessage( - messageHeader + messageFooter) + RevCommit commit = git.commit() + .setMessage(messageHeader + messageFooter) .setInsertChangeId(true).call(); // we should find a real change id (at the end of the file) byte[] chars = commit.getFullMessage().getBytes(UTF_8); @@ -364,11 +306,12 @@ public class CommitAndLogCommandTest extends RepositoryTestCase { String lastLine = RawParseUtils.decode(chars, lastLineBegin + 1, chars.length); assertTrue(lastLine.contains("Change-Id:")); - assertFalse(lastLine.contains( - "Change-Id: I" + ObjectId.zeroId().getName())); + assertFalse(lastLine + .contains("Change-Id: I" + ObjectId.zeroId().getName())); - commit = git.commit().setMessage( - messageHeader + changeIdTemplate + messageFooter) + commit = git.commit() + .setMessage( + messageHeader + changeIdTemplate + messageFooter) .setInsertChangeId(true).call(); // we should find a real change id (in the line as dictated by the // template) @@ -383,11 +326,12 @@ public class CommitAndLogCommandTest extends RepositoryTestCase { String line = RawParseUtils.decode(chars, lineStart, lineEnd); assertTrue(line.contains("Change-Id:")); - assertFalse(line.contains( - "Change-Id: I" + ObjectId.zeroId().getName())); + assertFalse(line + .contains("Change-Id: I" + ObjectId.zeroId().getName())); - commit = git.commit().setMessage( - messageHeader + changeIdTemplate + messageFooter) + commit = git.commit() + .setMessage( + messageHeader + changeIdTemplate + messageFooter) .setInsertChangeId(false).call(); // we should find the untouched template chars = commit.getFullMessage().getBytes(UTF_8); @@ -400,8 +344,8 @@ public class CommitAndLogCommandTest extends RepositoryTestCase { line = RawParseUtils.decode(chars, lineStart, lineEnd); - assertTrue(commit.getFullMessage().contains( - "Change-Id: I" + ObjectId.zeroId().getName())); + assertTrue(commit.getFullMessage() + .contains("Change-Id: I" + ObjectId.zeroId().getName())); } } } 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 3bde0eb33f..b5661e8440 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 @@ -148,9 +148,10 @@ public class CommitCommandTest extends RepositoryTestCase { writeTrashFile(path, "content"); git.add().addFilepattern(path).call(); RevCommit commit1 = git.commit().setMessage("commit").call(); - TreeWalk walk = TreeWalk.forPath(db, path, commit1.getTree()); - assertNotNull(walk); - assertEquals(FileMode.EXECUTABLE_FILE, walk.getFileMode(0)); + try (TreeWalk walk = TreeWalk.forPath(db, path, commit1.getTree())) { + assertNotNull(walk); + assertEquals(FileMode.EXECUTABLE_FILE, walk.getFileMode(0)); + } FS nonExecutableFs = new FS() { @@ -204,9 +205,10 @@ public class CommitCommandTest extends RepositoryTestCase { writeTrashFile(path, "content2"); RevCommit commit2 = git2.commit().setOnly(path).setMessage("commit2") .call(); - walk = TreeWalk.forPath(db, path, commit2.getTree()); - assertNotNull(walk); - assertEquals(FileMode.EXECUTABLE_FILE, walk.getFileMode(0)); + try (TreeWalk walk = TreeWalk.forPath(db, path, commit2.getTree())) { + assertNotNull(walk); + assertEquals(FileMode.EXECUTABLE_FILE, walk.getFileMode(0)); + } } @Test @@ -225,15 +227,16 @@ public class CommitCommandTest extends RepositoryTestCase { assertNotNull(repo); addRepoToClose(repo); - SubmoduleWalk generator = SubmoduleWalk.forIndex(db); - assertTrue(generator.next()); - assertEquals(path, generator.getPath()); - assertEquals(commit, generator.getObjectId()); - assertEquals(uri, generator.getModulesUrl()); - assertEquals(path, generator.getModulesPath()); - assertEquals(uri, generator.getConfigUrl()); - try (Repository subModRepo = generator.getRepository()) { - assertNotNull(subModRepo); + try (SubmoduleWalk generator = SubmoduleWalk.forIndex(db)) { + assertTrue(generator.next()); + assertEquals(path, generator.getPath()); + assertEquals(commit, generator.getObjectId()); + assertEquals(uri, generator.getModulesUrl()); + assertEquals(path, generator.getModulesPath()); + assertEquals(uri, generator.getConfigUrl()); + try (Repository subModRepo = generator.getRepository()) { + assertNotNull(subModRepo); + } } assertEquals(commit, repo.resolve(Constants.HEAD)); @@ -275,15 +278,16 @@ public class CommitCommandTest extends RepositoryTestCase { assertNotNull(repo); addRepoToClose(repo); - SubmoduleWalk generator = SubmoduleWalk.forIndex(db); - assertTrue(generator.next()); - assertEquals(path, generator.getPath()); - assertEquals(commit2, generator.getObjectId()); - assertEquals(uri, generator.getModulesUrl()); - assertEquals(path, generator.getModulesPath()); - assertEquals(uri, generator.getConfigUrl()); - try (Repository subModRepo = generator.getRepository()) { - assertNotNull(subModRepo); + try (SubmoduleWalk generator = SubmoduleWalk.forIndex(db)) { + assertTrue(generator.next()); + assertEquals(path, generator.getPath()); + assertEquals(commit2, generator.getObjectId()); + assertEquals(uri, generator.getModulesUrl()); + assertEquals(path, generator.getModulesPath()); + assertEquals(uri, generator.getConfigUrl()); + try (Repository subModRepo = generator.getRepository()) { + assertNotNull(subModRepo); + } } assertEquals(commit2, repo.resolve(Constants.HEAD)); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/EolRepositoryTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/EolRepositoryTest.java index 47806cb99d..d0dfd1ab92 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/EolRepositoryTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/EolRepositoryTest.java @@ -142,8 +142,6 @@ public class EolRepositoryTest extends RepositoryTestCase { protected String CONTENT_MIXED; - private TreeWalk walk; - /** work tree root .gitattributes */ private File dotGitattributes; @@ -689,27 +687,25 @@ public class EolRepositoryTest extends RepositoryTestCase { private void collectRepositoryState() throws Exception { dirCache = db.readDirCache(); - walk = beginWalk(); - if (dotGitattributes != null) - collectEntryContentAndAttributes(F, ".gitattributes", null); - collectEntryContentAndAttributes(F, fileCRLF.getName(), entryCRLF); - collectEntryContentAndAttributes(F, fileLF.getName(), entryLF); - collectEntryContentAndAttributes(F, fileMixed.getName(), entryMixed); - endWalk(); - } - - private TreeWalk beginWalk() throws Exception { - TreeWalk newWalk = new TreeWalk(db); - newWalk.addTree(new FileTreeIterator(db)); - newWalk.addTree(new DirCacheIterator(db.readDirCache())); - return newWalk; - } - - private void endWalk() throws IOException { - assertFalse("Not all files tested", walk.next()); + try (TreeWalk walk = new TreeWalk(db)) { + walk.addTree(new FileTreeIterator(db)); + walk.addTree(new DirCacheIterator(db.readDirCache())); + if (dotGitattributes != null) { + collectEntryContentAndAttributes(walk, F, ".gitattributes", + null); + } + collectEntryContentAndAttributes(walk, F, fileCRLF.getName(), + entryCRLF); + collectEntryContentAndAttributes(walk, F, fileLF.getName(), + entryLF); + collectEntryContentAndAttributes(walk, F, fileMixed.getName(), + entryMixed); + assertFalse("Not all files tested", walk.next()); + } } - private void collectEntryContentAndAttributes(FileMode type, String pathName, + private void collectEntryContentAndAttributes(TreeWalk walk, FileMode type, + String pathName, ActualEntry e) throws IOException { assertTrue("walk has entry", walk.next()); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/FetchAndPullCommandsRecurseSubmodulesTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/FetchAndPullCommandsRecurseSubmodulesTest.java index 73a705b252..08ded559f5 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/FetchAndPullCommandsRecurseSubmodulesTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/FetchAndPullCommandsRecurseSubmodulesTest.java @@ -343,19 +343,22 @@ public class FetchAndPullCommandsRecurseSubmodulesTest extends RepositoryTestCas private void assertSubmoduleFetchHeads(ObjectId expectedHead1, ObjectId expectedHead2) throws Exception { + Object newHead1 = null; + ObjectId newHead2 = null; try (SubmoduleWalk walk = SubmoduleWalk .forIndex(git2.getRepository())) { assertTrue(walk.next()); - Repository r = walk.getRepository(); - ObjectId newHead1 = r.resolve(Constants.FETCH_HEAD); - ObjectId newHead2; - try (SubmoduleWalk walk2 = SubmoduleWalk.forIndex(r)) { - assertTrue(walk2.next()); - newHead2 = walk2.getRepository().resolve(Constants.FETCH_HEAD); + try (Repository r = walk.getRepository()) { + newHead1 = r.resolve(Constants.FETCH_HEAD); + try (SubmoduleWalk walk2 = SubmoduleWalk.forIndex(r)) { + assertTrue(walk2.next()); + try (Repository r2 = walk2.getRepository()) { + newHead2 = r2.resolve(Constants.FETCH_HEAD); + } + } } - - assertEquals(expectedHead1, newHead1); - assertEquals(expectedHead2, newHead2); } + assertEquals(expectedHead1, newHead1); + assertEquals(expectedHead2, newHead2); } } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/LogFilterTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/LogFilterTest.java new file mode 100644 index 0000000000..988ca58906 --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/LogFilterTest.java @@ -0,0 +1,221 @@ +/* + * Copyright (C) 2019, John Tipper <John_Tipper@hotmail.com> + * 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.api; + +import static java.nio.charset.StandardCharsets.UTF_8; +import static org.junit.Assert.assertEquals; + +import java.io.File; +import java.io.PrintWriter; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Iterator; + +import org.eclipse.jgit.junit.RepositoryTestCase; +import org.eclipse.jgit.revwalk.RevCommit; +import org.eclipse.jgit.util.FileUtils; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +/** + * Testing the log command with include and exclude filters + */ +public class LogFilterTest extends RepositoryTestCase { + private Git git; + + @Before + public void setup() throws Exception { + super.setUp(); + git = new Git(db); + + // create first file + File file = new File(db.getWorkTree(), "a.txt"); + FileUtils.createNewFile(file); + try (PrintWriter writer = new PrintWriter(file, UTF_8.name())) { + writer.print("content1"); + } + + // First commit - a.txt file + git.add().addFilepattern("a.txt").call(); + git.commit().setMessage("commit1").setCommitter(committer).call(); + + // create second file + file = new File(db.getWorkTree(), "b.txt"); + FileUtils.createNewFile(file); + try (PrintWriter writer = new PrintWriter(file, UTF_8.name())) { + writer.print("content2"); + } + + // Second commit - b.txt file + git.add().addFilepattern("b.txt").call(); + git.commit().setMessage("commit2").setCommitter(committer).call(); + + // create third file + Path includeSubdir = Paths.get(db.getWorkTree().toString(), + "subdir-include"); + includeSubdir.toFile().mkdirs(); + file = Paths.get(includeSubdir.toString(), "c.txt").toFile(); + FileUtils.createNewFile(file); + try (PrintWriter writer = new PrintWriter(file, UTF_8.name())) { + writer.print("content3"); + } + + // Third commit - c.txt file + git.add().addFilepattern("subdir-include").call(); + git.commit().setMessage("commit3").setCommitter(committer).call(); + + // create fourth file + Path excludeSubdir = Paths.get(db.getWorkTree().toString(), + "subdir-exclude"); + excludeSubdir.toFile().mkdirs(); + file = Paths.get(excludeSubdir.toString(), "d.txt").toFile(); + FileUtils.createNewFile(file); + try (PrintWriter writer = new PrintWriter(file, UTF_8.name())) { + writer.print("content4"); + } + + // Fourth commit - d.txt file + git.add().addFilepattern("subdir-exclude").call(); + git.commit().setMessage("commit4").setCommitter(committer).call(); + } + + @After + @Override + public void tearDown() throws Exception { + git.close(); + super.tearDown(); + } + + @Test + public void testLogWithFilterCanDistinguishFilesByPath() throws Exception { + int count = 0; + for (RevCommit c : git.log().addPath("a.txt").call()) { + assertEquals("commit1", c.getFullMessage()); + count++; + } + assertEquals(1, count); + + count = 0; + for (RevCommit c : git.log().addPath("b.txt").call()) { + assertEquals("commit2", c.getFullMessage()); + count++; + } + assertEquals(1, count); + } + + @Test + public void testLogWithFilterCanIncludeFilesInDirectory() throws Exception { + int count = 0; + for (RevCommit c : git.log().addPath("subdir-include").call()) { + assertEquals("commit3", c.getFullMessage()); + count++; + } + assertEquals(1, count); + } + + @Test + public void testLogWithFilterCanExcludeFilesInDirectory() throws Exception { + int count = 0; + Iterator it = git.log().excludePath("subdir-exclude").call().iterator(); + while (it.hasNext()) { + it.next(); + count++; + } + // of all the commits, we expect to filter out only d.txt + assertEquals(3, count); + } + + @Test + public void testLogWithoutFilter() throws Exception { + int count = 0; + for (RevCommit c : git.log().call()) { + assertEquals(committer, c.getCommitterIdent()); + count++; + } + assertEquals(4, count); + } + + @Test + public void testLogWithFilterCanExcludeAndIncludeFilesInDifferentDirectories() + throws Exception { + int count = 0; + Iterator it = git.log().addPath("subdir-include") + .excludePath("subdir-exclude").call().iterator(); + while (it.hasNext()) { + it.next(); + count++; + } + // we expect to include c.txt + assertEquals(1, count); + } + + @Test + public void testLogWithFilterExcludeAndIncludeSameFileIncludesNothing() + throws Exception { + int count = 0; + Iterator it = git.log().addPath("subdir-exclude") + .excludePath("subdir-exclude").call().iterator(); + + while (it.hasNext()) { + it.next(); + count++; + } + // we expect the exclude to trump everything + assertEquals(0, count); + } + + @Test + public void testLogWithFilterCanExcludeFileAndDirectory() throws Exception { + int count = 0; + Iterator it = git.log().excludePath("b.txt") + .excludePath("subdir-exclude").call().iterator(); + + while (it.hasNext()) { + it.next(); + count++; + } + // we expect a.txt and c.txt + assertEquals(2, count); + } +} diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/RebaseCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/RebaseCommandTest.java index 4401bcedb3..7c8ec23848 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/RebaseCommandTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/RebaseCommandTest.java @@ -57,12 +57,9 @@ import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader; -import java.util.ArrayList; import java.util.Collections; -import java.util.HashSet; import java.util.Iterator; import java.util.List; -import java.util.Set; import org.eclipse.jgit.api.MergeResult.MergeStatus; import org.eclipse.jgit.api.RebaseCommand.InteractiveHandler; @@ -78,6 +75,7 @@ import org.eclipse.jgit.errors.AmbiguousObjectException; import org.eclipse.jgit.errors.IllegalTodoFileModification; import org.eclipse.jgit.errors.IncorrectObjectTypeException; import org.eclipse.jgit.errors.MissingObjectException; +import org.eclipse.jgit.events.ChangeRecorder; import org.eclipse.jgit.events.ListenerHandle; import org.eclipse.jgit.junit.RepositoryTestCase; import org.eclipse.jgit.lib.AbbreviatedObjectId; @@ -2014,10 +2012,9 @@ public class RebaseCommandTest extends RepositoryTestCase { checkoutBranch("refs/heads/topic"); writeTrashFile("sub/file0", "unstaged modified file0"); - Set<String> modifiedFiles = new HashSet<>(); + ChangeRecorder recorder = new ChangeRecorder(); ListenerHandle handle = db.getListenerList() - .addWorkingTreeModifiedListener( - event -> modifiedFiles.addAll(event.getModified())); + .addWorkingTreeModifiedListener(recorder); try { // rebase assertEquals(Status.OK, git.rebase() @@ -2035,9 +2032,8 @@ public class RebaseCommandTest extends RepositoryTestCase { + "[sub/file0, mode:100644, content:file0]", indexState(CONTENT)); assertEquals(RepositoryState.SAFE, db.getRepositoryState()); - List<String> modified = new ArrayList<>(modifiedFiles); - Collections.sort(modified); - assertEquals("[file1, sub/file0]", modified.toString()); + recorder.assertEvent(new String[] { "file1", "file2", "sub/file0" }, + new String[0]); } @Test @@ -2136,10 +2132,12 @@ public class RebaseCommandTest extends RepositoryTestCase { private List<DiffEntry> getStashedDiff() throws AmbiguousObjectException, IncorrectObjectTypeException, IOException, MissingObjectException { ObjectId stashId = db.resolve("stash@{0}"); - RevWalk revWalk = new RevWalk(db); - RevCommit stashCommit = revWalk.parseCommit(stashId); - List<DiffEntry> diffs = diffWorkingAgainstHead(stashCommit, revWalk); - return diffs; + try (RevWalk revWalk = new RevWalk(db)) { + RevCommit stashCommit = revWalk.parseCommit(stashId); + List<DiffEntry> diffs = diffWorkingAgainstHead(stashCommit, + revWalk); + return diffs; + } } private TreeWalk createTreeWalk() { diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/attributes/AttributesHandlerTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/attributes/AttributesHandlerTest.java index 5868482c88..adc64d227e 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/attributes/AttributesHandlerTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/attributes/AttributesHandlerTest.java @@ -69,83 +69,90 @@ public class AttributesHandlerTest extends RepositoryTestCase { private static final FileMode F = FileMode.REGULAR_FILE; - private TreeWalk walk; - @Test public void testExpandNonMacro1() throws Exception { setupRepo(null, null, null, "*.txt text"); - walk = beginWalk(); - assertIteration(D, "sub"); - assertIteration(F, "sub/.gitattributes"); - assertIteration(F, "sub/a.txt", attrs("text")); - endWalk(); + try (TreeWalk walk = beginWalk()) { + assertIteration(walk, D, "sub"); + assertIteration(walk, F, "sub/.gitattributes"); + assertIteration(walk, F, "sub/a.txt", attrs("text")); + assertFalse("Not all files tested", walk.next()); + } } @Test public void testExpandNonMacro2() throws Exception { setupRepo(null, null, null, "*.txt -text"); - walk = beginWalk(); - assertIteration(D, "sub"); - assertIteration(F, "sub/.gitattributes"); - assertIteration(F, "sub/a.txt", attrs("-text")); - endWalk(); + try (TreeWalk walk = beginWalk()) { + assertIteration(walk, D, "sub"); + assertIteration(walk, F, "sub/.gitattributes"); + assertIteration(walk, F, "sub/a.txt", attrs("-text")); + assertFalse("Not all files tested", walk.next()); + } } @Test public void testExpandNonMacro3() throws Exception { setupRepo(null, null, null, "*.txt !text"); - walk = beginWalk(); - assertIteration(D, "sub"); - assertIteration(F, "sub/.gitattributes"); - assertIteration(F, "sub/a.txt", attrs("")); - endWalk(); + try (TreeWalk walk = beginWalk()) { + assertIteration(walk, D, "sub"); + assertIteration(walk, F, "sub/.gitattributes"); + assertIteration(walk, F, "sub/a.txt", attrs("")); + assertFalse("Not all files tested", walk.next()); + } } @Test public void testExpandNonMacro4() throws Exception { setupRepo(null, null, null, "*.txt text=auto"); - walk = beginWalk(); - assertIteration(D, "sub"); - assertIteration(F, "sub/.gitattributes"); - assertIteration(F, "sub/a.txt", attrs("text=auto")); - endWalk(); + try (TreeWalk walk = beginWalk()) { + assertIteration(walk, D, "sub"); + assertIteration(walk, F, "sub/.gitattributes"); + assertIteration(walk, F, "sub/a.txt", attrs("text=auto")); + assertFalse("Not all files tested", walk.next()); + } } @Test public void testExpandBuiltInMacro1() throws Exception { setupRepo(null, null, null, "*.txt binary"); - walk = beginWalk(); - assertIteration(D, "sub"); - assertIteration(F, "sub/.gitattributes"); - assertIteration(F, "sub/a.txt", attrs("binary -diff -merge -text")); - endWalk(); + try (TreeWalk walk = beginWalk()) { + assertIteration(walk, D, "sub"); + assertIteration(walk, F, "sub/.gitattributes"); + assertIteration(walk, F, "sub/a.txt", + attrs("binary -diff -merge -text")); + assertFalse("Not all files tested", walk.next()); + } } @Test public void testExpandBuiltInMacro2() throws Exception { setupRepo(null, null, null, "*.txt -binary"); - walk = beginWalk(); - assertIteration(D, "sub"); - assertIteration(F, "sub/.gitattributes"); - assertIteration(F, "sub/a.txt", attrs("-binary diff merge text")); - endWalk(); + try (TreeWalk walk = beginWalk()) { + assertIteration(walk, D, "sub"); + assertIteration(walk, F, "sub/.gitattributes"); + assertIteration(walk, F, "sub/a.txt", + attrs("-binary diff merge text")); + assertFalse("Not all files tested", walk.next()); + } } @Test public void testExpandBuiltInMacro3() throws Exception { setupRepo(null, null, null, "*.txt !binary"); - walk = beginWalk(); - assertIteration(D, "sub"); - assertIteration(F, "sub/.gitattributes"); - assertIteration(F, "sub/a.txt", attrs("")); - endWalk(); + try (TreeWalk walk = beginWalk()) { + assertIteration(walk, D, "sub"); + assertIteration(walk, F, "sub/.gitattributes"); + assertIteration(walk, F, "sub/a.txt", attrs("")); + assertFalse("Not all files tested", walk.next()); + } } @Test @@ -153,44 +160,48 @@ public class AttributesHandlerTest extends RepositoryTestCase { setupRepo( "[attr]foo a -b !c d=e", null, null, "*.txt foo"); - walk = beginWalk(); - assertIteration(D, "sub"); - assertIteration(F, "sub/.gitattributes"); - assertIteration(F, "sub/a.txt", attrs("foo a -b d=e")); - endWalk(); + try (TreeWalk walk = beginWalk()) { + assertIteration(walk, D, "sub"); + assertIteration(walk, F, "sub/.gitattributes"); + assertIteration(walk, F, "sub/a.txt", attrs("foo a -b d=e")); + assertFalse("Not all files tested", walk.next()); + } } @Test public void testCustomGlobalMacro2() throws Exception { setupRepo("[attr]foo a -b !c d=e", null, null, "*.txt -foo"); - walk = beginWalk(); - assertIteration(D, "sub"); - assertIteration(F, "sub/.gitattributes"); - assertIteration(F, "sub/a.txt", attrs("-foo -a b d=e")); - endWalk(); + try (TreeWalk walk = beginWalk()) { + assertIteration(walk, D, "sub"); + assertIteration(walk, F, "sub/.gitattributes"); + assertIteration(walk, F, "sub/a.txt", attrs("-foo -a b d=e")); + assertFalse("Not all files tested", walk.next()); + } } @Test public void testCustomGlobalMacro3() throws Exception { setupRepo("[attr]foo a -b !c d=e", null, null, "*.txt !foo"); - walk = beginWalk(); - assertIteration(D, "sub"); - assertIteration(F, "sub/.gitattributes"); - assertIteration(F, "sub/a.txt", attrs("")); - endWalk(); + try (TreeWalk walk = beginWalk()) { + assertIteration(walk, D, "sub"); + assertIteration(walk, F, "sub/.gitattributes"); + assertIteration(walk, F, "sub/a.txt", attrs("")); + assertFalse("Not all files tested", walk.next()); + } } @Test public void testCustomGlobalMacro4() throws Exception { setupRepo("[attr]foo a -b !c d=e", null, null, "*.txt foo=bar"); - walk = beginWalk(); - assertIteration(D, "sub"); - assertIteration(F, "sub/.gitattributes"); - assertIteration(F, "sub/a.txt", attrs("foo=bar a -b d=bar")); - endWalk(); + try (TreeWalk walk = beginWalk()) { + assertIteration(walk, D, "sub"); + assertIteration(walk, F, "sub/.gitattributes"); + assertIteration(walk, F, "sub/a.txt", attrs("foo=bar a -b d=bar")); + assertFalse("Not all files tested", walk.next()); + } } @Test @@ -198,11 +209,12 @@ public class AttributesHandlerTest extends RepositoryTestCase { setupRepo("[attr]foo bar1", "[attr]foo bar2", null, "*.txt foo"); - walk = beginWalk(); - assertIteration(D, "sub"); - assertIteration(F, "sub/.gitattributes"); - assertIteration(F, "sub/a.txt", attrs("foo bar2")); - endWalk(); + try (TreeWalk walk = beginWalk()) { + assertIteration(walk, D, "sub"); + assertIteration(walk, F, "sub/.gitattributes"); + assertIteration(walk, F, "sub/a.txt", attrs("foo bar2")); + assertFalse("Not all files tested", walk.next()); + } } @Test @@ -211,12 +223,13 @@ public class AttributesHandlerTest extends RepositoryTestCase { null, "[attr]foo bar3", "*.txt foo"); - walk = beginWalk(); - assertIteration(F, ".gitattributes"); - assertIteration(D, "sub"); - assertIteration(F, "sub/.gitattributes"); - assertIteration(F, "sub/a.txt", attrs("foo bar3")); - endWalk(); + try (TreeWalk walk = beginWalk()) { + assertIteration(walk, F, ".gitattributes"); + assertIteration(walk, D, "sub"); + assertIteration(walk, F, "sub/.gitattributes"); + assertIteration(walk, F, "sub/a.txt", attrs("foo bar3")); + assertFalse("Not all files tested", walk.next()); + } } @Test @@ -224,12 +237,13 @@ public class AttributesHandlerTest extends RepositoryTestCase { setupRepo("[attr]foo bar1", "[attr]foo bar2", "[attr]foo bar3", "*.txt foo"); - walk = beginWalk(); - assertIteration(F, ".gitattributes"); - assertIteration(D, "sub"); - assertIteration(F, "sub/.gitattributes"); - assertIteration(F, "sub/a.txt", attrs("foo bar2")); - endWalk(); + try (TreeWalk walk = beginWalk()) { + assertIteration(walk, F, ".gitattributes"); + assertIteration(walk, D, "sub"); + assertIteration(walk, F, "sub/.gitattributes"); + assertIteration(walk, F, "sub/a.txt", attrs("foo bar2")); + assertFalse("Not all files tested", walk.next()); + } } @Test @@ -238,11 +252,12 @@ public class AttributesHandlerTest extends RepositoryTestCase { "[attr]foo x bar -foo", null, null, "*.txt foo"); - walk = beginWalk(); - assertIteration(D, "sub"); - assertIteration(F, "sub/.gitattributes"); - assertIteration(F, "sub/a.txt", attrs("foo x bar")); - endWalk(); + try (TreeWalk walk = beginWalk()) { + assertIteration(walk, D, "sub"); + assertIteration(walk, F, "sub/.gitattributes"); + assertIteration(walk, F, "sub/a.txt", attrs("foo x bar")); + assertFalse("Not all files tested", walk.next()); + } } @Test @@ -250,11 +265,12 @@ public class AttributesHandlerTest extends RepositoryTestCase { setupRepo( "[attr]foo x -bar\n[attr]bar y -foo", null, null, "*.txt foo"); - walk = beginWalk(); - assertIteration(D, "sub"); - assertIteration(F, "sub/.gitattributes"); - assertIteration(F, "sub/a.txt", attrs("foo x -bar -y")); - endWalk(); + try (TreeWalk walk = beginWalk()) { + assertIteration(walk, D, "sub"); + assertIteration(walk, F, "sub/.gitattributes"); + assertIteration(walk, F, "sub/a.txt", attrs("foo x -bar -y")); + assertFalse("Not all files tested", walk.next()); + } } @Test @@ -266,23 +282,30 @@ public class AttributesHandlerTest extends RepositoryTestCase { // apply to any of the files here. It would match for a // further subdirectory sub/sub. The sub/ rules must match // only for directories. - walk = beginWalk(); - assertIteration(F, ".gitattributes"); - assertIteration(D, "sub", attrs("global")); - assertIteration(F, "sub/.gitattributes", attrs("init top_sub")); - assertIteration(F, "sub/a.txt", attrs("init foo top top_sub")); - endWalk(); + try (TreeWalk walk = beginWalk()) { + assertIteration(walk, F, ".gitattributes"); + assertIteration(walk, D, "sub", attrs("global")); + assertIteration(walk, F, "sub/.gitattributes", + attrs("init top_sub")); + assertIteration(walk, F, "sub/a.txt", + attrs("init foo top top_sub")); + assertFalse("Not all files tested", walk.next()); + } // All right, let's see that they *do* apply in sub/sub: writeTrashFile("sub/sub/b.txt", "b"); - walk = beginWalk(); - assertIteration(F, ".gitattributes"); - assertIteration(D, "sub", attrs("global")); - assertIteration(F, "sub/.gitattributes", attrs("init top_sub")); - assertIteration(F, "sub/a.txt", attrs("init foo top top_sub")); - assertIteration(D, "sub/sub", attrs("init subsub2 top_sub global")); - assertIteration(F, "sub/sub/b.txt", - attrs("init foo subsub top top_sub")); - endWalk(); + try (TreeWalk walk = beginWalk()) { + assertIteration(walk, F, ".gitattributes"); + assertIteration(walk, D, "sub", attrs("global")); + assertIteration(walk, F, "sub/.gitattributes", + attrs("init top_sub")); + assertIteration(walk, F, "sub/a.txt", + attrs("init foo top top_sub")); + assertIteration(walk, D, "sub/sub", + attrs("init subsub2 top_sub global")); + assertIteration(walk, F, "sub/sub/b.txt", + attrs("init foo subsub top top_sub")); + assertFalse("Not all files tested", walk.next()); + } } @Test @@ -293,16 +316,17 @@ public class AttributesHandlerTest extends RepositoryTestCase { writeTrashFile("sub/b.jar", "bj"); writeTrashFile("sub/b.xml", "bx"); // On foo.xml/bar.jar we must not have 'xml' - walk = beginWalk(); - assertIteration(F, ".gitattributes"); - assertIteration(D, "foo.xml", attrs("xml")); - assertIteration(F, "foo.xml/bar.jar", attrs("jar")); - assertIteration(F, "foo.xml/bar.xml", attrs("xml")); - assertIteration(D, "sub"); - assertIteration(F, "sub/a.txt"); - assertIteration(F, "sub/b.jar", attrs("jar")); - assertIteration(F, "sub/b.xml", attrs("xml")); - endWalk(); + try (TreeWalk walk = beginWalk()) { + assertIteration(walk, F, ".gitattributes"); + assertIteration(walk, D, "foo.xml", attrs("xml")); + assertIteration(walk, F, "foo.xml/bar.jar", attrs("jar")); + assertIteration(walk, F, "foo.xml/bar.xml", attrs("xml")); + assertIteration(walk, D, "sub"); + assertIteration(walk, F, "sub/a.txt"); + assertIteration(walk, F, "sub/b.jar", attrs("jar")); + assertIteration(walk, F, "sub/b.xml", attrs("xml")); + assertFalse("Not all files tested", walk.next()); + } } @Test @@ -314,18 +338,19 @@ public class AttributesHandlerTest extends RepositoryTestCase { writeTrashFile("sub/b.jar", "bj"); writeTrashFile("sub/b.xml", "bx"); writeTrashFile("sub/foo/b.jar", "bf"); - walk = beginWalk(); - assertIteration(F, ".gitattributes"); - assertIteration(D, "foo", attrs("xml")); - assertIteration(F, "foo/bar.jar", attrs("jar")); - assertIteration(F, "foo/bar.xml"); - assertIteration(D, "sub"); - assertIteration(F, "sub/a.txt"); - assertIteration(F, "sub/b.jar", attrs("jar")); - assertIteration(F, "sub/b.xml"); - assertIteration(D, "sub/foo", attrs("sub xml")); - assertIteration(F, "sub/foo/b.jar", attrs("jar")); - endWalk(); + try (TreeWalk walk = beginWalk()) { + assertIteration(walk, F, ".gitattributes"); + assertIteration(walk, D, "foo", attrs("xml")); + assertIteration(walk, F, "foo/bar.jar", attrs("jar")); + assertIteration(walk, F, "foo/bar.xml"); + assertIteration(walk, D, "sub"); + assertIteration(walk, F, "sub/a.txt"); + assertIteration(walk, F, "sub/b.jar", attrs("jar")); + assertIteration(walk, F, "sub/b.xml"); + assertIteration(walk, D, "sub/foo", attrs("sub xml")); + assertIteration(walk, F, "sub/foo/b.jar", attrs("jar")); + assertFalse("Not all files tested", walk.next()); + } } @Test @@ -337,18 +362,19 @@ public class AttributesHandlerTest extends RepositoryTestCase { writeTrashFile("sub/b.xml", "bx"); writeTrashFile("sub/foo/b.jar", "bf"); // On foo.xml/bar.jar we must not have 'xml' - walk = beginWalk(); - assertIteration(F, ".gitattributes"); - assertIteration(D, "foo"); - assertIteration(F, "foo/bar.jar", attrs("jar xml")); - assertIteration(F, "foo/bar.xml", attrs("xml")); - assertIteration(D, "sub"); - assertIteration(F, "sub/a.txt"); - assertIteration(F, "sub/b.jar", attrs("jar")); - assertIteration(F, "sub/b.xml"); - assertIteration(D, "sub/foo"); - assertIteration(F, "sub/foo/b.jar", attrs("jar")); - endWalk(); + try (TreeWalk walk = beginWalk()) { + assertIteration(walk, F, ".gitattributes"); + assertIteration(walk, D, "foo"); + assertIteration(walk, F, "foo/bar.jar", attrs("jar xml")); + assertIteration(walk, F, "foo/bar.xml", attrs("xml")); + assertIteration(walk, D, "sub"); + assertIteration(walk, F, "sub/a.txt"); + assertIteration(walk, F, "sub/b.jar", attrs("jar")); + assertIteration(walk, F, "sub/b.xml"); + assertIteration(walk, D, "sub/foo"); + assertIteration(walk, F, "sub/foo/b.jar", attrs("jar")); + assertFalse("Not all files tested", walk.next()); + } } @Test @@ -357,27 +383,29 @@ public class AttributesHandlerTest extends RepositoryTestCase { writeTrashFile("sub/a.txt", "1"); writeTrashFile("foo/sext", "2"); writeTrashFile("foo/s.txt", "3"); - walk = beginWalk(); - assertIteration(F, ".gitattributes"); - assertIteration(D, "foo"); - assertIteration(F, "foo/s.txt", attrs("bar")); - assertIteration(F, "foo/sext", attrs("bar")); - assertIteration(D, "sub"); - assertIteration(F, "sub/a.txt"); - endWalk(); + try (TreeWalk walk = beginWalk()) { + assertIteration(walk, F, ".gitattributes"); + assertIteration(walk, D, "foo"); + assertIteration(walk, F, "foo/s.txt", attrs("bar")); + assertIteration(walk, F, "foo/sext", attrs("bar")); + assertIteration(walk, D, "sub"); + assertIteration(walk, F, "sub/a.txt"); + assertFalse("Not all files tested", walk.next()); + } } @Test public void testPrefixMatchNot() throws Exception { setupRepo(null, null, "sub/new bar", null); writeTrashFile("sub/new/foo.txt", "1"); - walk = beginWalk(); - assertIteration(F, ".gitattributes"); - assertIteration(D, "sub"); - assertIteration(F, "sub/a.txt"); - assertIteration(D, "sub/new", attrs("bar")); - assertIteration(F, "sub/new/foo.txt"); - endWalk(); + try (TreeWalk walk = beginWalk()) { + assertIteration(walk, F, ".gitattributes"); + assertIteration(walk, D, "sub"); + assertIteration(walk, F, "sub/a.txt"); + assertIteration(walk, D, "sub/new", attrs("bar")); + assertIteration(walk, F, "sub/new/foo.txt"); + assertFalse("Not all files tested", walk.next()); + } } @Test @@ -385,14 +413,15 @@ public class AttributesHandlerTest extends RepositoryTestCase { setupRepo(null, null, "s[t-v]b/n[de]w bar", null); writeTrashFile("sub/new/foo.txt", "1"); writeTrashFile("sub/ndw", "2"); - walk = beginWalk(); - assertIteration(F, ".gitattributes"); - assertIteration(D, "sub"); - assertIteration(F, "sub/a.txt"); - assertIteration(F, "sub/ndw", attrs("bar")); - assertIteration(D, "sub/new", attrs("bar")); - assertIteration(F, "sub/new/foo.txt"); - endWalk(); + try (TreeWalk walk = beginWalk()) { + assertIteration(walk, F, ".gitattributes"); + assertIteration(walk, D, "sub"); + assertIteration(walk, F, "sub/a.txt"); + assertIteration(walk, F, "sub/ndw", attrs("bar")); + assertIteration(walk, D, "sub/new", attrs("bar")); + assertIteration(walk, F, "sub/new/foo.txt"); + assertFalse("Not all files tested", walk.next()); + } } @Test @@ -400,15 +429,16 @@ public class AttributesHandlerTest extends RepositoryTestCase { setupRepo(null, null, "sub/new/* bar", null); writeTrashFile("sub/new/foo.txt", "1"); writeTrashFile("sub/new/lower/foo.txt", "2"); - walk = beginWalk(); - assertIteration(F, ".gitattributes"); - assertIteration(D, "sub"); - assertIteration(F, "sub/a.txt"); - assertIteration(D, "sub/new"); - assertIteration(F, "sub/new/foo.txt", attrs("bar")); - assertIteration(D, "sub/new/lower", attrs("bar")); - assertIteration(F, "sub/new/lower/foo.txt"); - endWalk(); + try (TreeWalk walk = beginWalk()) { + assertIteration(walk, F, ".gitattributes"); + assertIteration(walk, D, "sub"); + assertIteration(walk, F, "sub/a.txt"); + assertIteration(walk, D, "sub/new"); + assertIteration(walk, F, "sub/new/foo.txt", attrs("bar")); + assertIteration(walk, D, "sub/new/lower", attrs("bar")); + assertIteration(walk, F, "sub/new/lower/foo.txt"); + assertFalse("Not all files tested", walk.next()); + } } @Test @@ -417,20 +447,21 @@ public class AttributesHandlerTest extends RepositoryTestCase { writeTrashFile("sub/new/foo.txt", "1"); writeTrashFile("foo/sub/new/foo.txt", "2"); writeTrashFile("sub/sub/new/foo.txt", "3"); - walk = beginWalk(); - assertIteration(F, ".gitattributes"); - assertIteration(D, "foo"); - assertIteration(D, "foo/sub"); - assertIteration(D, "foo/sub/new"); - assertIteration(F, "foo/sub/new/foo.txt"); - assertIteration(D, "sub"); - assertIteration(F, "sub/a.txt"); - assertIteration(D, "sub/new", attrs("bar")); - assertIteration(F, "sub/new/foo.txt"); - assertIteration(D, "sub/sub"); - assertIteration(D, "sub/sub/new"); - assertIteration(F, "sub/sub/new/foo.txt"); - endWalk(); + try (TreeWalk walk = beginWalk()) { + assertIteration(walk, F, ".gitattributes"); + assertIteration(walk, D, "foo"); + assertIteration(walk, D, "foo/sub"); + assertIteration(walk, D, "foo/sub/new"); + assertIteration(walk, F, "foo/sub/new/foo.txt"); + assertIteration(walk, D, "sub"); + assertIteration(walk, F, "sub/a.txt"); + assertIteration(walk, D, "sub/new", attrs("bar")); + assertIteration(walk, F, "sub/new/foo.txt"); + assertIteration(walk, D, "sub/sub"); + assertIteration(walk, D, "sub/sub/new"); + assertIteration(walk, F, "sub/sub/new/foo.txt"); + assertFalse("Not all files tested", walk.next()); + } } @Test @@ -438,17 +469,18 @@ public class AttributesHandlerTest extends RepositoryTestCase { setupRepo(null, null, "**/sub/new/ bar", null); writeTrashFile("sub/new/foo.txt", "1"); writeTrashFile("foo/sub/new/foo.txt", "2"); - walk = beginWalk(); - assertIteration(F, ".gitattributes"); - assertIteration(D, "foo"); - assertIteration(D, "foo/sub"); - assertIteration(D, "foo/sub/new", attrs("bar")); - assertIteration(F, "foo/sub/new/foo.txt"); - assertIteration(D, "sub"); - assertIteration(F, "sub/a.txt"); - assertIteration(D, "sub/new", attrs("bar")); - assertIteration(F, "sub/new/foo.txt"); - endWalk(); + try (TreeWalk walk = beginWalk()) { + assertIteration(walk, F, ".gitattributes"); + assertIteration(walk, D, "foo"); + assertIteration(walk, D, "foo/sub"); + assertIteration(walk, D, "foo/sub/new", attrs("bar")); + assertIteration(walk, F, "foo/sub/new/foo.txt"); + assertIteration(walk, D, "sub"); + assertIteration(walk, F, "sub/a.txt"); + assertIteration(walk, D, "sub/new", attrs("bar")); + assertIteration(walk, F, "sub/new/foo.txt"); + assertFalse("Not all files tested", walk.next()); + } } @Test @@ -457,20 +489,21 @@ public class AttributesHandlerTest extends RepositoryTestCase { writeTrashFile("sub/new/foo.txt", "1"); writeTrashFile("foo/sub/new/foo.txt", "2"); writeTrashFile("sub/sub/new/foo.txt", "3"); - walk = beginWalk(); - assertIteration(F, ".gitattributes"); - assertIteration(D, "foo"); - assertIteration(D, "foo/sub"); - assertIteration(D, "foo/sub/new", attrs("bar")); - assertIteration(F, "foo/sub/new/foo.txt"); - assertIteration(D, "sub"); - assertIteration(F, "sub/a.txt"); - assertIteration(D, "sub/new", attrs("bar")); - assertIteration(F, "sub/new/foo.txt"); - assertIteration(D, "sub/sub"); - assertIteration(D, "sub/sub/new", attrs("bar")); - assertIteration(F, "sub/sub/new/foo.txt"); - endWalk(); + try (TreeWalk walk = beginWalk()) { + assertIteration(walk, F, ".gitattributes"); + assertIteration(walk, D, "foo"); + assertIteration(walk, D, "foo/sub"); + assertIteration(walk, D, "foo/sub/new", attrs("bar")); + assertIteration(walk, F, "foo/sub/new/foo.txt"); + assertIteration(walk, D, "sub"); + assertIteration(walk, F, "sub/a.txt"); + assertIteration(walk, D, "sub/new", attrs("bar")); + assertIteration(walk, F, "sub/new/foo.txt"); + assertIteration(walk, D, "sub/sub"); + assertIteration(walk, D, "sub/sub/new", attrs("bar")); + assertIteration(walk, F, "sub/sub/new/foo.txt"); + assertFalse("Not all files tested", walk.next()); + } } @Test @@ -479,20 +512,21 @@ public class AttributesHandlerTest extends RepositoryTestCase { writeTrashFile("sub/new/foo.txt", "1"); writeTrashFile("foo/sub/new/foo.txt", "2"); writeTrashFile("sub/sub/new/foo.txt", "3"); - walk = beginWalk(); - assertIteration(F, ".gitattributes"); - assertIteration(D, "foo"); - assertIteration(D, "foo/sub"); - assertIteration(D, "foo/sub/new", attrs("bar")); - assertIteration(F, "foo/sub/new/foo.txt"); - assertIteration(D, "sub"); - assertIteration(F, "sub/a.txt"); - assertIteration(D, "sub/new", attrs("bar")); - assertIteration(F, "sub/new/foo.txt"); - assertIteration(D, "sub/sub"); - assertIteration(D, "sub/sub/new", attrs("bar")); - assertIteration(F, "sub/sub/new/foo.txt"); - endWalk(); + try (TreeWalk walk = beginWalk()) { + assertIteration(walk, F, ".gitattributes"); + assertIteration(walk, D, "foo"); + assertIteration(walk, D, "foo/sub"); + assertIteration(walk, D, "foo/sub/new", attrs("bar")); + assertIteration(walk, F, "foo/sub/new/foo.txt"); + assertIteration(walk, D, "sub"); + assertIteration(walk, F, "sub/a.txt"); + assertIteration(walk, D, "sub/new", attrs("bar")); + assertIteration(walk, F, "sub/new/foo.txt"); + assertIteration(walk, D, "sub/sub"); + assertIteration(walk, D, "sub/sub/new", attrs("bar")); + assertIteration(walk, F, "sub/sub/new/foo.txt"); + assertFalse("Not all files tested", walk.next()); + } } @Test @@ -500,17 +534,18 @@ public class AttributesHandlerTest extends RepositoryTestCase { setupRepo(null, null, "s[uv]b/n*/ bar", null); writeTrashFile("sub/new/foo.txt", "1"); writeTrashFile("foo/sub/new/foo.txt", "2"); - walk = beginWalk(); - assertIteration(F, ".gitattributes"); - assertIteration(D, "foo"); - assertIteration(D, "foo/sub"); - assertIteration(D, "foo/sub/new"); - assertIteration(F, "foo/sub/new/foo.txt"); - assertIteration(D, "sub"); - assertIteration(F, "sub/a.txt"); - assertIteration(D, "sub/new", attrs("bar")); - assertIteration(F, "sub/new/foo.txt"); - endWalk(); + try (TreeWalk walk = beginWalk()) { + assertIteration(walk, F, ".gitattributes"); + assertIteration(walk, D, "foo"); + assertIteration(walk, D, "foo/sub"); + assertIteration(walk, D, "foo/sub/new"); + assertIteration(walk, F, "foo/sub/new/foo.txt"); + assertIteration(walk, D, "sub"); + assertIteration(walk, F, "sub/a.txt"); + assertIteration(walk, D, "sub/new", attrs("bar")); + assertIteration(walk, F, "sub/new/foo.txt"); + assertFalse("Not all files tested", walk.next()); + } } @Test @@ -519,30 +554,32 @@ public class AttributesHandlerTest extends RepositoryTestCase { writeTrashFile("sub/new/foo.txt", "1"); writeTrashFile("foo/sub/new/foo.txt", "2"); writeTrashFile("foo/new", "3"); - walk = beginWalk(); - assertIteration(F, ".gitattributes"); - assertIteration(D, "foo"); - assertIteration(F, "foo/new"); - assertIteration(D, "foo/sub"); - assertIteration(D, "foo/sub/new", attrs("bar")); - assertIteration(F, "foo/sub/new/foo.txt"); - assertIteration(D, "sub"); - assertIteration(F, "sub/a.txt"); - assertIteration(D, "sub/new", attrs("bar")); - assertIteration(F, "sub/new/foo.txt"); - endWalk(); + try (TreeWalk walk = beginWalk()) { + assertIteration(walk, F, ".gitattributes"); + assertIteration(walk, D, "foo"); + assertIteration(walk, F, "foo/new"); + assertIteration(walk, D, "foo/sub"); + assertIteration(walk, D, "foo/sub/new", attrs("bar")); + assertIteration(walk, F, "foo/sub/new/foo.txt"); + assertIteration(walk, D, "sub"); + assertIteration(walk, F, "sub/a.txt"); + assertIteration(walk, D, "sub/new", attrs("bar")); + assertIteration(walk, F, "sub/new/foo.txt"); + assertFalse("Not all files tested", walk.next()); + } } private static Collection<Attribute> attrs(String s) { return new AttributesRule("*", s).getAttributes(); } - private void assertIteration(FileMode type, String pathName) + private void assertIteration(TreeWalk walk, FileMode type, String pathName) throws IOException { - assertIteration(type, pathName, Collections.<Attribute> emptyList()); + assertIteration(walk, type, pathName, + Collections.<Attribute> emptyList()); } - private void assertIteration(FileMode type, String pathName, + private void assertIteration(TreeWalk walk, FileMode type, String pathName, Collection<Attribute> expectedAttrs) throws IOException { assertTrue("walk has entry", walk.next()); assertEquals(pathName, walk.getPathString()); @@ -611,8 +648,4 @@ public class AttributesHandlerTest extends RepositoryTestCase { newWalk.addTree(new FileTreeIterator(db)); return newWalk; } - - private void endWalk() throws IOException { - assertFalse("Not all files tested", walk.next()); - } } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/attributes/AttributesNodeDirCacheIteratorTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/attributes/AttributesNodeDirCacheIteratorTest.java index 837de74818..cb37d8978a 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/attributes/AttributesNodeDirCacheIteratorTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/attributes/AttributesNodeDirCacheIteratorTest.java @@ -78,8 +78,6 @@ public class AttributesNodeDirCacheIteratorTest extends RepositoryTestCase { private Git git; - private TreeWalk walk; - @Override @Before public void setUp() throws Exception { @@ -105,23 +103,25 @@ public class AttributesNodeDirCacheIteratorTest extends RepositoryTestCase { // Adds file to index git.add().addFilepattern(".").call(); - walk = beginWalk(); - - assertIteration(F, ".gitattributes"); - assertIteration(F, "readme.txt", asList(EOL_LF)); + try (TreeWalk walk = beginWalk()) { + assertIteration(walk, F, ".gitattributes"); + assertIteration(walk, F, "readme.txt", asList(EOL_LF)); - assertIteration(D, "src"); + assertIteration(walk, D, "src"); - assertIteration(D, "src/config"); - assertIteration(F, "src/config/.gitattributes"); - assertIteration(F, "src/config/readme.txt", asList(DELTA_UNSET)); - assertIteration(F, "src/config/windows.file", null); - assertIteration(F, "src/config/windows.txt", asList(DELTA_UNSET)); + assertIteration(walk, D, "src/config"); + assertIteration(walk, F, "src/config/.gitattributes"); + assertIteration(walk, F, "src/config/readme.txt", + asList(DELTA_UNSET)); + assertIteration(walk, F, "src/config/windows.file", null); + assertIteration(walk, F, "src/config/windows.txt", + asList(DELTA_UNSET)); - assertIteration(F, "windows.file", null); - assertIteration(F, "windows.txt", asList(EOL_LF)); + assertIteration(walk, F, "windows.file", null); + assertIteration(walk, F, "windows.txt", asList(EOL_LF)); - endWalk(); + assertFalse("Not all files tested", walk.next()); + } } /** @@ -138,17 +138,18 @@ public class AttributesNodeDirCacheIteratorTest extends RepositoryTestCase { // Adds file to index git.add().addFilepattern(".").call(); - walk = beginWalk(); - assertIteration(F, "l0.txt"); + try (TreeWalk walk = beginWalk()) { + assertIteration(walk, F, "l0.txt"); - assertIteration(D, "level1"); - assertIteration(F, "level1/l1.txt"); + assertIteration(walk, D, "level1"); + assertIteration(walk, F, "level1/l1.txt"); - assertIteration(D, "level1/level2"); - assertIteration(F, "level1/level2/l2.txt"); + assertIteration(walk, D, "level1/level2"); + assertIteration(walk, F, "level1/level2/l2.txt"); - endWalk(); + assertFalse("Not all files tested", walk.next()); + } } /** @@ -166,18 +167,19 @@ public class AttributesNodeDirCacheIteratorTest extends RepositoryTestCase { // Adds file to index git.add().addFilepattern(".").call(); - walk = beginWalk(); - assertIteration(F, ".gitattributes"); - assertIteration(F, "l0.txt"); + try (TreeWalk walk = beginWalk()) { + assertIteration(walk, F, ".gitattributes"); + assertIteration(walk, F, "l0.txt"); - assertIteration(D, "level1"); - assertIteration(F, "level1/l1.txt"); + assertIteration(walk, D, "level1"); + assertIteration(walk, F, "level1/l1.txt"); - assertIteration(D, "level1/level2"); - assertIteration(F, "level1/level2/l2.txt"); + assertIteration(walk, D, "level1/level2"); + assertIteration(walk, F, "level1/level2/l2.txt"); - endWalk(); + assertFalse("Not all files tested", walk.next()); + } } @Test @@ -191,18 +193,19 @@ public class AttributesNodeDirCacheIteratorTest extends RepositoryTestCase { // Adds file to index git.add().addFilepattern(".").call(); - walk = beginWalk(); - assertIteration(F, ".gitattributes"); + try (TreeWalk walk = beginWalk()) { + assertIteration(walk, F, ".gitattributes"); - assertIteration(D, "levelA"); - assertIteration(F, "levelA/.gitattributes"); - assertIteration(F, "levelA/lA.txt"); + assertIteration(walk, D, "levelA"); + assertIteration(walk, F, "levelA/.gitattributes"); + assertIteration(walk, F, "levelA/lA.txt"); - assertIteration(D, "levelB"); - assertIteration(F, "levelB/.gitattributes"); + assertIteration(walk, D, "levelB"); + assertIteration(walk, F, "levelB/.gitattributes"); - endWalk(); + assertFalse("Not all files tested", walk.next()); + } } @Test @@ -215,25 +218,27 @@ public class AttributesNodeDirCacheIteratorTest extends RepositoryTestCase { // Adds file to index git.add().addFilepattern(".").call(); - walk = beginWalk(); - assertIteration(F, "gitattributes"); + try (TreeWalk walk = beginWalk()) { + assertIteration(walk, F, "gitattributes"); - assertIteration(F, "l0.txt"); + assertIteration(walk, F, "l0.txt"); - assertIteration(D, "levelA"); - assertIteration(F, "levelA/file.gitattributes"); - assertIteration(F, "levelA/lA.txt"); + assertIteration(walk, D, "levelA"); + assertIteration(walk, F, "levelA/file.gitattributes"); + assertIteration(walk, F, "levelA/lA.txt"); - endWalk(); + assertFalse("Not all files tested", walk.next()); + } } - private void assertIteration(FileMode type, String pathName) + private void assertIteration(TreeWalk walk, FileMode type, String pathName) throws IOException { - assertIteration(type, pathName, Collections.<Attribute> emptyList()); + assertIteration(walk, type, pathName, + Collections.<Attribute> emptyList()); } - private void assertIteration(FileMode type, String pathName, + private void assertIteration(TreeWalk walk, FileMode type, String pathName, List<Attribute> nodeAttrs) throws IOException { assertTrue("walk has entry", walk.next()); assertEquals(pathName, walk.getPathString()); @@ -243,14 +248,14 @@ public class AttributesNodeDirCacheIteratorTest extends RepositoryTestCase { AttributesNode attributesNode = itr.getEntryAttributesNode(db .newObjectReader()); - assertAttributesNode(pathName, attributesNode, nodeAttrs); + assertAttributesNode(walk, pathName, attributesNode, nodeAttrs); if (D.equals(type)) walk.enterSubtree(); } - private void assertAttributesNode(String pathName, + private void assertAttributesNode(TreeWalk walk, String pathName, AttributesNode attributesNode, List<Attribute> nodeAttrs) throws IOException { if (attributesNode == null) @@ -292,8 +297,4 @@ public class AttributesNodeDirCacheIteratorTest extends RepositoryTestCase { newWalk.addTree(new DirCacheIterator(db.readDirCache())); return newWalk; } - - private void endWalk() throws IOException { - assertFalse("Not all files tested", walk.next()); - } } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/attributes/AttributesNodeWorkingTreeIteratorTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/attributes/AttributesNodeWorkingTreeIteratorTest.java index b159cca0d5..9991ae59b0 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/attributes/AttributesNodeWorkingTreeIteratorTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/attributes/AttributesNodeWorkingTreeIteratorTest.java @@ -77,8 +77,6 @@ public class AttributesNodeWorkingTreeIteratorTest extends RepositoryTestCase { private static Attribute DELTA_UNSET = new Attribute("delta", State.UNSET); - private TreeWalk walk; - @Test public void testRules() throws Exception { @@ -102,24 +100,26 @@ public class AttributesNodeWorkingTreeIteratorTest extends RepositoryTestCase { writeTrashFile("src/config/windows.file", ""); writeTrashFile("src/config/windows.txt", ""); - walk = beginWalk(); - - assertIteration(F, ".gitattributes"); - assertIteration(F, "global.txt", asList(EOL_LF)); - assertIteration(F, "readme.txt", asList(EOL_LF)); + try (TreeWalk walk = beginWalk()) { + assertIteration(walk, F, ".gitattributes"); + assertIteration(walk, F, "global.txt", asList(EOL_LF)); + assertIteration(walk, F, "readme.txt", asList(EOL_LF)); - assertIteration(D, "src"); + assertIteration(walk, D, "src"); - assertIteration(D, "src/config"); - assertIteration(F, "src/config/.gitattributes"); - assertIteration(F, "src/config/readme.txt", asList(DELTA_UNSET)); - assertIteration(F, "src/config/windows.file", null); - assertIteration(F, "src/config/windows.txt", asList(DELTA_UNSET)); + assertIteration(walk, D, "src/config"); + assertIteration(walk, F, "src/config/.gitattributes"); + assertIteration(walk, F, "src/config/readme.txt", + asList(DELTA_UNSET)); + assertIteration(walk, F, "src/config/windows.file", null); + assertIteration(walk, F, "src/config/windows.txt", + asList(DELTA_UNSET)); - assertIteration(F, "windows.file", null); - assertIteration(F, "windows.txt", asList(EOL_LF)); + assertIteration(walk, F, "windows.file", null); + assertIteration(walk, F, "windows.txt", asList(EOL_LF)); - endWalk(); + assertFalse("Not all files tested", walk.next()); + } } /** @@ -134,17 +134,17 @@ public class AttributesNodeWorkingTreeIteratorTest extends RepositoryTestCase { writeTrashFile("level1/l1.txt", ""); writeTrashFile("level1/level2/l2.txt", ""); - walk = beginWalk(); + try (TreeWalk walk = beginWalk()) { + assertIteration(walk, F, "l0.txt"); - assertIteration(F, "l0.txt"); + assertIteration(walk, D, "level1"); + assertIteration(walk, F, "level1/l1.txt"); - assertIteration(D, "level1"); - assertIteration(F, "level1/l1.txt"); + assertIteration(walk, D, "level1/level2"); + assertIteration(walk, F, "level1/level2/l2.txt"); - assertIteration(D, "level1/level2"); - assertIteration(F, "level1/level2/l2.txt"); - - endWalk(); + assertFalse("Not all files tested", walk.next()); + } } /** @@ -160,18 +160,18 @@ public class AttributesNodeWorkingTreeIteratorTest extends RepositoryTestCase { writeTrashFile("level1/l1.txt", ""); writeTrashFile("level1/level2/l2.txt", ""); - walk = beginWalk(); - - assertIteration(F, ".gitattributes"); - assertIteration(F, "l0.txt"); + try (TreeWalk walk = beginWalk()) { + assertIteration(walk, F, ".gitattributes"); + assertIteration(walk, F, "l0.txt"); - assertIteration(D, "level1"); - assertIteration(F, "level1/l1.txt"); + assertIteration(walk, D, "level1"); + assertIteration(walk, F, "level1/l1.txt"); - assertIteration(D, "level1/level2"); - assertIteration(F, "level1/level2/l2.txt"); + assertIteration(walk, D, "level1/level2"); + assertIteration(walk, F, "level1/level2/l2.txt"); - endWalk(); + assertFalse("Not all files tested", walk.next()); + } } @Test @@ -183,26 +183,27 @@ public class AttributesNodeWorkingTreeIteratorTest extends RepositoryTestCase { writeTrashFile("levelA/lA.txt", ""); - walk = beginWalk(); - - assertIteration(F, ".gitattributes"); + try (TreeWalk walk = beginWalk()) { + assertIteration(walk, F, ".gitattributes"); - assertIteration(D, "levelA"); - assertIteration(F, "levelA/.gitattributes"); - assertIteration(F, "levelA/lA.txt"); + assertIteration(walk, D, "levelA"); + assertIteration(walk, F, "levelA/.gitattributes"); + assertIteration(walk, F, "levelA/lA.txt"); - assertIteration(D, "levelB"); - assertIteration(F, "levelB/.gitattributes"); + assertIteration(walk, D, "levelB"); + assertIteration(walk, F, "levelB/.gitattributes"); - endWalk(); + assertFalse("Not all files tested", walk.next()); + } } - private void assertIteration(FileMode type, String pathName) + private void assertIteration(TreeWalk walk, FileMode type, String pathName) throws IOException { - assertIteration(type, pathName, Collections.<Attribute> emptyList()); + assertIteration(walk, type, pathName, + Collections.<Attribute> emptyList()); } - private void assertIteration(FileMode type, String pathName, + private void assertIteration(TreeWalk walk, FileMode type, String pathName, List<Attribute> nodeAttrs) throws IOException { assertTrue("walk has entry", walk.next()); @@ -212,13 +213,13 @@ public class AttributesNodeWorkingTreeIteratorTest extends RepositoryTestCase { assertNotNull("has tree", itr); AttributesNode attributesNode = itr.getEntryAttributesNode(); - assertAttributesNode(pathName, attributesNode, nodeAttrs); + assertAttributesNode(walk, pathName, attributesNode, nodeAttrs); if (D.equals(type)) walk.enterSubtree(); } - private void assertAttributesNode(String pathName, + private void assertAttributesNode(TreeWalk walk, String pathName, AttributesNode attributesNode, List<Attribute> nodeAttrs) throws IOException { if (attributesNode == null) @@ -259,8 +260,4 @@ public class AttributesNodeWorkingTreeIteratorTest extends RepositoryTestCase { newWalk.addTree(new FileTreeIterator(db)); return newWalk; } - - private void endWalk() throws IOException { - assertFalse("Not all files tested", walk.next()); - } } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/attributes/TreeWalkAttributeTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/attributes/TreeWalkAttributeTest.java index d6aead4a52..0291fcc1e9 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/attributes/TreeWalkAttributeTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/attributes/TreeWalkAttributeTest.java @@ -131,6 +131,12 @@ public class TreeWalkAttributeTest extends RepositoryTestCase { @Override @After public void tearDown() throws Exception { + if (walk != null) { + walk.close(); + } + if (ci_walk != null) { + ci_walk.close(); + } super.tearDown(); if (customAttributeFile != null) customAttributeFile.delete(); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/ignore/IgnoreNodeTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/ignore/IgnoreNodeTest.java index cbc0761463..45046a3999 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/ignore/IgnoreNodeTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/ignore/IgnoreNodeTest.java @@ -63,6 +63,7 @@ import org.eclipse.jgit.treewalk.TreeWalk; import org.eclipse.jgit.treewalk.WorkingTreeIterator; import org.eclipse.jgit.util.FileUtils; import org.eclipse.jgit.util.SystemReader; +import org.junit.After; import org.junit.Test; /** @@ -79,6 +80,13 @@ public class IgnoreNodeTest extends RepositoryTestCase { private TreeWalk walk; + @After + public void closeWalk() { + if (walk != null) { + walk.close(); + } + } + @Test public void testSimpleRootGitIgnoreGlobalIgnore() throws IOException { writeIgnoreFile(".gitignore", "x"); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsGarbageCollectorTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsGarbageCollectorTest.java index 5a5ae1d7a3..cfc275a7de 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsGarbageCollectorTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsGarbageCollectorTest.java @@ -723,7 +723,7 @@ public class DfsGarbageCollectorTest { DfsPackDescription t1 = odb.newPack(INSERT); try (DfsOutputStream out = odb.writeFile(t1, REFTABLE)) { - new ReftableWriter().begin(out).finish(); + new ReftableWriter(out).begin().finish(); t1.addFileExt(REFTABLE); } odb.commitPack(Collections.singleton(t1), null); @@ -755,7 +755,7 @@ public class DfsGarbageCollectorTest { DfsPackDescription t1 = odb.newPack(INSERT); try (DfsOutputStream out = odb.writeFile(t1, REFTABLE)) { - new ReftableWriter().begin(out).finish(); + new ReftableWriter(out).begin().finish(); t1.addFileExt(REFTABLE); } odb.commitPack(Collections.singleton(t1), null); @@ -795,10 +795,10 @@ public class DfsGarbageCollectorTest { Ref next = new ObjectIdRef.PeeledNonTag(Ref.Storage.LOOSE, "refs/heads/next", commit0.copy()); try (DfsOutputStream out = odb.writeFile(t1, REFTABLE)) { - ReftableWriter w = new ReftableWriter(); + ReftableWriter w = new ReftableWriter(out); w.setMinUpdateIndex(42); w.setMaxUpdateIndex(42); - w.begin(out); + w.begin(); w.sortAndWriteRefs(Collections.singleton(next)); w.finish(); t1.addFileExt(REFTABLE); @@ -877,10 +877,10 @@ public class DfsGarbageCollectorTest { Ref newNext = new ObjectIdRef.PeeledNonTag(Ref.Storage.LOOSE, NEXT, commit1); try (DfsOutputStream out = odb.writeFile(t1, REFTABLE)) { - ReftableWriter w = new ReftableWriter(); - w.setMinUpdateIndex(1); - w.setMaxUpdateIndex(1); - w.begin(out); + ReftableWriter w = new ReftableWriter(out) + .setMinUpdateIndex(1) + .setMaxUpdateIndex(1) + .begin(); w.writeRef(newNext, 1); w.finish(); t1.addFileExt(REFTABLE); @@ -929,10 +929,10 @@ public class DfsGarbageCollectorTest { Ref newNext = new ObjectIdRef.PeeledNonTag(Ref.Storage.LOOSE, NEXT, commit1); try (DfsOutputStream out = odb.writeFile(t1, REFTABLE)) { - ReftableWriter w = new ReftableWriter(); - w.setMinUpdateIndex(1); - w.setMaxUpdateIndex(1); - w.begin(out); + ReftableWriter w = new ReftableWriter(out) + .setMinUpdateIndex(1) + .setMaxUpdateIndex(1) + .begin(); w.writeRef(newNext, 1); w.finish(); t1.addFileExt(REFTABLE); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsInserterTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsInserterTest.java index e71ee6d25f..4d36144212 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsInserterTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsInserterTest.java @@ -92,18 +92,22 @@ public class DfsInserterTest { @Test public void testReadFromInserterSmallObjects() throws IOException { - ObjectInserter ins = db.newObjectInserter(); - ObjectId id1 = ins.insert(Constants.OBJ_BLOB, Constants.encode("foo")); - ObjectId id2 = ins.insert(Constants.OBJ_BLOB, Constants.encode("bar")); - assertEquals(0, db.getObjectDatabase().listPacks().size()); + try (ObjectInserter ins = db.newObjectInserter()) { + ObjectId id1 = ins.insert(Constants.OBJ_BLOB, + Constants.encode("foo")); + ObjectId id2 = ins.insert(Constants.OBJ_BLOB, + Constants.encode("bar")); + assertEquals(0, db.getObjectDatabase().listPacks().size()); - ObjectReader reader = ins.newReader(); - assertSame(ins, reader.getCreatedFromInserter()); - assertEquals("foo", readString(reader.open(id1))); - assertEquals("bar", readString(reader.open(id2))); - assertEquals(0, db.getObjectDatabase().listPacks().size()); - ins.flush(); - assertEquals(1, db.getObjectDatabase().listPacks().size()); + try (ObjectReader reader = ins.newReader()) { + assertSame(ins, reader.getCreatedFromInserter()); + assertEquals("foo", readString(reader.open(id1))); + assertEquals("bar", readString(reader.open(id2))); + assertEquals(0, db.getObjectDatabase().listPacks().size()); + ins.flush(); + assertEquals(1, db.getObjectDatabase().listPacks().size()); + } + } } @Test @@ -114,17 +118,19 @@ public class DfsInserterTest { .setBlockLimit(2048)); byte[] data = new TestRng(JGitTestUtil.getName()).nextBytes(8192); - DfsInserter ins = (DfsInserter) db.newObjectInserter(); - ins.setCompressionLevel(Deflater.NO_COMPRESSION); - ObjectId id1 = ins.insert(Constants.OBJ_BLOB, data); - assertEquals(0, db.getObjectDatabase().listPacks().size()); + try (DfsInserter ins = (DfsInserter) db.newObjectInserter()) { + ins.setCompressionLevel(Deflater.NO_COMPRESSION); + ObjectId id1 = ins.insert(Constants.OBJ_BLOB, data); + assertEquals(0, db.getObjectDatabase().listPacks().size()); - ObjectReader reader = ins.newReader(); - assertSame(ins, reader.getCreatedFromInserter()); - assertTrue(Arrays.equals(data, readStream(reader.open(id1)))); - assertEquals(0, db.getObjectDatabase().listPacks().size()); - ins.flush(); + try (ObjectReader reader = ins.newReader()) { + assertSame(ins, reader.getCreatedFromInserter()); + assertTrue(Arrays.equals(data, readStream(reader.open(id1)))); + assertEquals(0, db.getObjectDatabase().listPacks().size()); + } + ins.flush(); + } List<DfsPackDescription> packs = db.getObjectDatabase().listPacks(); assertEquals(1, packs.size()); assertTrue(packs.get(0).getFileSize(PackExt.PACK) > 2048); @@ -132,48 +138,58 @@ public class DfsInserterTest { @Test public void testReadFromFallback() throws IOException { - ObjectInserter ins = db.newObjectInserter(); - ObjectId id1 = ins.insert(Constants.OBJ_BLOB, Constants.encode("foo")); - ins.flush(); - ObjectId id2 = ins.insert(Constants.OBJ_BLOB, Constants.encode("bar")); - assertEquals(1, db.getObjectDatabase().listPacks().size()); - - ObjectReader reader = ins.newReader(); - assertSame(ins, reader.getCreatedFromInserter()); - assertEquals("foo", readString(reader.open(id1))); - assertEquals("bar", readString(reader.open(id2))); - assertEquals(1, db.getObjectDatabase().listPacks().size()); - ins.flush(); - assertEquals(2, db.getObjectDatabase().listPacks().size()); + try (ObjectInserter ins = db.newObjectInserter()) { + ObjectId id1 = ins.insert(Constants.OBJ_BLOB, + Constants.encode("foo")); + ins.flush(); + ObjectId id2 = ins.insert(Constants.OBJ_BLOB, + Constants.encode("bar")); + assertEquals(1, db.getObjectDatabase().listPacks().size()); + + try (ObjectReader reader = ins.newReader()) { + assertSame(ins, reader.getCreatedFromInserter()); + assertEquals("foo", readString(reader.open(id1))); + assertEquals("bar", readString(reader.open(id2))); + assertEquals(1, db.getObjectDatabase().listPacks().size()); + } + ins.flush(); + assertEquals(2, db.getObjectDatabase().listPacks().size()); + } } @Test public void testReaderResolve() throws IOException { - ObjectInserter ins = db.newObjectInserter(); - ObjectId id1 = ins.insert(Constants.OBJ_BLOB, Constants.encode("foo")); - ins.flush(); - ObjectId id2 = ins.insert(Constants.OBJ_BLOB, Constants.encode("bar")); - String abbr1 = ObjectId.toString(id1).substring(0, 4); - String abbr2 = ObjectId.toString(id2).substring(0, 4); - assertFalse(abbr1.equals(abbr2)); - - ObjectReader reader = ins.newReader(); - assertSame(ins, reader.getCreatedFromInserter()); - Collection<ObjectId> objs; - objs = reader.resolve(AbbreviatedObjectId.fromString(abbr1)); - assertEquals(1, objs.size()); - assertEquals(id1, objs.iterator().next()); - - objs = reader.resolve(AbbreviatedObjectId.fromString(abbr2)); - assertEquals(1, objs.size()); - assertEquals(id2, objs.iterator().next()); + try (ObjectInserter ins = db.newObjectInserter()) { + ObjectId id1 = ins.insert(Constants.OBJ_BLOB, + Constants.encode("foo")); + ins.flush(); + ObjectId id2 = ins.insert(Constants.OBJ_BLOB, + Constants.encode("bar")); + String abbr1 = ObjectId.toString(id1).substring(0, 4); + String abbr2 = ObjectId.toString(id2).substring(0, 4); + assertFalse(abbr1.equals(abbr2)); + + try (ObjectReader reader = ins.newReader()) { + assertSame(ins, reader.getCreatedFromInserter()); + Collection<ObjectId> objs; + objs = reader.resolve(AbbreviatedObjectId.fromString(abbr1)); + assertEquals(1, objs.size()); + assertEquals(id1, objs.iterator().next()); + + objs = reader.resolve(AbbreviatedObjectId.fromString(abbr2)); + assertEquals(1, objs.size()); + assertEquals(id2, objs.iterator().next()); + } + } } @Test public void testGarbageSelectivelyVisible() throws IOException { - ObjectInserter ins = db.newObjectInserter(); - ObjectId fooId = ins.insert(Constants.OBJ_BLOB, Constants.encode("foo")); - ins.flush(); + ObjectId fooId; + try (ObjectInserter ins = db.newObjectInserter()) { + fooId = ins.insert(Constants.OBJ_BLOB, Constants.encode("foo")); + ins.flush(); + } assertEquals(1, db.getObjectDatabase().listPacks().size()); // Make pack 0 garbage. @@ -187,36 +203,40 @@ public class DfsInserterTest { @Test public void testInserterIgnoresUnreachable() throws IOException { - ObjectInserter ins = db.newObjectInserter(); - ObjectId fooId = ins.insert(Constants.OBJ_BLOB, Constants.encode("foo")); - ins.flush(); - assertEquals(1, db.getObjectDatabase().listPacks().size()); + ObjectId fooId; + try (ObjectInserter ins = db.newObjectInserter()) { + fooId = ins.insert(Constants.OBJ_BLOB, Constants.encode("foo")); + ins.flush(); + assertEquals(1, db.getObjectDatabase().listPacks().size()); - // Make pack 0 garbage. - db.getObjectDatabase().listPacks().get(0).setPackSource(PackSource.UNREACHABLE_GARBAGE); + // Make pack 0 garbage. + db.getObjectDatabase().listPacks().get(0) + .setPackSource(PackSource.UNREACHABLE_GARBAGE); - // We shouldn't be able to see foo because it's garbage. - assertFalse(db.getObjectDatabase().has(fooId, true)); + // We shouldn't be able to see foo because it's garbage. + assertFalse(db.getObjectDatabase().has(fooId, true)); - // But if we re-insert foo, it should become visible again. - ins.insert(Constants.OBJ_BLOB, Constants.encode("foo")); - ins.flush(); + // But if we re-insert foo, it should become visible again. + ins.insert(Constants.OBJ_BLOB, Constants.encode("foo")); + ins.flush(); + } assertTrue(db.getObjectDatabase().has(fooId, true)); // Verify that we have a foo in both packs, and 1 of them is garbage. - DfsReader reader = new DfsReader(db.getObjectDatabase()); - DfsPackFile packs[] = db.getObjectDatabase().getPacks(); - Set<PackSource> pack_sources = new HashSet<>(); + try (DfsReader reader = new DfsReader(db.getObjectDatabase())) { + DfsPackFile packs[] = db.getObjectDatabase().getPacks(); + Set<PackSource> pack_sources = new HashSet<>(); - assertEquals(2, packs.length); + assertEquals(2, packs.length); - pack_sources.add(packs[0].getPackDescription().getPackSource()); - pack_sources.add(packs[1].getPackDescription().getPackSource()); + pack_sources.add(packs[0].getPackDescription().getPackSource()); + pack_sources.add(packs[1].getPackDescription().getPackSource()); - assertTrue(packs[0].hasObject(reader, fooId)); - assertTrue(packs[1].hasObject(reader, fooId)); - assertTrue(pack_sources.contains(PackSource.UNREACHABLE_GARBAGE)); - assertTrue(pack_sources.contains(PackSource.INSERT)); + assertTrue(packs[0].hasObject(reader, fooId)); + assertTrue(packs[1].hasObject(reader, fooId)); + assertTrue(pack_sources.contains(PackSource.UNREACHABLE_GARBAGE)); + assertTrue(pack_sources.contains(PackSource.INSERT)); + } } @Test @@ -237,17 +257,20 @@ public class DfsInserterTest { assertEquals(2, db.getObjectDatabase().listPacks().size()); // Verify that we have a foo in both INSERT packs. - DfsReader reader = new DfsReader(db.getObjectDatabase()); - DfsPackFile packs[] = db.getObjectDatabase().getPacks(); - - assertEquals(2, packs.length); - DfsPackFile p1 = packs[0]; - assertEquals(PackSource.INSERT, p1.getPackDescription().getPackSource()); - assertTrue(p1.hasObject(reader, fooId)); - - DfsPackFile p2 = packs[1]; - assertEquals(PackSource.INSERT, p2.getPackDescription().getPackSource()); - assertTrue(p2.hasObject(reader, fooId)); + try (DfsReader reader = new DfsReader(db.getObjectDatabase())) { + DfsPackFile packs[] = db.getObjectDatabase().getPacks(); + + assertEquals(2, packs.length); + DfsPackFile p1 = packs[0]; + assertEquals(PackSource.INSERT, + p1.getPackDescription().getPackSource()); + assertTrue(p1.hasObject(reader, fooId)); + + DfsPackFile p2 = packs[1]; + assertEquals(PackSource.INSERT, + p2.getPackDescription().getPackSource()); + assertTrue(p2.hasObject(reader, fooId)); + } } private static String readString(ObjectLoader loader) throws IOException { diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/BatchRefUpdateTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/BatchRefUpdateTest.java index 79cf4d5aff..cb5b07a4db 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/BatchRefUpdateTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/BatchRefUpdateTest.java @@ -61,6 +61,7 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; +import static org.junit.Assume.assumeFalse; import static org.junit.Assume.assumeTrue; import java.io.File; @@ -109,19 +110,29 @@ import org.junit.runners.Parameterized.Parameters; @SuppressWarnings("boxing") @RunWith(Parameterized.class) public class BatchRefUpdateTest extends LocalDiskRepositoryTestCase { - @Parameter + @Parameter(0) public boolean atomic; - @Parameters(name = "atomic={0}") + @Parameter(1) + public boolean useReftable; + + @Parameters(name = "atomic={0} reftable={1}") public static Collection<Object[]> data() { - return Arrays.asList(new Object[][]{ {Boolean.FALSE}, {Boolean.TRUE} }); + return Arrays.asList(new Object[][] { { Boolean.FALSE, Boolean.FALSE }, + { Boolean.TRUE, Boolean.FALSE }, + { Boolean.FALSE, Boolean.TRUE }, + { Boolean.TRUE, Boolean.TRUE }, }); } private Repository diskRepo; + private TestRepository<Repository> repo; + private RefDirectory refdir; + private RevCommit A; - private RevCommit B; + + private RevCommit B; // B descends from A. /** * When asserting the number of RefsChangedEvents you must account for one @@ -143,11 +154,18 @@ public class BatchRefUpdateTest extends LocalDiskRepositoryTestCase { public void setUp() throws Exception { super.setUp(); - diskRepo = createBareRepository(); + FileRepository fileRepo = createBareRepository(); + if (useReftable) { + fileRepo.convertToReftable(false, false); + } + + diskRepo = fileRepo; setLogAllRefUpdates(true); - refdir = (RefDirectory) diskRepo.getRefDatabase(); - refdir.setRetrySleepMs(Arrays.asList(0, 0)); + if (!useReftable) { + refdir = (RefDirectory) diskRepo.getRefDatabase(); + refdir.setRetrySleepMs(Arrays.asList(0, 0)); + } repo = new TestRepository<>(diskRepo); A = repo.commit().create(); @@ -166,11 +184,12 @@ public class BatchRefUpdateTest extends LocalDiskRepositoryTestCase { @Test public void packedRefsFileIsSorted() throws IOException { assumeTrue(atomic); + assumeFalse(useReftable); for (int i = 0; i < 2; i++) { BatchRefUpdate bu = diskRepo.getRefDatabase().newBatchUpdate(); - String b1 = String.format("refs/heads/a%d",i); - String b2 = String.format("refs/heads/b%d",i); + String b1 = String.format("refs/heads/a%d", i); + String b2 = String.format("refs/heads/b%d", i); bu.setAtomic(atomic); ReceiveCommand c1 = new ReceiveCommand(ObjectId.zeroId(), A, b1); ReceiveCommand c2 = new ReceiveCommand(ObjectId.zeroId(), B, b2); @@ -183,70 +202,65 @@ public class BatchRefUpdateTest extends LocalDiskRepositoryTestCase { } File packed = new File(diskRepo.getDirectory(), "packed-refs"); - String packedStr = new String(Files.readAllBytes(packed.toPath()), UTF_8); + String packedStr = new String(Files.readAllBytes(packed.toPath()), + UTF_8); int a2 = packedStr.indexOf("refs/heads/a1"); int b1 = packedStr.indexOf("refs/heads/b0"); - assertTrue(a2 < b1); + assertTrue(a2 < b1); } @Test public void simpleNoForce() throws IOException { - writeLooseRef("refs/heads/master", A); - writeLooseRef("refs/heads/masters", B); + writeLooseRefs("refs/heads/master", A, "refs/heads/masters", B); List<ReceiveCommand> cmds = Arrays.asList( new ReceiveCommand(A, B, "refs/heads/master", UPDATE), - new ReceiveCommand(B, A, "refs/heads/masters", UPDATE_NONFASTFORWARD)); + new ReceiveCommand(B, A, "refs/heads/masters", + UPDATE_NONFASTFORWARD)); execute(newBatchUpdate(cmds)); if (atomic) { assertResults(cmds, TRANSACTION_ABORTED, REJECTED_NONFASTFORWARD); - assertRefs( - "refs/heads/master", A, - "refs/heads/masters", B); + assertRefs("refs/heads/master", A, "refs/heads/masters", B); assertEquals(1, refsChangedEvents); } else { assertResults(cmds, OK, REJECTED_NONFASTFORWARD); - assertRefs( - "refs/heads/master", B, - "refs/heads/masters", B); + assertRefs("refs/heads/master", B, "refs/heads/masters", B); assertEquals(2, refsChangedEvents); } } @Test public void simpleForce() throws IOException { - writeLooseRef("refs/heads/master", A); - writeLooseRef("refs/heads/masters", B); + writeLooseRefs("refs/heads/master", A, "refs/heads/masters", B); List<ReceiveCommand> cmds = Arrays.asList( new ReceiveCommand(A, B, "refs/heads/master", UPDATE), - new ReceiveCommand(B, A, "refs/heads/masters", UPDATE_NONFASTFORWARD)); + new ReceiveCommand(B, A, "refs/heads/masters", + UPDATE_NONFASTFORWARD)); execute(newBatchUpdate(cmds).setAllowNonFastForwards(true)); assertResults(cmds, OK, OK); - assertRefs( - "refs/heads/master", B, - "refs/heads/masters", A); - assertEquals(atomic ? 2 : 3, refsChangedEvents); + assertRefs("refs/heads/master", B, "refs/heads/masters", A); + assertEquals(batchesRefUpdates() ? 2 : 3, refsChangedEvents); } @Test - public void nonFastForwardDoesNotDoExpensiveMergeCheck() throws IOException { + public void nonFastForwardDoesNotDoExpensiveMergeCheck() + throws IOException { writeLooseRef("refs/heads/master", B); - List<ReceiveCommand> cmds = Arrays.asList( - new ReceiveCommand(B, A, "refs/heads/master", UPDATE_NONFASTFORWARD)); + List<ReceiveCommand> cmds = Arrays.asList(new ReceiveCommand(B, A, + "refs/heads/master", UPDATE_NONFASTFORWARD)); try (RevWalk rw = new RevWalk(diskRepo) { - @Override - public boolean isMergedInto(RevCommit base, RevCommit tip) { - throw new AssertionError("isMergedInto() should not be called"); - } - }) { - newBatchUpdate(cmds) - .setAllowNonFastForwards(true) - .execute(rw, new StrictWorkMonitor()); + @Override + public boolean isMergedInto(RevCommit base, RevCommit tip) { + throw new AssertionError("isMergedInto() should not be called"); + } + }) { + newBatchUpdate(cmds).setAllowNonFastForwards(true).execute(rw, + new StrictWorkMonitor()); } assertResults(cmds, OK); @@ -256,8 +270,7 @@ public class BatchRefUpdateTest extends LocalDiskRepositoryTestCase { @Test public void fileDirectoryConflict() throws IOException { - writeLooseRef("refs/heads/master", A); - writeLooseRef("refs/heads/masters", B); + writeLooseRefs("refs/heads/master", A, "refs/heads/masters", B); List<ReceiveCommand> cmds = Arrays.asList( new ReceiveCommand(A, B, "refs/heads/master", UPDATE), @@ -266,29 +279,24 @@ public class BatchRefUpdateTest extends LocalDiskRepositoryTestCase { execute(newBatchUpdate(cmds).setAllowNonFastForwards(true), false); if (atomic) { - // Atomic update sees that master and master/x are conflicting, then marks - // the first one in the list as LOCK_FAILURE and aborts the rest. - assertResults(cmds, - LOCK_FAILURE, TRANSACTION_ABORTED, TRANSACTION_ABORTED); - assertRefs( - "refs/heads/master", A, - "refs/heads/masters", B); + // Atomic update sees that master and master/x are conflicting, then + // marks the first one in the list as LOCK_FAILURE and aborts the rest. + assertResults(cmds, LOCK_FAILURE, TRANSACTION_ABORTED, + TRANSACTION_ABORTED); + assertRefs("refs/heads/master", A, "refs/heads/masters", B); assertEquals(1, refsChangedEvents); } else { - // Non-atomic updates are applied in order: master succeeds, then master/x - // fails due to conflict. + // Non-atomic updates are applied in order: master succeeds, then + // master/x fails due to conflict. assertResults(cmds, OK, LOCK_FAILURE, LOCK_FAILURE); - assertRefs( - "refs/heads/master", B, - "refs/heads/masters", B); + assertRefs("refs/heads/master", B, "refs/heads/masters", B); assertEquals(2, refsChangedEvents); } } @Test public void conflictThanksToDelete() throws IOException { - writeLooseRef("refs/heads/master", A); - writeLooseRef("refs/heads/masters", B); + writeLooseRefs("refs/heads/master", A, "refs/heads/masters", B); List<ReceiveCommand> cmds = Arrays.asList( new ReceiveCommand(A, B, "refs/heads/master", UPDATE), @@ -297,12 +305,10 @@ public class BatchRefUpdateTest extends LocalDiskRepositoryTestCase { execute(newBatchUpdate(cmds).setAllowNonFastForwards(true)); assertResults(cmds, OK, OK, OK); - assertRefs( - "refs/heads/master", B, - "refs/heads/masters/x", A); + assertRefs("refs/heads/master", B, "refs/heads/masters/x", A); if (atomic) { assertEquals(2, refsChangedEvents); - } else { + } else if (!useReftable) { // The non-atomic case actually produces 5 events, but that's an // implementation detail. We expect at least 4 events, one for the // initial read due to writeLooseRef(), and then one for each @@ -315,8 +321,8 @@ public class BatchRefUpdateTest extends LocalDiskRepositoryTestCase { public void updateToMissingObject() throws IOException { writeLooseRef("refs/heads/master", A); - ObjectId bad = - ObjectId.fromString("deadbeefdeadbeefdeadbeefdeadbeefdeadbeef"); + ObjectId bad = ObjectId + .fromString("deadbeefdeadbeefdeadbeefdeadbeefdeadbeef"); List<ReceiveCommand> cmds = Arrays.asList( new ReceiveCommand(A, bad, "refs/heads/master", UPDATE), new ReceiveCommand(zeroId(), B, "refs/heads/foo2", CREATE)); @@ -328,9 +334,7 @@ public class BatchRefUpdateTest extends LocalDiskRepositoryTestCase { assertEquals(1, refsChangedEvents); } else { assertResults(cmds, REJECTED_MISSING_OBJECT, OK); - assertRefs( - "refs/heads/master", A, - "refs/heads/foo2", B); + assertRefs("refs/heads/master", A, "refs/heads/foo2", B); assertEquals(2, refsChangedEvents); } } @@ -339,8 +343,8 @@ public class BatchRefUpdateTest extends LocalDiskRepositoryTestCase { public void addMissingObject() throws IOException { writeLooseRef("refs/heads/master", A); - ObjectId bad = - ObjectId.fromString("deadbeefdeadbeefdeadbeefdeadbeefdeadbeef"); + ObjectId bad = ObjectId + .fromString("deadbeefdeadbeefdeadbeefdeadbeefdeadbeef"); List<ReceiveCommand> cmds = Arrays.asList( new ReceiveCommand(A, B, "refs/heads/master", UPDATE), new ReceiveCommand(zeroId(), bad, "refs/heads/foo2", CREATE)); @@ -390,9 +394,7 @@ public class BatchRefUpdateTest extends LocalDiskRepositoryTestCase { assertEquals(1, refsChangedEvents); } else { assertResults(cmds, LOCK_FAILURE, OK); - assertRefs( - "refs/heads/master", A, - "refs/heads/foo2", B); + assertRefs("refs/heads/master", A, "refs/heads/foo2", B); assertEquals(2, refsChangedEvents); } } @@ -421,9 +423,10 @@ public class BatchRefUpdateTest extends LocalDiskRepositoryTestCase { public void noRefLog() throws IOException { writeRef("refs/heads/master", A); - Map<String, ReflogEntry> oldLogs = - getLastReflogs("refs/heads/master", "refs/heads/branch"); - assertEquals(Collections.singleton("refs/heads/master"), oldLogs.keySet()); + Map<String, ReflogEntry> oldLogs = getLastReflogs("refs/heads/master", + "refs/heads/branch"); + assertEquals(Collections.singleton("refs/heads/master"), + oldLogs.keySet()); List<ReceiveCommand> cmds = Arrays.asList( new ReceiveCommand(A, B, "refs/heads/master", UPDATE), @@ -431,10 +434,8 @@ public class BatchRefUpdateTest extends LocalDiskRepositoryTestCase { execute(newBatchUpdate(cmds).setAllowNonFastForwards(true)); assertResults(cmds, OK, OK); - assertRefs( - "refs/heads/master", B, - "refs/heads/branch", B); - assertEquals(atomic ? 2 : 3, refsChangedEvents); + assertRefs("refs/heads/master", B, "refs/heads/branch", B); + assertEquals(batchesRefUpdates() ? 2 : 3, refsChangedEvents); assertReflogUnchanged(oldLogs, "refs/heads/master"); assertReflogUnchanged(oldLogs, "refs/heads/branch"); } @@ -444,24 +445,19 @@ public class BatchRefUpdateTest extends LocalDiskRepositoryTestCase { writeRef("refs/heads/master", A); writeRef("refs/heads/branch2", A); - Map<String, ReflogEntry> oldLogs = getLastReflogs( - "refs/heads/master", "refs/heads/branch1", "refs/heads/branch2"); + Map<String, ReflogEntry> oldLogs = getLastReflogs("refs/heads/master", + "refs/heads/branch1", "refs/heads/branch2"); List<ReceiveCommand> cmds = Arrays.asList( new ReceiveCommand(A, B, "refs/heads/master", UPDATE), new ReceiveCommand(zeroId(), B, "refs/heads/branch1", CREATE)); - execute( - newBatchUpdate(cmds) - .setAllowNonFastForwards(true) - .setRefLogMessage("a reflog", false)); + execute(newBatchUpdate(cmds).setAllowNonFastForwards(true) + .setRefLogMessage("a reflog", false)); assertResults(cmds, OK, OK); - assertRefs( - "refs/heads/master", B, - "refs/heads/branch1", B, + assertRefs("refs/heads/master", B, "refs/heads/branch1", B, "refs/heads/branch2", A); - assertEquals(atomic ? 3 : 4, refsChangedEvents); - assertReflogEquals( - reflog(A, B, new PersonIdent(diskRepo), "a reflog"), + assertEquals(batchesRefUpdates() ? 3 : 4, refsChangedEvents); + assertReflogEquals(reflog(A, B, new PersonIdent(diskRepo), "a reflog"), getLastReflog("refs/heads/master")); assertReflogEquals( reflog(zeroId(), B, new PersonIdent(diskRepo), "a reflog"), @@ -476,21 +472,19 @@ public class BatchRefUpdateTest extends LocalDiskRepositoryTestCase { List<ReceiveCommand> cmds = Arrays.asList( new ReceiveCommand(A, B, "refs/heads/master", UPDATE), - new ReceiveCommand(B, A, "refs/heads/branch1", UPDATE_NONFASTFORWARD), + new ReceiveCommand(B, A, "refs/heads/branch1", + UPDATE_NONFASTFORWARD), new ReceiveCommand(zeroId(), A, "refs/heads/branch2", CREATE)); - execute( - newBatchUpdate(cmds) - .setAllowNonFastForwards(true) - .setRefLogMessage(null, true)); + execute(newBatchUpdate(cmds).setAllowNonFastForwards(true) + .setRefLogMessage(null, true)); assertResults(cmds, OK, OK, OK); - assertRefs( - "refs/heads/master", B, - "refs/heads/branch1", A, + assertRefs("refs/heads/master", B, "refs/heads/branch1", A, "refs/heads/branch2", A); - assertEquals(atomic ? 3 : 5, refsChangedEvents); + assertEquals(batchesRefUpdates() ? 3 : 5, refsChangedEvents); assertReflogEquals( - // Always forced; setAllowNonFastForwards(true) bypasses the check. + // Always forced; setAllowNonFastForwards(true) bypasses the + // check. reflog(A, B, new PersonIdent(diskRepo), "forced-update"), getLastReflog("refs/heads/master")); assertReflogEquals( @@ -505,8 +499,8 @@ public class BatchRefUpdateTest extends LocalDiskRepositoryTestCase { public void reflogAppendStatusFastForward() throws IOException { writeRef("refs/heads/master", A); - List<ReceiveCommand> cmds = Arrays.asList( - new ReceiveCommand(A, B, "refs/heads/master", UPDATE)); + List<ReceiveCommand> cmds = Arrays + .asList(new ReceiveCommand(A, B, "refs/heads/master", UPDATE)); execute(newBatchUpdate(cmds).setRefLogMessage(null, true)); assertResults(cmds, OK); @@ -527,15 +521,15 @@ public class BatchRefUpdateTest extends LocalDiskRepositoryTestCase { execute(newBatchUpdate(cmds).setRefLogMessage("a reflog", true)); assertResults(cmds, OK, OK); - assertRefs( - "refs/heads/master", B, - "refs/heads/branch", A); - assertEquals(atomic ? 2 : 3, refsChangedEvents); + assertRefs("refs/heads/master", B, "refs/heads/branch", A); + assertEquals(batchesRefUpdates() ? 2 : 3, refsChangedEvents); assertReflogEquals( - reflog(A, B, new PersonIdent(diskRepo), "a reflog: fast-forward"), + reflog(A, B, new PersonIdent(diskRepo), + "a reflog: fast-forward"), getLastReflog("refs/heads/master")); assertReflogEquals( - reflog(zeroId(), A, new PersonIdent(diskRepo), "a reflog: created"), + reflog(zeroId(), A, new PersonIdent(diskRepo), + "a reflog: created"), getLastReflog("refs/heads/branch")); } @@ -546,33 +540,26 @@ public class BatchRefUpdateTest extends LocalDiskRepositoryTestCase { List<ReceiveCommand> cmds = Arrays.asList( new ReceiveCommand(A, B, "refs/heads/master", UPDATE), new ReceiveCommand(zeroId(), B, "refs/heads/branch", CREATE)); - PersonIdent ident = new PersonIdent("A Reflog User", "reflog@example.com"); - execute( - newBatchUpdate(cmds) - .setRefLogMessage("a reflog", false) - .setRefLogIdent(ident)); + PersonIdent ident = new PersonIdent("A Reflog User", + "reflog@example.com"); + execute(newBatchUpdate(cmds).setRefLogMessage("a reflog", false) + .setRefLogIdent(ident)); assertResults(cmds, OK, OK); - assertEquals(atomic ? 2 : 3, refsChangedEvents); - assertRefs( - "refs/heads/master", B, - "refs/heads/branch", B); - assertReflogEquals( - reflog(A, B, ident, "a reflog"), - getLastReflog("refs/heads/master"), - true); - assertReflogEquals( - reflog(zeroId(), B, ident, "a reflog"), - getLastReflog("refs/heads/branch"), - true); + assertEquals(batchesRefUpdates() ? 2 : 3, refsChangedEvents); + assertRefs("refs/heads/master", B, "refs/heads/branch", B); + assertReflogEquals(reflog(A, B, ident, "a reflog"), + getLastReflog("refs/heads/master"), true); + assertReflogEquals(reflog(zeroId(), B, ident, "a reflog"), + getLastReflog("refs/heads/branch"), true); } @Test public void reflogDelete() throws IOException { writeRef("refs/heads/master", A); writeRef("refs/heads/branch", A); - assertEquals( - 2, getLastReflogs("refs/heads/master", "refs/heads/branch").size()); + assertEquals(2, getLastReflogs("refs/heads/master", "refs/heads/branch") + .size()); List<ReceiveCommand> cmds = Arrays.asList( new ReceiveCommand(A, zeroId(), "refs/heads/master", DELETE), @@ -581,10 +568,16 @@ public class BatchRefUpdateTest extends LocalDiskRepositoryTestCase { assertResults(cmds, OK, OK); assertRefs("refs/heads/branch", B); - assertEquals(atomic ? 3 : 4, refsChangedEvents); - assertNull(getLastReflog("refs/heads/master")); - assertReflogEquals( - reflog(A, B, new PersonIdent(diskRepo), "a reflog"), + assertEquals(batchesRefUpdates() ? 3 : 4, refsChangedEvents); + if (useReftable) { + // reftable retains reflog entries for deleted branches. + assertReflogEquals( + reflog(A, zeroId(), new PersonIdent(diskRepo), "a reflog"), + getLastReflog("refs/heads/master")); + } else { + assertNull(getLastReflog("refs/heads/master")); + } + assertReflogEquals(reflog(A, B, new PersonIdent(diskRepo), "a reflog"), getLastReflog("refs/heads/branch")); } @@ -599,8 +592,11 @@ public class BatchRefUpdateTest extends LocalDiskRepositoryTestCase { assertResults(cmds, OK, OK); assertRefs("refs/heads/master/x", A); - assertEquals(atomic ? 2 : 3, refsChangedEvents); - assertNull(getLastReflog("refs/heads/master")); + assertEquals(batchesRefUpdates() ? 2 : 3, refsChangedEvents); + if (!useReftable) { + // reftable retains reflog entries for deleted branches. + assertNull(getLastReflog("refs/heads/master")); + } assertReflogEquals( reflog(zeroId(), A, new PersonIdent(diskRepo), "a reflog"), getLastReflog("refs/heads/master/x")); @@ -610,8 +606,8 @@ public class BatchRefUpdateTest extends LocalDiskRepositoryTestCase { public void reflogOnLockFailure() throws IOException { writeRef("refs/heads/master", A); - Map<String, ReflogEntry> oldLogs = - getLastReflogs("refs/heads/master", "refs/heads/branch"); + Map<String, ReflogEntry> oldLogs = getLastReflogs("refs/heads/master", + "refs/heads/branch"); List<ReceiveCommand> cmds = Arrays.asList( new ReceiveCommand(A, B, "refs/heads/master", UPDATE), @@ -642,29 +638,23 @@ public class BatchRefUpdateTest extends LocalDiskRepositoryTestCase { new ReceiveCommand(zeroId(), B, "refs/heads/branch", CREATE)); cmds.get(0).setRefLogMessage("custom log", false); PersonIdent ident = new PersonIdent(diskRepo); - execute( - newBatchUpdate(cmds) - .setRefLogIdent(ident) - .setRefLogMessage("a reflog", true)); + execute(newBatchUpdate(cmds).setRefLogIdent(ident) + .setRefLogMessage("a reflog", true)); assertResults(cmds, OK, OK); - assertEquals(atomic ? 2 : 3, refsChangedEvents); - assertReflogEquals( - reflog(A, B, ident, "custom log"), - getLastReflog("refs/heads/master"), - true); - assertReflogEquals( - reflog(zeroId(), B, ident, "a reflog: created"), - getLastReflog("refs/heads/branch"), - true); + assertEquals(batchesRefUpdates() ? 2 : 3, refsChangedEvents); + assertReflogEquals(reflog(A, B, ident, "custom log"), + getLastReflog("refs/heads/master"), true); + assertReflogEquals(reflog(zeroId(), B, ident, "a reflog: created"), + getLastReflog("refs/heads/branch"), true); } @Test public void overrideDisableRefLog() throws Exception { writeRef("refs/heads/master", A); - Map<String, ReflogEntry> oldLogs = - getLastReflogs("refs/heads/master", "refs/heads/branch"); + Map<String, ReflogEntry> oldLogs = getLastReflogs("refs/heads/master", + "refs/heads/branch"); List<ReceiveCommand> cmds = Arrays.asList( new ReceiveCommand(A, B, "refs/heads/master", UPDATE), @@ -673,20 +663,22 @@ public class BatchRefUpdateTest extends LocalDiskRepositoryTestCase { execute(newBatchUpdate(cmds).setRefLogMessage("a reflog", true)); assertResults(cmds, OK, OK); - assertEquals(atomic ? 2 : 3, refsChangedEvents); + assertEquals(batchesRefUpdates() ? 2 : 3, refsChangedEvents); assertReflogUnchanged(oldLogs, "refs/heads/master"); assertReflogEquals( - reflog(zeroId(), B, new PersonIdent(diskRepo), "a reflog: created"), + reflog(zeroId(), B, new PersonIdent(diskRepo), + "a reflog: created"), getLastReflog("refs/heads/branch")); } @Test public void refLogNotWrittenWithoutConfigOption() throws Exception { + assumeFalse(useReftable); setLogAllRefUpdates(false); writeRef("refs/heads/master", A); - Map<String, ReflogEntry> oldLogs = - getLastReflogs("refs/heads/master", "refs/heads/branch"); + Map<String, ReflogEntry> oldLogs = getLastReflogs("refs/heads/master", + "refs/heads/branch"); assertTrue(oldLogs.isEmpty()); List<ReceiveCommand> cmds = Arrays.asList( @@ -701,22 +693,20 @@ public class BatchRefUpdateTest extends LocalDiskRepositoryTestCase { @Test public void forceRefLogInUpdate() throws Exception { + assumeFalse(useReftable); setLogAllRefUpdates(false); writeRef("refs/heads/master", A); - assertTrue( - getLastReflogs("refs/heads/master", "refs/heads/branch").isEmpty()); + assertTrue(getLastReflogs("refs/heads/master", "refs/heads/branch") + .isEmpty()); List<ReceiveCommand> cmds = Arrays.asList( new ReceiveCommand(A, B, "refs/heads/master", UPDATE), new ReceiveCommand(zeroId(), B, "refs/heads/branch", CREATE)); - execute( - newBatchUpdate(cmds) - .setRefLogMessage("a reflog", false) - .setForceRefLog(true)); + execute(newBatchUpdate(cmds).setRefLogMessage("a reflog", false) + .setForceRefLog(true)); assertResults(cmds, OK, OK); - assertReflogEquals( - reflog(A, B, new PersonIdent(diskRepo), "a reflog"), + assertReflogEquals(reflog(A, B, new PersonIdent(diskRepo), "a reflog"), getLastReflog("refs/heads/master")); assertReflogEquals( reflog(zeroId(), B, new PersonIdent(diskRepo), "a reflog"), @@ -725,11 +715,12 @@ public class BatchRefUpdateTest extends LocalDiskRepositoryTestCase { @Test public void forceRefLogInCommand() throws Exception { + assumeFalse(useReftable); setLogAllRefUpdates(false); writeRef("refs/heads/master", A); - Map<String, ReflogEntry> oldLogs = - getLastReflogs("refs/heads/master", "refs/heads/branch"); + Map<String, ReflogEntry> oldLogs = getLastReflogs("refs/heads/master", + "refs/heads/branch"); assertTrue(oldLogs.isEmpty()); List<ReceiveCommand> cmds = Arrays.asList( @@ -747,6 +738,8 @@ public class BatchRefUpdateTest extends LocalDiskRepositoryTestCase { @Test public void packedRefsLockFailure() throws Exception { + assumeFalse(useReftable); + writeLooseRef("refs/heads/master", A); List<ReceiveCommand> cmds = Arrays.asList( @@ -765,11 +758,10 @@ public class BatchRefUpdateTest extends LocalDiskRepositoryTestCase { assertRefs("refs/heads/master", A); assertEquals(1, refsChangedEvents); } else { - // Only operates on loose refs, doesn't care that packed-refs is locked. + // Only operates on loose refs, doesn't care that packed-refs is + // locked. assertResults(cmds, OK, OK); - assertRefs( - "refs/heads/master", B, - "refs/heads/branch", B); + assertRefs("refs/heads/master", B, "refs/heads/branch", B); assertEquals(3, refsChangedEvents); } } finally { @@ -779,6 +771,8 @@ public class BatchRefUpdateTest extends LocalDiskRepositoryTestCase { @Test public void oneRefLockFailure() throws Exception { + assumeFalse(useReftable); + writeLooseRef("refs/heads/master", A); List<ReceiveCommand> cmds = Arrays.asList( @@ -799,9 +793,7 @@ public class BatchRefUpdateTest extends LocalDiskRepositoryTestCase { assertEquals(1, refsChangedEvents); } else { assertResults(cmds, OK, LOCK_FAILURE); - assertRefs( - "refs/heads/branch", B, - "refs/heads/master", A); + assertRefs("refs/heads/branch", B, "refs/heads/master", A); assertEquals(2, refsChangedEvents); } } finally { @@ -811,10 +803,11 @@ public class BatchRefUpdateTest extends LocalDiskRepositoryTestCase { @Test public void singleRefUpdateDoesNotRequirePackedRefsLock() throws Exception { + assumeFalse(useReftable); writeLooseRef("refs/heads/master", A); - List<ReceiveCommand> cmds = Arrays.asList( - new ReceiveCommand(A, B, "refs/heads/master", UPDATE)); + List<ReceiveCommand> cmds = Arrays + .asList(new ReceiveCommand(A, B, "refs/heads/master", UPDATE)); LockFile myLock = refdir.lockPackedRefs(); try { @@ -832,6 +825,7 @@ public class BatchRefUpdateTest extends LocalDiskRepositoryTestCase { @Test public void atomicUpdateRespectsInProcessLock() throws Exception { assumeTrue(atomic); + assumeFalse(useReftable); writeLooseRef("refs/heads/master", A); @@ -854,7 +848,8 @@ public class BatchRefUpdateTest extends LocalDiskRepositoryTestCase { long timeoutSecs = 10; long startNanos = System.nanoTime(); - // Hold onto the lock until we observe the worker thread has attempted to + // Hold onto the lock until we observe the worker thread has + // attempted to // acquire it. while (l.getQueueLength() == 0) { long elapsedNanos = System.nanoTime() - startNanos; @@ -864,7 +859,8 @@ public class BatchRefUpdateTest extends LocalDiskRepositoryTestCase { Thread.sleep(3); } - // Once we unlock, the worker thread should finish the update promptly. + // Once we unlock, the worker thread should finish the update + // promptly. l.unlock(); t.join(SECONDS.toMillis(timeoutSecs)); assertFalse(t.isAlive()); @@ -876,9 +872,7 @@ public class BatchRefUpdateTest extends LocalDiskRepositoryTestCase { assertResults(cmds, OK, OK); assertEquals(2, refsChangedEvents); - assertRefs( - "refs/heads/master", B, - "refs/heads/branch", B); + assertRefs("refs/heads/master", B, "refs/heads/branch", B); } private void setLogAllRefUpdates(boolean enable) throws Exception { @@ -890,7 +884,38 @@ public class BatchRefUpdateTest extends LocalDiskRepositoryTestCase { } private void writeLooseRef(String name, AnyObjectId id) throws IOException { - write(new File(diskRepo.getDirectory(), name), id.name() + "\n"); + if (useReftable) { + writeRef(name, id); + } else { + write(new File(diskRepo.getDirectory(), name), id.name() + "\n"); + } + } + + private void writeLooseRefs(String name1, AnyObjectId id1, String name2, + AnyObjectId id2) throws IOException { + if (useReftable) { + BatchRefUpdate bru = diskRepo.getRefDatabase().newBatchUpdate(); + + Ref r1 = diskRepo.exactRef(name1); + ReceiveCommand c1 = new ReceiveCommand( + r1 != null ? r1.getObjectId() : ObjectId.zeroId(), + id1.toObjectId(), name1, r1 == null ? CREATE : UPDATE); + + Ref r2 = diskRepo.exactRef(name2); + ReceiveCommand c2 = new ReceiveCommand( + r2 != null ? r2.getObjectId() : ObjectId.zeroId(), + id2.toObjectId(), name2, r2 == null ? CREATE : UPDATE); + + bru.addCommand(c1, c2); + try (RevWalk rw = new RevWalk(diskRepo)) { + bru.execute(rw, NullProgressMonitor.INSTANCE); + } + assertEquals(c2.getResult(), ReceiveCommand.Result.OK); + assertEquals(c1.getResult(), ReceiveCommand.Result.OK); + } else { + writeLooseRef(name1, id1); + writeLooseRef(name2, id2); + } } private void writeRef(String name, AnyObjectId id) throws IOException { @@ -900,16 +925,16 @@ public class BatchRefUpdateTest extends LocalDiskRepositoryTestCase { u.setNewObjectId(id); RefUpdate.Result r = u.update(); switch (r) { - case NEW: - case FORCED: - return; - default: - throw new IOException("Got " + r + " while updating " + name); + case NEW: + case FORCED: + return; + default: + throw new IOException("Got " + r + " while updating " + name); } } private BatchRefUpdate newBatchUpdate(List<ReceiveCommand> cmds) { - BatchRefUpdate u = refdir.newBatchUpdate(); + BatchRefUpdate u = diskRepo.getRefDatabase().newBatchUpdate(); if (atomic) { assertTrue(u.isAtomic()); } else { @@ -923,10 +948,11 @@ public class BatchRefUpdateTest extends LocalDiskRepositoryTestCase { execute(u, false); } - private void execute(BatchRefUpdate u, boolean strictWork) throws IOException { + private void execute(BatchRefUpdate u, boolean strictWork) + throws IOException { try (RevWalk rw = new RevWalk(diskRepo)) { - u.execute(rw, - strictWork ? new StrictWorkMonitor() : NullProgressMonitor.INSTANCE); + u.execute(rw, strictWork ? new StrictWorkMonitor() + : NullProgressMonitor.INSTANCE); } } @@ -941,15 +967,18 @@ public class BatchRefUpdateTest extends LocalDiskRepositoryTestCase { expected.put((String) args[i], (AnyObjectId) args[i + 1]); } - Map<String, Ref> refs = refdir.getRefs(RefDatabase.ALL); + Map<String, Ref> refs = diskRepo.getRefDatabase() + .getRefs(RefDatabase.ALL); Ref actualHead = refs.remove(Constants.HEAD); if (actualHead != null) { String actualLeafName = actualHead.getLeaf().getName(); assertEquals( - "expected HEAD to point to refs/heads/master, got: " + actualLeafName, + "expected HEAD to point to refs/heads/master, got: " + + actualLeafName, "refs/heads/master", actualLeafName); AnyObjectId expectedMaster = expected.get("refs/heads/master"); - assertNotNull("expected master ref since HEAD exists", expectedMaster); + assertNotNull("expected master ref since HEAD exists", + expectedMaster); assertEquals(expectedMaster, actualHead.getObjectId()); } @@ -961,11 +990,11 @@ public class BatchRefUpdateTest extends LocalDiskRepositoryTestCase { } enum Result { - OK(ReceiveCommand.Result.OK), - LOCK_FAILURE(ReceiveCommand.Result.LOCK_FAILURE), - REJECTED_NONFASTFORWARD(ReceiveCommand.Result.REJECTED_NONFASTFORWARD), - REJECTED_MISSING_OBJECT(ReceiveCommand.Result.REJECTED_MISSING_OBJECT), - TRANSACTION_ABORTED(ReceiveCommand::isTransactionAborted); + OK(ReceiveCommand.Result.OK), LOCK_FAILURE( + ReceiveCommand.Result.LOCK_FAILURE), REJECTED_NONFASTFORWARD( + ReceiveCommand.Result.REJECTED_NONFASTFORWARD), REJECTED_MISSING_OBJECT( + ReceiveCommand.Result.REJECTED_MISSING_OBJECT), TRANSACTION_ABORTED( + ReceiveCommand::isTransactionAborted); @SuppressWarnings("ImmutableEnumChecker") final Predicate<? super ReceiveCommand> p; @@ -979,8 +1008,7 @@ public class BatchRefUpdateTest extends LocalDiskRepositoryTestCase { } } - private void assertResults( - List<ReceiveCommand> cmds, Result... expected) { + private void assertResults(List<ReceiveCommand> cmds, Result... expected) { if (expected.length != cmds.size()) { throw new IllegalArgumentException( "expected " + cmds.size() + " result args"); @@ -988,12 +1016,10 @@ public class BatchRefUpdateTest extends LocalDiskRepositoryTestCase { for (int i = 0; i < cmds.size(); i++) { ReceiveCommand c = cmds.get(i); Result r = expected[i]; - assertTrue( - String.format( - "result of command (%d) should be %s: %s %s%s", - Integer.valueOf(i), r, c, - c.getResult(), - c.getMessage() != null ? " (" + c.getMessage() + ")" : ""), + assertTrue(String.format( + "result of command (%d) should be %s, got %s %s%s", + Integer.valueOf(i), r, c, c.getResult(), + c.getMessage() != null ? " (" + c.getMessage() + ")" : ""), r.p.test(c)); } } @@ -1022,18 +1048,18 @@ public class BatchRefUpdateTest extends LocalDiskRepositoryTestCase { return LockFile.getLockFile(refdir.fileFor(refName)); } - private void assertReflogUnchanged( - Map<String, ReflogEntry> old, String name) throws IOException { + private void assertReflogUnchanged(Map<String, ReflogEntry> old, + String name) throws IOException { assertReflogEquals(old.get(name), getLastReflog(name), true); } - private static void assertReflogEquals( - ReflogEntry expected, ReflogEntry actual) { + private static void assertReflogEquals(ReflogEntry expected, + ReflogEntry actual) { assertReflogEquals(expected, actual, false); } - private static void assertReflogEquals( - ReflogEntry expected, ReflogEntry actual, boolean strictTime) { + private static void assertReflogEquals(ReflogEntry expected, + ReflogEntry actual, boolean strictTime) { if (expected == null) { assertNull(actual); return; @@ -1044,9 +1070,9 @@ public class BatchRefUpdateTest extends LocalDiskRepositoryTestCase { if (strictTime) { assertEquals(expected.getWho(), actual.getWho()); } else { - assertEquals(expected.getWho().getName(), actual.getWho().getName()); - assertEquals( - expected.getWho().getEmailAddress(), + assertEquals(expected.getWho().getName(), + actual.getWho().getName()); + assertEquals(expected.getWho().getEmailAddress(), actual.getWho().getEmailAddress()); } assertEquals(expected.getComment(), actual.getComment()); @@ -1081,4 +1107,8 @@ public class BatchRefUpdateTest extends LocalDiskRepositoryTestCase { } }; } + + private boolean batchesRefUpdates() { + return atomic || useReftable; + } } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/FileReftableStackTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/FileReftableStackTest.java new file mode 100644 index 0000000000..a2710e1534 --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/FileReftableStackTest.java @@ -0,0 +1,203 @@ +/* + * Copyright (C) 2019 Google LLC + * 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.file; + +import static org.eclipse.jgit.lib.Ref.Storage.PACKED; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; +import org.eclipse.jgit.internal.storage.file.FileReftableStack.Segment; +import org.eclipse.jgit.internal.storage.reftable.MergedReftable; +import org.eclipse.jgit.internal.storage.reftable.RefCursor; +import org.eclipse.jgit.lib.Config; +import org.eclipse.jgit.lib.ObjectId; +import org.eclipse.jgit.lib.ObjectIdRef; +import org.eclipse.jgit.lib.Ref; +import org.eclipse.jgit.util.FileUtils; +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +public class FileReftableStackTest { + + private static Ref newRef(String name, ObjectId id) { + return new ObjectIdRef.PeeledNonTag(PACKED, name, id); + } + + private File reftableDir; + + @Before + public void setup() throws Exception { + reftableDir = FileUtils.createTempDir("rtstack", "", null); + } + + @After + public void tearDown() throws Exception { + if (reftableDir != null) { + FileUtils.delete(reftableDir, FileUtils.RECURSIVE); + } + } + + void writeBranches(FileReftableStack stack, String template, int start, + int N) throws IOException { + for (int i = 0; i < N; i++) { + while (true) { + final long next = stack.getMergedReftable().maxUpdateIndex() + + 1; + + String name = String.format(template, + Integer.valueOf(start + i)); + Ref r = newRef(name, ObjectId.zeroId()); + boolean ok = stack.addReftable(rw -> { + rw.setMinUpdateIndex(next).setMaxUpdateIndex(next).begin() + .writeRef(r); + }); + if (ok) { + break; + } + } + } + } + + public void testCompaction(int N) throws Exception { + try (FileReftableStack stack = new FileReftableStack( + new File(reftableDir, "refs"), reftableDir, null, + () -> new Config())) { + writeBranches(stack, "refs/heads/branch%d", 0, N); + MergedReftable table = stack.getMergedReftable(); + for (int i = 1; i < N; i++) { + String name = String.format("refs/heads/branch%d", + Integer.valueOf(i)); + RefCursor c = table.seekRef(name); + assertTrue(c.next()); + assertEquals(ObjectId.zeroId(), c.getRef().getObjectId()); + } + + List<String> files = Arrays.asList(reftableDir.listFiles()).stream() + .map(File::getName).collect(Collectors.toList()); + Collections.sort(files); + + assertTrue(files.size() < 20); + + FileReftableStack.CompactionStats stats = stack.getStats(); + assertEquals(0, stats.failed); + assertTrue(stats.attempted < N); + assertTrue(stats.refCount < FileReftableStack.log(N) * N); + } + } + + @Test + public void testCompaction9() throws Exception { + testCompaction(9); + } + + @Test + public void testCompaction1024() throws Exception { + testCompaction(1024); + } + + @Rule + public final ExpectedException thrown = ExpectedException.none(); + + @SuppressWarnings({ "resource", "unused" }) + @Test + public void missingReftable() throws Exception { + try (FileReftableStack stack = new FileReftableStack( + new File(reftableDir, "refs"), reftableDir, null, + () -> new Config())) { + outer: for (int i = 0; i < 10; i++) { + final long next = stack.getMergedReftable().maxUpdateIndex() + + 1; + String name = String.format("branch%d", Integer.valueOf(i)); + Ref r = newRef(name, ObjectId.zeroId()); + boolean ok = stack.addReftable(rw -> { + rw.setMinUpdateIndex(next).setMaxUpdateIndex(next).begin() + .writeRef(r); + }); + assertTrue(ok); + + List<File> files = Arrays.asList(reftableDir.listFiles()); + for (int j = 0; j < files.size(); j++) { + File f = files.get(j); + if (f.getName().endsWith(".ref")) { + assertTrue(f.delete()); + break outer; + } + } + } + } + thrown.expect(FileNotFoundException.class); + new FileReftableStack(new File(reftableDir, "refs"), reftableDir, null, + () -> new Config()); + } + + @Test + public void testSegments() { + long in[] = { 1024, 1024, 1536, 100, 64, 50, 25, 24 }; + List<Segment> got = FileReftableStack.segmentSizes(in); + Segment want[] = { new Segment(0, 3, 10, 3584), + new Segment(3, 5, 6, 164), new Segment(5, 6, 5, 50), + new Segment(6, 8, 4, 49), }; + assertEquals(got.size(), want.length); + for (int i = 0; i < want.length; i++) { + assertTrue(want[i].equals(got.get(i))); + } + } + + @Test + public void testLog2() throws Exception { + assertEquals(10, FileReftableStack.log(1024)); + assertEquals(10, FileReftableStack.log(1025)); + assertEquals(10, FileReftableStack.log(2047)); + } +} diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/FileReftableTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/FileReftableTest.java new file mode 100644 index 0000000000..cdc64fa1b2 --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/FileReftableTest.java @@ -0,0 +1,568 @@ +/* + * Copyright (C) 2019, 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.file; + +import static org.eclipse.jgit.lib.RefUpdate.Result.FAST_FORWARD; +import static org.eclipse.jgit.lib.RefUpdate.Result.FORCED; +import static org.eclipse.jgit.lib.RefUpdate.Result.IO_FAILURE; +import static org.eclipse.jgit.lib.RefUpdate.Result.LOCK_FAILURE; +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.assertNotSame; +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.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.jgit.lib.AnyObjectId; +import org.eclipse.jgit.lib.Constants; +import org.eclipse.jgit.lib.NullProgressMonitor; +import org.eclipse.jgit.lib.ObjectId; +import org.eclipse.jgit.lib.PersonIdent; +import org.eclipse.jgit.lib.Ref; +import org.eclipse.jgit.lib.RefRename; +import org.eclipse.jgit.lib.RefUpdate; +import org.eclipse.jgit.lib.RefUpdate.Result; +import org.eclipse.jgit.lib.ReflogEntry; +import org.eclipse.jgit.lib.ReflogReader; +import org.eclipse.jgit.lib.RepositoryCache; +import org.eclipse.jgit.revwalk.RevWalk; +import org.eclipse.jgit.test.resources.SampleDataRepositoryTestCase; +import org.eclipse.jgit.transport.ReceiveCommand; +import org.junit.Test; + +public class FileReftableTest extends SampleDataRepositoryTestCase { + String bCommit; + + @Override + public void setUp() throws Exception { + super.setUp(); + Ref b = db.exactRef("refs/heads/b"); + bCommit = b.getObjectId().getName(); + db.convertToReftable(false, false); + } + + @SuppressWarnings("boxing") + @Test + public void testRacyReload() throws Exception { + ObjectId id = db.resolve("master"); + int retry = 0; + try (FileRepository repo1 = new FileRepository(db.getDirectory()); + FileRepository repo2 = new FileRepository(db.getDirectory())) { + FileRepository repos[] = { repo1, repo2 }; + for (int i = 0; i < 10; i++) { + for (int j = 0; j < 2; j++) { + FileRepository repo = repos[j]; + RefUpdate u = repo.getRefDatabase().newUpdate( + String.format("branch%d", i * 10 + j), false); + + u.setNewObjectId(id); + RefUpdate.Result r = u.update(); + if (!r.equals(Result.NEW)) { + retry++; + u = repo.getRefDatabase().newUpdate( + String.format("branch%d", i * 10 + j), false); + + u.setNewObjectId(id); + r = u.update(); + assertEquals(r, Result.NEW); + } + } + } + + // only the first one succeeds + assertEquals(retry, 19); + } + } + + @Test + public void additionalRefsAreRemoved() { + assertFalse(new File(db.getDirectory(), Constants.HEAD).exists()); + } + + @Test + public void testCompactFully() throws Exception { + ObjectId c1 = db.resolve("master^^"); + ObjectId c2 = db.resolve("master^"); + for (int i = 0; i < 5; i++) { + RefUpdate u = db.updateRef("refs/heads/master"); + u.setForceUpdate(true); + u.setNewObjectId((i%2) == 0 ? c1 : c2); + assertEquals(u.update(), FORCED); + } + + File tableDir = new File(db.getDirectory(), Constants.REFTABLE); + assertTrue(tableDir.listFiles().length > 1); + ((FileReftableDatabase)db.getRefDatabase()).compactFully(); + assertEquals(tableDir.listFiles().length,1); + } + + @Test + public void testConvert() throws Exception { + Ref h = db.exactRef("HEAD"); + assertTrue(h.isSymbolic()); + assertEquals("refs/heads/master", h.getTarget().getName()); + + Ref b = db.exactRef("refs/heads/b"); + assertFalse(b.isSymbolic()); + assertTrue(b.isPeeled()); + assertEquals(bCommit, b.getObjectId().name()); + + assertTrue(db.getRefDatabase().hasFastTipsWithSha1()); + } + + @Test + public void testConvertToRefdir() throws Exception { + db.convertToPackedRefs(false); + assertTrue(db.getRefDatabase() instanceof RefDirectory); + Ref h = db.exactRef("HEAD"); + assertTrue(h.isSymbolic()); + assertEquals("refs/heads/master", h.getTarget().getName()); + + Ref b = db.exactRef("refs/heads/b"); + assertFalse(b.isSymbolic()); + assertTrue(b.isPeeled()); + assertEquals(bCommit, b.getObjectId().name()); + + assertFalse(db.getRefDatabase().hasFastTipsWithSha1()); + } + + @Test + public void testBatchrefUpdate() throws Exception { + ObjectId cur = db.resolve("master"); + ObjectId prev = db.resolve("master^"); + + PersonIdent person = new PersonIdent("name", "mail@example.com"); + ReceiveCommand rc1 = new ReceiveCommand(ObjectId.zeroId(), cur, "refs/heads/batch1"); + ReceiveCommand rc2 = new ReceiveCommand(ObjectId.zeroId(), prev, "refs/heads/batch2"); + String msg = "message"; + try (RevWalk rw = new RevWalk(db)) { + db.getRefDatabase().newBatchUpdate() + .addCommand(rc1, rc2) + .setAtomic(true) + .setRefLogIdent(person) + .setRefLogMessage(msg, false) + .execute(rw, NullProgressMonitor.INSTANCE); + } + + assertEquals(rc1.getResult(), ReceiveCommand.Result.OK); + assertEquals(rc2.getResult(), ReceiveCommand.Result.OK); + + ReflogEntry e = db.getReflogReader("refs/heads/batch1").getLastEntry(); + assertEquals(msg, e.getComment()); + assertEquals(person, e.getWho()); + assertEquals(cur, e.getNewId()); + + e = db.getReflogReader("refs/heads/batch2").getLastEntry(); + assertEquals(msg, e.getComment()); + assertEquals(person, e.getWho()); + assertEquals(prev, e.getNewId()); + + assertEquals(cur, db.exactRef("refs/heads/batch1").getObjectId()); + assertEquals(prev, db.exactRef("refs/heads/batch2").getObjectId()); + } + + @Test + public void testFastforwardStatus() throws Exception { + ObjectId cur = db.resolve("master"); + ObjectId prev = db.resolve("master^"); + RefUpdate u = db.updateRef("refs/heads/master"); + + u.setNewObjectId(prev); + u.setForceUpdate(true); + assertEquals(FORCED, u.update()); + + RefUpdate u2 = db.updateRef("refs/heads/master"); + + u2.setNewObjectId(cur); + assertEquals(FAST_FORWARD, u2.update()); + } + + @Test + public void testUpdateChecksOldValue() throws Exception { + ObjectId cur = db.resolve("master"); + ObjectId prev = db.resolve("master^"); + RefUpdate u1 = db.updateRef("refs/heads/master"); + RefUpdate u2 = db.updateRef("refs/heads/master"); + + u1.setExpectedOldObjectId(cur); + u1.setNewObjectId(prev); + u1.setForceUpdate(true); + + u2.setExpectedOldObjectId(cur); + u2.setNewObjectId(prev); + u2.setForceUpdate(true); + + assertEquals(FORCED, u1.update()); + assertEquals(LOCK_FAILURE, u2.update()); + } + + @Test + public void testWritesymref() throws Exception { + writeSymref(Constants.HEAD, "refs/heads/a"); + assertNotNull(db.exactRef("refs/heads/b")); + } + + @Test + public void testFastforwardStatus2() throws Exception { + writeSymref(Constants.HEAD, "refs/heads/a"); + ObjectId bId = db.exactRef("refs/heads/b").getObjectId(); + RefUpdate u = db.updateRef("refs/heads/a"); + u.setNewObjectId(bId); + u.setRefLogMessage("Setup", false); + assertEquals(FAST_FORWARD, u.update()); + } + + @Test + public void testDelete() throws Exception { + RefUpdate up = db.getRefDatabase().newUpdate("refs/heads/a", false); + up.setForceUpdate(true); + RefUpdate.Result res = up.delete(); + assertEquals(res, FORCED); + assertNull(db.exactRef("refs/heads/a")); + } + + @Test + public void testDeleteWithoutHead() throws IOException { + // Prepare repository without HEAD + RefUpdate refUpdate = db.updateRef(Constants.HEAD, true); + refUpdate.setForceUpdate(true); + refUpdate.setNewObjectId(ObjectId.zeroId()); + + RefUpdate.Result updateResult = refUpdate.update(); + assertEquals(FORCED, updateResult); + + Ref r = db.exactRef("HEAD"); + assertEquals(ObjectId.zeroId(), r.getObjectId()); + RefUpdate.Result deleteHeadResult = db.updateRef(Constants.HEAD) + .delete(); + + // why does doDelete say NEW ? + assertEquals(RefUpdate.Result.NO_CHANGE, deleteHeadResult); + + // Any result is ok as long as it's not an NPE + db.updateRef(Constants.R_HEADS + "master").delete(); + } + + @Test + public void testUpdateRefDetached() throws Exception { + ObjectId pid = db.resolve("refs/heads/master"); + ObjectId ppid = db.resolve("refs/heads/master^"); + RefUpdate updateRef = db.updateRef("HEAD", true); + updateRef.setForceUpdate(true); + updateRef.setNewObjectId(ppid); + RefUpdate.Result update = updateRef.update(); + assertEquals(FORCED, update); + assertEquals(ppid, db.resolve("HEAD")); + Ref ref = db.exactRef("HEAD"); + assertEquals("HEAD", ref.getName()); + assertTrue("is detached", !ref.isSymbolic()); + + // the branch HEAD referred to is left untouched + assertEquals(pid, db.resolve("refs/heads/master")); + ReflogReader reflogReader = db.getReflogReader("HEAD"); + ReflogEntry e = reflogReader.getReverseEntries().get(0); + assertEquals(ppid, e.getNewId()); + assertEquals("GIT_COMMITTER_EMAIL", e.getWho().getEmailAddress()); + assertEquals("GIT_COMMITTER_NAME", e.getWho().getName()); + assertEquals(1250379778000L, e.getWho().getWhen().getTime()); + assertEquals(pid, e.getOldId()); + } + + @Test + public void testWriteReflog() throws Exception { + ObjectId pid = db.resolve("refs/heads/master^"); + RefUpdate updateRef = db.updateRef("refs/heads/master"); + updateRef.setNewObjectId(pid); + String msg = "REFLOG!"; + updateRef.setRefLogMessage(msg, true); + PersonIdent person = new PersonIdent("name", "mail@example.com"); + updateRef.setRefLogIdent(person); + updateRef.setForceUpdate(true); + RefUpdate.Result update = updateRef.update(); + assertEquals(FORCED, update); // internal + ReflogReader r = db.getReflogReader("refs/heads/master"); + + ReflogEntry e = r.getLastEntry(); + assertEquals(e.getNewId(), pid); + assertEquals(e.getComment(), "REFLOG!: FORCED"); + assertEquals(e.getWho(), person); + } + + @Test + public void testLooseDelete() throws IOException { + final String newRef = "refs/heads/abc"; + assertNull(db.exactRef(newRef)); + + RefUpdate ref = db.updateRef(newRef); + ObjectId nonZero = db.resolve(Constants.HEAD); + assertNotEquals(nonZero, ObjectId.zeroId()); + ref.setNewObjectId(nonZero); + assertEquals(RefUpdate.Result.NEW, ref.update()); + + ref = db.updateRef(newRef); + ref.setNewObjectId(db.resolve(Constants.HEAD)); + + assertEquals(ref.delete(), RefUpdate.Result.NO_CHANGE); + + // Differs from RefupdateTest. Deleting a loose ref leaves reflog trail. + ReflogReader reader = db.getReflogReader("refs/heads/abc"); + assertEquals(ObjectId.zeroId(), reader.getReverseEntry(1).getOldId()); + assertEquals(nonZero, reader.getReverseEntry(1).getNewId()); + assertEquals(nonZero, reader.getReverseEntry(0).getOldId()); + assertEquals(ObjectId.zeroId(), reader.getReverseEntry(0).getNewId()); + } + + private static class SubclassedId extends ObjectId { + SubclassedId(AnyObjectId src) { + super(src); + } + } + + @Test + public void testNoCacheObjectIdSubclass() throws IOException { + final String newRef = "refs/heads/abc"; + final RefUpdate ru = updateRef(newRef); + final SubclassedId newid = new SubclassedId(ru.getNewObjectId()); + ru.setNewObjectId(newid); + RefUpdate.Result update = ru.update(); + assertEquals(RefUpdate.Result.NEW, update); + Ref r = db.exactRef(newRef); + assertEquals(newRef, r.getName()); + assertNotNull(r.getObjectId()); + assertNotSame(newid, r.getObjectId()); + assertSame(ObjectId.class, r.getObjectId().getClass()); + assertEquals(newid, r.getObjectId()); + List<ReflogEntry> reverseEntries1 = db.getReflogReader("refs/heads/abc") + .getReverseEntries(); + ReflogEntry entry1 = reverseEntries1.get(0); + assertEquals(1, reverseEntries1.size()); + assertEquals(ObjectId.zeroId(), entry1.getOldId()); + assertEquals(r.getObjectId(), entry1.getNewId()); + + assertEquals(new PersonIdent(db).toString(), + entry1.getWho().toString()); + assertEquals("", entry1.getComment()); + List<ReflogEntry> reverseEntries2 = db.getReflogReader("HEAD") + .getReverseEntries(); + assertEquals(0, reverseEntries2.size()); + } + + @Test + public void testDeleteSymref() throws IOException { + RefUpdate dst = updateRef("refs/heads/abc"); + assertEquals(RefUpdate.Result.NEW, dst.update()); + ObjectId id = dst.getNewObjectId(); + + RefUpdate u = db.updateRef("refs/symref"); + assertEquals(RefUpdate.Result.NEW, u.link(dst.getName())); + + Ref ref = db.exactRef(u.getName()); + assertNotNull(ref); + assertTrue(ref.isSymbolic()); + assertEquals(dst.getName(), ref.getLeaf().getName()); + assertEquals(id, ref.getLeaf().getObjectId()); + + u = db.updateRef(u.getName()); + u.setDetachingSymbolicRef(); + u.setForceUpdate(true); + assertEquals(FORCED, u.delete()); + + assertNull(db.exactRef(u.getName())); + ref = db.exactRef(dst.getName()); + assertNotNull(ref); + assertFalse(ref.isSymbolic()); + assertEquals(id, ref.getObjectId()); + } + + @Test + public void writeUnbornHead() throws Exception { + RefUpdate.Result r = db.updateRef("HEAD").link("refs/heads/unborn"); + assertEquals(FORCED, r); + + Ref head = db.exactRef("HEAD"); + assertTrue(head.isSymbolic()); + assertEquals(head.getTarget().getName(), "refs/heads/unborn"); + } + + /** + * Update the HEAD ref when the referenced branch is unborn + * + * @throws Exception + */ + @Test + public void testUpdateRefDetachedUnbornHead() throws Exception { + ObjectId ppid = db.resolve("refs/heads/master^"); + writeSymref("HEAD", "refs/heads/unborn"); + RefUpdate updateRef = db.updateRef("HEAD", true); + updateRef.setForceUpdate(true); + updateRef.setNewObjectId(ppid); + RefUpdate.Result update = updateRef.update(); + assertEquals(RefUpdate.Result.NEW, update); + assertEquals(ppid, db.resolve("HEAD")); + Ref ref = db.exactRef("HEAD"); + assertEquals("HEAD", ref.getName()); + assertTrue("is detached", !ref.isSymbolic()); + + // the branch HEAD referred to is left untouched + assertNull(db.resolve("refs/heads/unborn")); + ReflogReader reflogReader = db.getReflogReader("HEAD"); + ReflogEntry e = reflogReader.getReverseEntries().get(0); + assertEquals(ObjectId.zeroId(), e.getOldId()); + assertEquals(ppid, e.getNewId()); + assertEquals("GIT_COMMITTER_EMAIL", e.getWho().getEmailAddress()); + assertEquals("GIT_COMMITTER_NAME", e.getWho().getName()); + assertEquals(1250379778000L, e.getWho().getWhen().getTime()); + } + + @Test + public void testDeleteNotFound() throws IOException { + RefUpdate ref = updateRef("refs/heads/doesnotexist"); + assertNull(db.exactRef(ref.getName())); + assertEquals(RefUpdate.Result.NEW, ref.delete()); + assertNull(db.exactRef(ref.getName())); + } + + @Test + public void testRenameSymref() throws IOException { + db.resolve("HEAD"); + RefRename r = db.renameRef("HEAD", "KOPF"); + assertEquals(IO_FAILURE, r.rename()); + } + + @Test + public void testRenameCurrentBranch() throws IOException { + ObjectId rb = db.resolve("refs/heads/b"); + writeSymref(Constants.HEAD, "refs/heads/b"); + ObjectId oldHead = db.resolve(Constants.HEAD); + assertEquals("internal test condition, b == HEAD", oldHead, rb); + RefRename renameRef = db.renameRef("refs/heads/b", + "refs/heads/new/name"); + RefUpdate.Result result = renameRef.rename(); + assertEquals(RefUpdate.Result.RENAMED, result); + assertEquals(rb, db.resolve("refs/heads/new/name")); + assertNull(db.resolve("refs/heads/b")); + assertEquals(rb, db.resolve(Constants.HEAD)); + + List<String> names = new ArrayList<>(); + names.add("HEAD"); + names.add("refs/heads/b"); + names.add("refs/heads/new/name"); + + for (String nm : names) { + ReflogReader rd = db.getReflogReader(nm); + assertNotNull(rd); + ReflogEntry last = rd.getLastEntry(); + ObjectId id = last.getNewId(); + assertTrue(ObjectId.zeroId().equals(id) || rb.equals(id)); + + id = last.getNewId(); + assertTrue(ObjectId.zeroId().equals(id) || rb.equals(id)); + + String want = "Branch: renamed b to new/name"; + assertEquals(want, last.getComment()); + } + } + + @Test + public void isGitRepository() { + assertTrue(RepositoryCache.FileKey.isGitRepository(db.getDirectory(), db.getFS())); + } + + @Test + public void testRenameDestExists() throws IOException { + ObjectId rb = db.resolve("refs/heads/b"); + writeSymref(Constants.HEAD, "refs/heads/b"); + ObjectId oldHead = db.resolve(Constants.HEAD); + assertEquals("internal test condition, b == HEAD", oldHead, rb); + RefRename renameRef = db.renameRef("refs/heads/b", "refs/heads/a"); + RefUpdate.Result result = renameRef.rename(); + assertEquals(RefUpdate.Result.LOCK_FAILURE, result); + } + + @Test + public void testRenameAtomic() throws IOException { + ObjectId prevId = db.resolve("refs/heads/master^"); + + RefRename rename = db.renameRef("refs/heads/master", + "refs/heads/newmaster"); + + RefUpdate updateRef = db.updateRef("refs/heads/master"); + updateRef.setNewObjectId(prevId); + updateRef.setForceUpdate(true); + assertEquals(FORCED, updateRef.update()); + assertEquals(RefUpdate.Result.LOCK_FAILURE, rename.rename()); + } + + @Test + public void reftableRefsStorageClass() throws IOException { + Ref b = db.exactRef("refs/heads/b"); + assertEquals(Ref.Storage.PACKED, b.getStorage()); + } + + private RefUpdate updateRef(String name) throws IOException { + final RefUpdate ref = db.updateRef(name); + ref.setNewObjectId(db.resolve(Constants.HEAD)); + return ref; + } + + private void writeSymref(String src, String dst) throws IOException { + RefUpdate u = db.updateRef(src); + switch (u.link(dst)) { + case NEW: + case FORCED: + case NO_CHANGE: + break; + default: + fail("link " + src + " to " + dst); + } + } +} diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackFileSnapshotTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackFileSnapshotTest.java index d5bc61a692..9016a02b0b 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackFileSnapshotTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackFileSnapshotTest.java @@ -295,9 +295,8 @@ public class PackFileSnapshotTest extends RepositoryTestCase { Files.copy(src, dstOut); return dst; } - } else { - return Files.copy(src, dst, StandardCopyOption.REPLACE_EXISTING); } + return Files.copy(src, dst, StandardCopyOption.REPLACE_EXISTING); } private Path copyPack(Path base, String srcSuffix, String dstSuffix) 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 1e2341b6a5..3f281c49d2 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 @@ -468,22 +468,22 @@ public class PackWriterTest extends SampleDataRepositoryTestCase { @Test public void testDeltaStatistics() throws Exception { config.setDeltaCompress(true); + // TestRepository will close repo FileRepository repo = createBareRepository(); ArrayList<RevObject> blobs = new ArrayList<>(); try (TestRepository<FileRepository> testRepo = new TestRepository<>( repo)) { 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); + 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); + } } } @@ -535,6 +535,7 @@ public class PackWriterTest extends SampleDataRepositoryTestCase { @Test public void testExclude() throws Exception { + // TestRepository closes repo FileRepository repo = createBareRepository(); try (TestRepository<FileRepository> testRepo = new TestRepository<>( @@ -568,98 +569,102 @@ public class PackWriterTest extends SampleDataRepositoryTestCase { @Test public void testShallowIsMinimalDepth1() throws Exception { - FileRepository repo = setupRepoForShallowFetch(); - - PackIndex idx = writeShallowPack(repo, 1, wants(c2), NONE, NONE); - assertContent(idx, Arrays.asList(c2.getId(), c2.getTree().getId(), - contentA.getId(), contentB.getId())); - - // Client already has blobs A and B, verify those are not packed. - idx = writeShallowPack(repo, 1, wants(c5), haves(c2), shallows(c2)); - assertContent(idx, Arrays.asList(c5.getId(), c5.getTree().getId(), - contentC.getId(), contentD.getId(), contentE.getId())); + try (FileRepository repo = setupRepoForShallowFetch()) { + PackIndex idx = writeShallowPack(repo, 1, wants(c2), NONE, NONE); + assertContent(idx, Arrays.asList(c2.getId(), c2.getTree().getId(), + contentA.getId(), contentB.getId())); + + // Client already has blobs A and B, verify those are not packed. + idx = writeShallowPack(repo, 1, wants(c5), haves(c2), shallows(c2)); + assertContent(idx, Arrays.asList(c5.getId(), c5.getTree().getId(), + contentC.getId(), contentD.getId(), contentE.getId())); + } } @Test public void testShallowIsMinimalDepth2() throws Exception { - FileRepository repo = setupRepoForShallowFetch(); - - PackIndex idx = writeShallowPack(repo, 2, wants(c2), NONE, NONE); - assertContent(idx, - Arrays.asList(c1.getId(), c2.getId(), c1.getTree().getId(), - c2.getTree().getId(), contentA.getId(), - contentB.getId())); - - // Client already has blobs A and B, verify those are not packed. - idx = writeShallowPack(repo, 2, wants(c5), haves(c1, c2), shallows(c1)); - assertContent(idx, - Arrays.asList(c4.getId(), c5.getId(), c4.getTree().getId(), - c5.getTree().getId(), contentC.getId(), - contentD.getId(), contentE.getId())); + try (FileRepository repo = setupRepoForShallowFetch()) { + PackIndex idx = writeShallowPack(repo, 2, wants(c2), NONE, NONE); + assertContent(idx, + Arrays.asList(c1.getId(), c2.getId(), c1.getTree().getId(), + c2.getTree().getId(), contentA.getId(), + contentB.getId())); + + // Client already has blobs A and B, verify those are not packed. + idx = writeShallowPack(repo, 2, wants(c5), haves(c1, c2), + shallows(c1)); + assertContent(idx, + Arrays.asList(c4.getId(), c5.getId(), c4.getTree().getId(), + c5.getTree().getId(), contentC.getId(), + contentD.getId(), contentE.getId())); + } } @Test public void testShallowFetchShallowParentDepth1() throws Exception { - FileRepository repo = setupRepoForShallowFetch(); - - PackIndex idx = writeShallowPack(repo, 1, wants(c5), NONE, NONE); - assertContent(idx, - Arrays.asList(c5.getId(), c5.getTree().getId(), - contentA.getId(), contentB.getId(), contentC.getId(), - contentD.getId(), contentE.getId())); - - idx = writeShallowPack(repo, 1, wants(c4), haves(c5), shallows(c5)); - assertContent(idx, Arrays.asList(c4.getId(), c4.getTree().getId())); + try (FileRepository repo = setupRepoForShallowFetch()) { + PackIndex idx = writeShallowPack(repo, 1, wants(c5), NONE, NONE); + assertContent(idx, Arrays.asList(c5.getId(), c5.getTree().getId(), + contentA.getId(), contentB.getId(), contentC.getId(), + contentD.getId(), contentE.getId())); + + idx = writeShallowPack(repo, 1, wants(c4), haves(c5), shallows(c5)); + assertContent(idx, Arrays.asList(c4.getId(), c4.getTree().getId())); + } } @Test public void testShallowFetchShallowParentDepth2() throws Exception { - FileRepository repo = setupRepoForShallowFetch(); - - PackIndex idx = writeShallowPack(repo, 2, wants(c5), NONE, NONE); - assertContent(idx, - Arrays.asList(c4.getId(), c5.getId(), c4.getTree().getId(), - c5.getTree().getId(), contentA.getId(), - contentB.getId(), contentC.getId(), contentD.getId(), - contentE.getId())); - - idx = writeShallowPack(repo, 2, wants(c3), haves(c4, c5), shallows(c4)); - assertContent(idx, Arrays.asList(c2.getId(), c3.getId(), - c2.getTree().getId(), c3.getTree().getId())); + try (FileRepository repo = setupRepoForShallowFetch()) { + PackIndex idx = writeShallowPack(repo, 2, wants(c5), NONE, NONE); + assertContent(idx, + Arrays.asList(c4.getId(), c5.getId(), c4.getTree().getId(), + c5.getTree().getId(), contentA.getId(), + contentB.getId(), contentC.getId(), + contentD.getId(), contentE.getId())); + + idx = writeShallowPack(repo, 2, wants(c3), haves(c4, c5), + shallows(c4)); + assertContent(idx, Arrays.asList(c2.getId(), c3.getId(), + c2.getTree().getId(), c3.getTree().getId())); + } } @Test public void testShallowFetchShallowAncestorDepth1() throws Exception { - FileRepository repo = setupRepoForShallowFetch(); - - PackIndex idx = writeShallowPack(repo, 1, wants(c5), NONE, NONE); - assertContent(idx, - Arrays.asList(c5.getId(), c5.getTree().getId(), - contentA.getId(), contentB.getId(), contentC.getId(), - contentD.getId(), contentE.getId())); - - idx = writeShallowPack(repo, 1, wants(c3), haves(c5), shallows(c5)); - assertContent(idx, Arrays.asList(c3.getId(), c3.getTree().getId())); + try (FileRepository repo = setupRepoForShallowFetch()) { + PackIndex idx = writeShallowPack(repo, 1, wants(c5), NONE, NONE); + assertContent(idx, Arrays.asList(c5.getId(), c5.getTree().getId(), + contentA.getId(), contentB.getId(), contentC.getId(), + contentD.getId(), contentE.getId())); + + idx = writeShallowPack(repo, 1, wants(c3), haves(c5), shallows(c5)); + assertContent(idx, Arrays.asList(c3.getId(), c3.getTree().getId())); + } } @Test public void testShallowFetchShallowAncestorDepth2() throws Exception { - FileRepository repo = setupRepoForShallowFetch(); - - PackIndex idx = writeShallowPack(repo, 2, wants(c5), NONE, NONE); - assertContent(idx, - Arrays.asList(c4.getId(), c5.getId(), c4.getTree().getId(), - c5.getTree().getId(), contentA.getId(), - contentB.getId(), contentC.getId(), contentD.getId(), - contentE.getId())); - - idx = writeShallowPack(repo, 2, wants(c2), haves(c4, c5), shallows(c4)); - assertContent(idx, Arrays.asList(c1.getId(), c2.getId(), - c1.getTree().getId(), c2.getTree().getId())); + try (FileRepository repo = setupRepoForShallowFetch()) { + PackIndex idx = writeShallowPack(repo, 2, wants(c5), NONE, NONE); + assertContent(idx, + Arrays.asList(c4.getId(), c5.getId(), c4.getTree().getId(), + c5.getTree().getId(), contentA.getId(), + contentB.getId(), contentC.getId(), + contentD.getId(), contentE.getId())); + + idx = writeShallowPack(repo, 2, wants(c2), haves(c4, c5), + shallows(c4)); + assertContent(idx, Arrays.asList(c1.getId(), c2.getId(), + c1.getTree().getId(), c2.getTree().getId())); + } } private FileRepository setupRepoForShallowFetch() throws Exception { FileRepository repo = createBareRepository(); + // TestRepository will close the repo, but we need to return an open + // one! + repo.incrementOpen(); try (TestRepository<Repository> r = new TestRepository<>(repo)) { BranchBuilder bb = r.branch("refs/heads/master"); contentA = r.blob("A"); @@ -680,8 +685,9 @@ public class PackWriterTest extends SampleDataRepositoryTestCase { private static PackIndex writePack(FileRepository repo, Set<? extends ObjectId> want, Set<ObjectIdSet> excludeObjects) throws IOException { - RevWalk walk = new RevWalk(repo); - return writePack(repo, walk, 0, want, NONE, excludeObjects); + try (RevWalk walk = new RevWalk(repo)) { + return writePack(repo, walk, 0, want, NONE, excludeObjects); + } } private static PackIndex writeShallowPack(FileRepository repo, int depth, @@ -689,9 +695,10 @@ public class PackWriterTest extends SampleDataRepositoryTestCase { Set<? extends ObjectId> shallow) throws IOException { // During negotiation, UploadPack would have set up a DepthWalk and // marked the client's "shallow" commits. Emulate that here. - DepthWalk.RevWalk walk = new DepthWalk.RevWalk(repo, depth - 1); - walk.assumeShallow(shallow); - return writePack(repo, walk, depth, want, have, EMPTY_ID_SET); + try (DepthWalk.RevWalk walk = new DepthWalk.RevWalk(repo, depth - 1)) { + walk.assumeShallow(shallow); + return writePack(repo, walk, depth, want, have, EMPTY_ID_SET); + } } private static PackIndex writePack(FileRepository repo, RevWalk walk, @@ -707,6 +714,7 @@ public class PackWriterTest extends SampleDataRepositoryTestCase { if (depth > 0) { pw.setShallowPack(depth, null); } + // ow doesn't need to be closed; caller closes walk. ObjectWalk ow = walk.toObjectWalkWithSameObjects(); pw.preparePack(NullProgressMonitor.INSTANCE, ow, want, have, NONE); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/RefUpdateTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/RefUpdateTest.java index 3a43564180..bd2c203f5c 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/RefUpdateTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/RefUpdateTest.java @@ -45,9 +45,12 @@ package org.eclipse.jgit.internal.storage.file; -import static org.eclipse.jgit.junit.Assert.assertEquals; import static java.nio.charset.StandardCharsets.UTF_8; +import static org.eclipse.jgit.junit.Assert.assertEquals; import static org.eclipse.jgit.lib.Constants.LOCK_SUFFIX; +import static org.eclipse.jgit.lib.RefUpdate.Result.FORCED; +import static org.eclipse.jgit.lib.RefUpdate.Result.IO_FAILURE; +import static org.eclipse.jgit.lib.RefUpdate.Result.LOCK_FAILURE; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; @@ -82,7 +85,6 @@ import org.eclipse.jgit.test.resources.SampleDataRepositoryTestCase; import org.junit.Test; public class RefUpdateTest extends SampleDataRepositoryTestCase { - private void writeSymref(String src, String dst) throws IOException { RefUpdate u = db.updateRef(src); switch (u.link(dst)) { @@ -233,6 +235,17 @@ public class RefUpdateTest extends SampleDataRepositoryTestCase { } @Test + public void testWriteReflog() throws IOException { + ObjectId pid = db.resolve("refs/heads/master^"); + RefUpdate updateRef = db.updateRef("refs/heads/master"); + updateRef.setNewObjectId(pid); + updateRef.setForceUpdate(true); + Result update = updateRef.update(); + assertEquals(Result.FORCED, update); + assertEquals(1,db.getReflogReader("refs/heads/master").getReverseEntries().size()); + } + + @Test public void testLooseDelete() throws IOException { final String newRef = "refs/heads/abc"; RefUpdate ref = updateRef(newRef); @@ -379,6 +392,8 @@ public class RefUpdateTest extends SampleDataRepositoryTestCase { refUpdate.setNewObjectId(ObjectId.zeroId()); Result updateResult = refUpdate.update(); assertEquals(Result.FORCED, updateResult); + + assertEquals(ObjectId.zeroId(), db.exactRef("HEAD").getObjectId()); Result deleteHeadResult = db.updateRef(Constants.HEAD).delete(); assertEquals(Result.NO_CHANGE, deleteHeadResult); @@ -903,6 +918,45 @@ public class RefUpdateTest extends SampleDataRepositoryTestCase { } @Test + public void testUpdateChecksOldValue() throws Exception { + ObjectId cur = db.resolve("master"); + ObjectId prev = db.resolve("master^"); + RefUpdate u1 = db.updateRef("refs/heads/master"); + RefUpdate u2 = db.updateRef("refs/heads/master"); + + u1.setExpectedOldObjectId(cur); + u1.setNewObjectId(prev); + u1.setForceUpdate(true); + + u2.setExpectedOldObjectId(cur); + u2.setNewObjectId(prev); + u2.setForceUpdate(true); + + assertEquals(FORCED, u1.update()); + assertEquals(LOCK_FAILURE, u2.update()); + } + + @Test + public void testRenameAtomic() throws IOException { + ObjectId prevId = db.resolve("refs/heads/master^"); + + RefRename rename = db.renameRef("refs/heads/master", "refs/heads/newmaster"); + + RefUpdate updateRef = db.updateRef("refs/heads/master"); + updateRef.setNewObjectId(prevId); + updateRef.setForceUpdate(true); + assertEquals(FORCED, updateRef.update()); + assertEquals(RefUpdate.Result.LOCK_FAILURE, rename.rename()); + } + + @Test + public void testRenameSymref() throws IOException { + db.resolve("HEAD"); + RefRename r = db.renameRef("HEAD", "KOPF"); + assertEquals(IO_FAILURE, r.rename()); + } + + @Test public void testRenameRefNameColission1avoided() throws IOException { // setup ObjectId rb = db.resolve("refs/heads/b"); 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 43f30d8ca8..5100c1ce29 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 @@ -145,13 +145,14 @@ public class T0003_BasicTest extends SampleDataRepositoryTestCase { } File theDir = new File(repo1Parent, Constants.DOT_GIT); - FileRepository r = (FileRepository) new FileRepositoryBuilder() - .setGitDir(theDir).build(); - assertEqualsPath(theDir, r.getDirectory()); - assertEqualsPath(repo1Parent, r.getWorkTree()); - assertEqualsPath(new File(theDir, "index"), r.getIndexFile()); - assertEqualsPath(new File(theDir, Constants.OBJECTS), r.getObjectDatabase() - .getDirectory()); + try (FileRepository r = (FileRepository) new FileRepositoryBuilder() + .setGitDir(theDir).build()) { + assertEqualsPath(theDir, r.getDirectory()); + assertEqualsPath(repo1Parent, r.getWorkTree()); + assertEqualsPath(new File(theDir, "index"), r.getIndexFile()); + assertEqualsPath(new File(theDir, Constants.OBJECTS), + r.getObjectDatabase().getDirectory()); + } } /** @@ -170,14 +171,15 @@ public class T0003_BasicTest extends SampleDataRepositoryTestCase { } File theDir = new File(repo1Parent, Constants.DOT_GIT); - FileRepository r = (FileRepository) new FileRepositoryBuilder() + try (FileRepository r = (FileRepository) new FileRepositoryBuilder() .setGitDir(theDir).setWorkTree(repo1Parent.getParentFile()) - .build(); - assertEqualsPath(theDir, r.getDirectory()); - assertEqualsPath(repo1Parent.getParentFile(), r.getWorkTree()); - assertEqualsPath(new File(theDir, "index"), r.getIndexFile()); - assertEqualsPath(new File(theDir, Constants.OBJECTS), r.getObjectDatabase() - .getDirectory()); + .build()) { + assertEqualsPath(theDir, r.getDirectory()); + assertEqualsPath(repo1Parent.getParentFile(), r.getWorkTree()); + assertEqualsPath(new File(theDir, "index"), r.getIndexFile()); + assertEqualsPath(new File(theDir, Constants.OBJECTS), + r.getObjectDatabase().getDirectory()); + } } /** @@ -195,13 +197,14 @@ public class T0003_BasicTest extends SampleDataRepositoryTestCase { } File theDir = new File(repo1Parent, Constants.DOT_GIT); - FileRepository r = (FileRepository) new FileRepositoryBuilder() - .setWorkTree(repo1Parent).build(); - assertEqualsPath(theDir, r.getDirectory()); - assertEqualsPath(repo1Parent, r.getWorkTree()); - assertEqualsPath(new File(theDir, "index"), r.getIndexFile()); - assertEqualsPath(new File(theDir, Constants.OBJECTS), r.getObjectDatabase() - .getDirectory()); + try (FileRepository r = (FileRepository) new FileRepositoryBuilder() + .setWorkTree(repo1Parent).build()) { + assertEqualsPath(theDir, r.getDirectory()); + assertEqualsPath(repo1Parent, r.getWorkTree()); + assertEqualsPath(new File(theDir, "index"), r.getIndexFile()); + assertEqualsPath(new File(theDir, Constants.OBJECTS), + r.getObjectDatabase().getDirectory()); + } } /** @@ -224,13 +227,14 @@ public class T0003_BasicTest extends SampleDataRepositoryTestCase { } File theDir = new File(repo1Parent, Constants.DOT_GIT); - FileRepository r = (FileRepository) new FileRepositoryBuilder() - .setGitDir(theDir).build(); - assertEqualsPath(theDir, r.getDirectory()); - assertEqualsPath(workdir, r.getWorkTree()); - assertEqualsPath(new File(theDir, "index"), r.getIndexFile()); - assertEqualsPath(new File(theDir, Constants.OBJECTS), r.getObjectDatabase() - .getDirectory()); + try (FileRepository r = (FileRepository) new FileRepositoryBuilder() + .setGitDir(theDir).build()) { + assertEqualsPath(theDir, r.getDirectory()); + assertEqualsPath(workdir, r.getWorkTree()); + assertEqualsPath(new File(theDir, "index"), r.getIndexFile()); + assertEqualsPath(new File(theDir, Constants.OBJECTS), + r.getObjectDatabase().getDirectory()); + } } /** @@ -253,13 +257,14 @@ public class T0003_BasicTest extends SampleDataRepositoryTestCase { } File theDir = new File(repo1Parent, Constants.DOT_GIT); - FileRepository r = (FileRepository) new FileRepositoryBuilder() - .setGitDir(theDir).build(); - assertEqualsPath(theDir, r.getDirectory()); - assertEqualsPath(workdir, r.getWorkTree()); - assertEqualsPath(new File(theDir, "index"), r.getIndexFile()); - assertEqualsPath(new File(theDir, Constants.OBJECTS), r.getObjectDatabase() - .getDirectory()); + try (FileRepository r = (FileRepository) new FileRepositoryBuilder() + .setGitDir(theDir).build()) { + assertEqualsPath(theDir, r.getDirectory()); + assertEqualsPath(workdir, r.getWorkTree()); + assertEqualsPath(new File(theDir, "index"), r.getIndexFile()); + assertEqualsPath(new File(theDir, Constants.OBJECTS), + r.getObjectDatabase().getDirectory()); + } } /** @@ -306,17 +311,20 @@ public class T0003_BasicTest extends SampleDataRepositoryTestCase { // open when we create it we won't write the object file out as a loose // object (as it already exists in the pack). // - final Repository newdb = createBareRepository(); - try (ObjectInserter oi = newdb.newObjectInserter()) { - final ObjectId treeId = oi.insert(new TreeFormatter()); - assertEquals("4b825dc642cb6eb9a060e54bf8d69288fbee4904", - treeId.name()); + try (Repository newdb = createBareRepository()) { + try (ObjectInserter oi = newdb.newObjectInserter()) { + final ObjectId treeId = oi.insert(new TreeFormatter()); + assertEquals("4b825dc642cb6eb9a060e54bf8d69288fbee4904", + treeId.name()); + } + + final File o = new File( + new File(new File(newdb.getDirectory(), Constants.OBJECTS), + "4b"), + "825dc642cb6eb9a060e54bf8d69288fbee4904"); + assertTrue("Exists " + o, o.isFile()); + assertTrue("Read-only " + o, !o.canWrite()); } - - final File o = new File(new File(new File(newdb.getDirectory(), - Constants.OBJECTS), "4b"), "825dc642cb6eb9a060e54bf8d69288fbee4904"); - assertTrue("Exists " + o, o.isFile()); - assertTrue("Read-only " + o, !o.canWrite()); } @Test diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftable/MergedReftableTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftable/MergedReftableTest.java index 11d6439931..53d13f1d60 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftable/MergedReftableTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftable/MergedReftableTest.java @@ -187,6 +187,19 @@ public class MergedReftableTest { } } + @Test + public void tableByIDDeletion() throws IOException { + List<Ref> delta1 = Arrays.asList( + ref("refs/heads/apple", 1), + ref("refs/heads/master", 2)); + List<Ref> delta2 = Arrays.asList(ref("refs/heads/master", 3)); + + MergedReftable mr = merge(write(delta1), write(delta2)); + try (RefCursor rc = mr.byObjectId(id(2))) { + assertFalse(rc.next()); + } + } + @SuppressWarnings("boxing") @Test public void fourTableScan() throws IOException { @@ -225,29 +238,6 @@ public class MergedReftableTest { } @Test - public void scanDuplicates() throws IOException { - List<Ref> delta1 = Arrays.asList( - ref("refs/heads/apple", 1), - ref("refs/heads/banana", 2)); - List<Ref> delta2 = Arrays.asList( - ref("refs/heads/apple", 3), - ref("refs/heads/apple", 4)); - - MergedReftable mr = merge(write(delta1, 1000), write(delta2, 2000)); - try (RefCursor rc = mr.allRefs()) { - assertTrue(rc.next()); - assertEquals("refs/heads/apple", rc.getRef().getName()); - assertEquals(id(3), rc.getRef().getObjectId()); - assertEquals(2000, rc.getRef().getUpdateIndex()); - assertTrue(rc.next()); - assertEquals("refs/heads/banana", rc.getRef().getName()); - assertEquals(id(2), rc.getRef().getObjectId()); - assertEquals(1000, rc.getRef().getUpdateIndex()); - assertFalse(rc.next()); - } - } - - @Test public void scanIncludeDeletes() throws IOException { List<Ref> delta1 = Arrays.asList(ref("refs/heads/next", 4)); List<Ref> delta2 = Arrays.asList(delete("refs/heads/next")); @@ -297,10 +287,10 @@ public class MergedReftableTest { @Test public void missedUpdate() throws IOException { ByteArrayOutputStream buf = new ByteArrayOutputStream(); - ReftableWriter writer = new ReftableWriter() + ReftableWriter writer = new ReftableWriter(buf) .setMinUpdateIndex(1) .setMaxUpdateIndex(3) - .begin(buf); + .begin(); writer.writeRef(ref("refs/heads/a", 1), 1); writer.writeRef(ref("refs/heads/c", 3), 3); writer.finish(); @@ -337,13 +327,13 @@ public class MergedReftableTest { List<Ref> delta2 = Arrays.asList(delete("refs/heads/next")); List<Ref> delta3 = Arrays.asList(ref("refs/heads/master", 8)); - ReftableCompactor compactor = new ReftableCompactor(); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + ReftableCompactor compactor = new ReftableCompactor(out); compactor.addAll(Arrays.asList( read(write(delta1)), read(write(delta2)), read(write(delta3)))); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - compactor.compact(out); + compactor.compact(); byte[] table = out.toByteArray(); ReftableReader reader = read(table); @@ -414,7 +404,7 @@ public class MergedReftableTest { } private static MergedReftable merge(byte[]... table) { - List<Reftable> stack = new ArrayList<>(table.length); + List<ReftableReader> stack = new ArrayList<>(table.length); for (byte[] b : table) { stack.add(read(b)); } @@ -461,10 +451,10 @@ public class MergedReftableTest { private byte[] write(Collection<Ref> refs, long updateIndex) throws IOException { ByteArrayOutputStream buffer = new ByteArrayOutputStream(); - new ReftableWriter() + new ReftableWriter(buffer) .setMinUpdateIndex(updateIndex) .setMaxUpdateIndex(updateIndex) - .begin(buffer) + .begin() .sortAndWriteRefs(refs) .finish(); return buffer.toByteArray(); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftable/ReftableCompactorTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftable/ReftableCompactorTest.java index 1ea73097fe..9a7f240951 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftable/ReftableCompactorTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftable/ReftableCompactorTest.java @@ -67,9 +67,10 @@ public class ReftableCompactorTest { @Test public void noTables() throws IOException { - ReftableCompactor compactor = new ReftableCompactor(); + ReftableCompactor compactor; try (ByteArrayOutputStream out = new ByteArrayOutputStream()) { - compactor.compact(out); + compactor = new ReftableCompactor(out); + compactor.compact(); } Stats stats = compactor.getStats(); assertEquals(0, stats.minUpdateIndex()); @@ -81,10 +82,10 @@ public class ReftableCompactorTest { public void oneTable() throws IOException { byte[] inTab; try (ByteArrayOutputStream inBuf = new ByteArrayOutputStream()) { - ReftableWriter writer = new ReftableWriter() + ReftableWriter writer = new ReftableWriter(inBuf) .setMinUpdateIndex(0) .setMaxUpdateIndex(0) - .begin(inBuf); + .begin(); writer.writeRef(ref(MASTER, 1)); writer.finish(); @@ -92,10 +93,11 @@ public class ReftableCompactorTest { } byte[] outTab; - ReftableCompactor compactor = new ReftableCompactor(); + ReftableCompactor compactor; try (ByteArrayOutputStream outBuf = new ByteArrayOutputStream()) { + compactor = new ReftableCompactor(outBuf); compactor.tryAddFirst(read(inTab)); - compactor.compact(outBuf); + compactor.compact(); outTab = outBuf.toByteArray(); } Stats stats = compactor.getStats(); @@ -116,10 +118,10 @@ public class ReftableCompactorTest { public void twoTablesOneRef() throws IOException { byte[] inTab1; try (ByteArrayOutputStream inBuf = new ByteArrayOutputStream()) { - ReftableWriter writer = new ReftableWriter() + ReftableWriter writer = new ReftableWriter(inBuf) .setMinUpdateIndex(0) .setMaxUpdateIndex(0) - .begin(inBuf); + .begin(); writer.writeRef(ref(MASTER, 1)); writer.finish(); @@ -128,10 +130,10 @@ public class ReftableCompactorTest { byte[] inTab2; try (ByteArrayOutputStream inBuf = new ByteArrayOutputStream()) { - ReftableWriter writer = new ReftableWriter() + ReftableWriter writer = new ReftableWriter(inBuf) .setMinUpdateIndex(1) .setMaxUpdateIndex(1) - .begin(inBuf); + .begin(); writer.writeRef(ref(MASTER, 2)); writer.finish(); @@ -139,10 +141,11 @@ public class ReftableCompactorTest { } byte[] outTab; - ReftableCompactor compactor = new ReftableCompactor(); + ReftableCompactor compactor; try (ByteArrayOutputStream outBuf = new ByteArrayOutputStream()) { + compactor = new ReftableCompactor(outBuf); compactor.addAll(Arrays.asList(read(inTab1), read(inTab2))); - compactor.compact(outBuf); + compactor.compact(); outTab = outBuf.toByteArray(); } Stats stats = compactor.getStats(); @@ -163,10 +166,10 @@ public class ReftableCompactorTest { public void twoTablesTwoRefs() throws IOException { byte[] inTab1; try (ByteArrayOutputStream inBuf = new ByteArrayOutputStream()) { - ReftableWriter writer = new ReftableWriter() + ReftableWriter writer = new ReftableWriter(inBuf) .setMinUpdateIndex(0) .setMaxUpdateIndex(0) - .begin(inBuf); + .begin(); writer.writeRef(ref(MASTER, 1)); writer.writeRef(ref(NEXT, 2)); @@ -176,10 +179,10 @@ public class ReftableCompactorTest { byte[] inTab2; try (ByteArrayOutputStream inBuf = new ByteArrayOutputStream()) { - ReftableWriter writer = new ReftableWriter() + ReftableWriter writer = new ReftableWriter(inBuf) .setMinUpdateIndex(1) .setMaxUpdateIndex(1) - .begin(inBuf); + .begin(); writer.writeRef(ref(MASTER, 3)); writer.finish(); @@ -187,10 +190,11 @@ public class ReftableCompactorTest { } byte[] outTab; - ReftableCompactor compactor = new ReftableCompactor(); + ReftableCompactor compactor; try (ByteArrayOutputStream outBuf = new ByteArrayOutputStream()) { + compactor = new ReftableCompactor(outBuf); compactor.addAll(Arrays.asList(read(inTab1), read(inTab2))); - compactor.compact(outBuf); + compactor.compact(); outTab = outBuf.toByteArray(); } Stats stats = compactor.getStats(); @@ -216,10 +220,10 @@ public class ReftableCompactorTest { public void twoTablesIncludeOneDelete() throws IOException { byte[] inTab1; try (ByteArrayOutputStream inBuf = new ByteArrayOutputStream()) { - ReftableWriter writer = new ReftableWriter() + ReftableWriter writer = new ReftableWriter(inBuf) .setMinUpdateIndex(0) .setMaxUpdateIndex(0) - .begin(inBuf); + .begin(); writer.writeRef(ref(MASTER, 1)); writer.finish(); @@ -228,10 +232,10 @@ public class ReftableCompactorTest { byte[] inTab2; try (ByteArrayOutputStream inBuf = new ByteArrayOutputStream()) { - ReftableWriter writer = new ReftableWriter() + ReftableWriter writer = new ReftableWriter(inBuf) .setMinUpdateIndex(1) .setMaxUpdateIndex(1) - .begin(inBuf); + .begin(); writer.writeRef(tombstone(MASTER)); writer.finish(); @@ -239,11 +243,12 @@ public class ReftableCompactorTest { } byte[] outTab; - ReftableCompactor compactor = new ReftableCompactor(); + ReftableCompactor compactor; try (ByteArrayOutputStream outBuf = new ByteArrayOutputStream()) { + compactor = new ReftableCompactor(outBuf); compactor.setIncludeDeletes(true); compactor.addAll(Arrays.asList(read(inTab1), read(inTab2))); - compactor.compact(outBuf); + compactor.compact(); outTab = outBuf.toByteArray(); } Stats stats = compactor.getStats(); @@ -261,10 +266,10 @@ public class ReftableCompactorTest { public void twoTablesNotIncludeOneDelete() throws IOException { byte[] inTab1; try (ByteArrayOutputStream inBuf = new ByteArrayOutputStream()) { - ReftableWriter writer = new ReftableWriter() + ReftableWriter writer = new ReftableWriter(inBuf) .setMinUpdateIndex(0) .setMaxUpdateIndex(0) - .begin(inBuf); + .begin(); writer.writeRef(ref(MASTER, 1)); writer.finish(); @@ -273,10 +278,10 @@ public class ReftableCompactorTest { byte[] inTab2; try (ByteArrayOutputStream inBuf = new ByteArrayOutputStream()) { - ReftableWriter writer = new ReftableWriter() + ReftableWriter writer = new ReftableWriter(inBuf) .setMinUpdateIndex(1) .setMaxUpdateIndex(1) - .begin(inBuf); + .begin(); writer.writeRef(tombstone(MASTER)); writer.finish(); @@ -284,11 +289,12 @@ public class ReftableCompactorTest { } byte[] outTab; - ReftableCompactor compactor = new ReftableCompactor(); + ReftableCompactor compactor; try (ByteArrayOutputStream outBuf = new ByteArrayOutputStream()) { + compactor = new ReftableCompactor(outBuf); compactor.setIncludeDeletes(false); compactor.addAll(Arrays.asList(read(inTab1), read(inTab2))); - compactor.compact(outBuf); + compactor.compact(); outTab = outBuf.toByteArray(); } Stats stats = compactor.getStats(); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftable/ReftableTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftable/ReftableTest.java index 0e33fa6e76..ec8b7593f0 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftable/ReftableTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftable/ReftableTest.java @@ -66,6 +66,8 @@ import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.List; +import java.util.concurrent.locks.ReentrantLock; +import java.util.stream.Collectors; import org.eclipse.jgit.internal.JGitText; import org.eclipse.jgit.internal.storage.io.BlockSource; @@ -76,6 +78,7 @@ import org.eclipse.jgit.lib.PersonIdent; import org.eclipse.jgit.lib.Ref; import org.eclipse.jgit.lib.ReflogEntry; import org.eclipse.jgit.lib.SymbolicRef; +import org.hamcrest.Matchers; import org.junit.Test; public class ReftableTest { @@ -134,9 +137,9 @@ public class ReftableTest { byte[] table; ReftableConfig cfg = new ReftableConfig(); cfg.setIndexObjects(false); - ReftableWriter writer = new ReftableWriter().setConfig(cfg); try (ByteArrayOutputStream buf = new ByteArrayOutputStream()) { - writer.begin(buf); + ReftableWriter writer = new ReftableWriter(buf).setConfig(cfg); + writer.begin(); assertEquals(92, writer.estimateTotalBytes()); writer.writeRef(exp); assertEquals(expBytes, writer.estimateTotalBytes()); @@ -146,12 +149,13 @@ public class ReftableTest { assertEquals(expBytes, table.length); } - @SuppressWarnings("boxing") @Test public void estimateCurrentBytesWithIndex() throws IOException { List<Ref> refs = new ArrayList<>(); for (int i = 1; i <= 5670; i++) { - refs.add(ref(String.format("refs/heads/%04d", i), i)); + @SuppressWarnings("boxing") + Ref ref = ref(String.format("refs/heads/%04d", i), i); + refs.add(ref); } ReftableConfig cfg = new ReftableConfig(); @@ -160,9 +164,9 @@ public class ReftableTest { int expBytes = 147860; byte[] table; - ReftableWriter writer = new ReftableWriter().setConfig(cfg); try (ByteArrayOutputStream buf = new ByteArrayOutputStream()) { - writer.begin(buf); + ReftableWriter writer = new ReftableWriter(buf).setConfig(cfg); + writer.begin(); writer.sortAndWriteRefs(refs); assertEquals(expBytes, writer.estimateTotalBytes()); writer.finish(); @@ -174,6 +178,69 @@ public class ReftableTest { } @Test + public void hasObjMapRefs() throws IOException { + ArrayList<Ref> refs = new ArrayList<>(); + refs.add(ref(MASTER, 1)); + byte[] table = write(refs); + ReftableReader t = read(table); + assertTrue(t.hasObjectMap()); + } + + @Test + public void hasObjMapRefsSmallTable() throws IOException { + ArrayList<Ref> refs = new ArrayList<>(); + ReftableConfig cfg = new ReftableConfig(); + cfg.setIndexObjects(false); + refs.add(ref(MASTER, 1)); + byte[] table = write(refs); + ReftableReader t = read(table); + assertTrue(t.hasObjectMap()); + } + + @Test + public void hasObjLogs() throws IOException { + PersonIdent who = new PersonIdent("Log", "Ger", 1500079709, -8 * 60); + String msg = "test"; + ReftableConfig cfg = new ReftableConfig(); + cfg.setIndexObjects(false); + + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + ReftableWriter writer = new ReftableWriter(buffer) + .setMinUpdateIndex(1) + .setConfig(cfg) + .setMaxUpdateIndex(1) + .begin(); + + writer.writeLog("master", 1, who, ObjectId.zeroId(), id(1), msg); + writer.finish(); + byte[] table = buffer.toByteArray(); + + ReftableReader t = read(table); + assertTrue(t.hasObjectMap()); + } + + @Test + public void hasObjMapRefsNoIndexObjects() throws IOException { + ArrayList<Ref> refs = new ArrayList<>(); + ReftableConfig cfg = new ReftableConfig(); + cfg.setIndexObjects(false); + cfg.setRefBlockSize(256); + cfg.setAlignBlocks(true); + + // Fill up 5 blocks. + int N = 256 * 5 / 25; + for (int i= 0; i < N; i++) { + @SuppressWarnings("boxing") + Ref ref = ref(String.format("%02d/xxxxxxxxxx", i), i); + refs.add(ref); + } + byte[] table = write(refs, cfg); + + ReftableReader t = read(table); + assertFalse(t.hasObjectMap()); + } + + @Test public void oneIdRef() throws IOException { Ref exp = ref(MASTER, 1); byte[] table = write(exp); @@ -361,12 +428,13 @@ public class ReftableTest { } } - @SuppressWarnings("boxing") @Test public void indexScan() throws IOException { List<Ref> refs = new ArrayList<>(); for (int i = 1; i <= 5670; i++) { - refs.add(ref(String.format("refs/heads/%04d", i), i)); + @SuppressWarnings("boxing") + Ref ref = ref(String.format("refs/heads/%04d", i), i); + refs.add(ref); } byte[] table = write(refs); @@ -375,12 +443,13 @@ public class ReftableTest { assertScan(refs, read(table)); } - @SuppressWarnings("boxing") @Test public void indexSeek() throws IOException { List<Ref> refs = new ArrayList<>(); for (int i = 1; i <= 5670; i++) { - refs.add(ref(String.format("refs/heads/%04d", i), i)); + @SuppressWarnings("boxing") + Ref ref = ref(String.format("refs/heads/%04d", i), i); + refs.add(ref); } byte[] table = write(refs); @@ -389,12 +458,13 @@ public class ReftableTest { assertSeek(refs, read(table)); } - @SuppressWarnings("boxing") @Test public void noIndexScan() throws IOException { List<Ref> refs = new ArrayList<>(); for (int i = 1; i <= 567; i++) { - refs.add(ref(String.format("refs/heads/%03d", i), i)); + @SuppressWarnings("boxing") + Ref ref = ref(String.format("refs/heads/%03d", i), i); + refs.add(ref); } byte[] table = write(refs); @@ -404,12 +474,13 @@ public class ReftableTest { assertScan(refs, read(table)); } - @SuppressWarnings("boxing") @Test public void noIndexSeek() throws IOException { List<Ref> refs = new ArrayList<>(); for (int i = 1; i <= 567; i++) { - refs.add(ref(String.format("refs/heads/%03d", i), i)); + @SuppressWarnings("boxing") + Ref ref = ref(String.format("refs/heads/%03d", i), i); + refs.add(ref); } byte[] table = write(refs); @@ -418,27 +489,29 @@ public class ReftableTest { } @Test - public void invalidRefWriteOrder() throws IOException { + public void invalidRefWriteOrderSortAndWrite() { Ref master = ref(MASTER, 1); - Ref next = ref(NEXT, 2); - ReftableWriter writer = new ReftableWriter() + ReftableWriter writer = new ReftableWriter(new ByteArrayOutputStream()) .setMinUpdateIndex(1) .setMaxUpdateIndex(1) - .begin(new ByteArrayOutputStream()); + .begin(); + + List<Ref> refs = new ArrayList<>(); + refs.add(master); + refs.add(master); - writer.writeRef(next); IllegalArgumentException e = assertThrows( IllegalArgumentException.class, - () -> writer.writeRef(master)); + () -> writer.sortAndWriteRefs(refs)); assertThat(e.getMessage(), containsString("records must be increasing")); } @Test public void invalidReflogWriteOrderUpdateIndex() throws IOException { - ReftableWriter writer = new ReftableWriter() + ReftableWriter writer = new ReftableWriter(new ByteArrayOutputStream()) .setMinUpdateIndex(1) .setMaxUpdateIndex(2) - .begin(new ByteArrayOutputStream()); + .begin(); PersonIdent who = new PersonIdent("Log", "Ger", 1500079709, -8 * 60); String msg = "test"; @@ -451,10 +524,10 @@ public class ReftableTest { @Test public void invalidReflogWriteOrderName() throws IOException { - ReftableWriter writer = new ReftableWriter() + ReftableWriter writer = new ReftableWriter(new ByteArrayOutputStream()) .setMinUpdateIndex(1) .setMaxUpdateIndex(1) - .begin(new ByteArrayOutputStream()); + .begin(); PersonIdent who = new PersonIdent("Log", "Ger", 1500079709, -8 * 60); String msg = "test"; @@ -473,10 +546,10 @@ public class ReftableTest { String msg = "test"; ByteArrayOutputStream buffer = new ByteArrayOutputStream(); - ReftableWriter writer = new ReftableWriter() + ReftableWriter writer = new ReftableWriter(buffer) .setMinUpdateIndex(1) .setMaxUpdateIndex(1) - .begin(buffer); + .begin(); writer.writeRef(master); writer.writeRef(next); @@ -523,16 +596,96 @@ public class ReftableTest { } @Test + public void reflogReader() throws IOException { + Ref master = ref(MASTER, 1); + Ref next = ref(NEXT, 2); + + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + ReftableWriter writer = new ReftableWriter(buffer).setMinUpdateIndex(1) + .setMaxUpdateIndex(1).begin(); + + writer.writeRef(master); + writer.writeRef(next); + + PersonIdent who1 = new PersonIdent("Log", "Ger", 1500079709, -8 * 60); + writer.writeLog(MASTER, 3, who1, ObjectId.zeroId(), id(1), "1"); + PersonIdent who2 = new PersonIdent("Log", "Ger", 1500079710, -8 * 60); + writer.writeLog(MASTER, 2, who2, id(1), id(2), "2"); + PersonIdent who3 = new PersonIdent("Log", "Ger", 1500079711, -8 * 60); + writer.writeLog(MASTER, 1, who3, id(2), id(3), "3"); + + writer.finish(); + byte[] table = buffer.toByteArray(); + + ReentrantLock lock = new ReentrantLock(); + ReftableReader t = read(table); + ReftableReflogReader rlr = new ReftableReflogReader(lock, t, MASTER); + + assertEquals(rlr.getLastEntry().getWho(), who1); + List<PersonIdent> all = rlr.getReverseEntries().stream() + .map(x -> x.getWho()).collect(Collectors.toList()); + Matchers.contains(all, who3, who2, who1); + + assertEquals(rlr.getReverseEntry(1).getWho(), who2); + + List<ReflogEntry> reverse2 = rlr.getReverseEntries(2); + Matchers.contains(reverse2, who3, who2); + + List<PersonIdent> more = rlr.getReverseEntries(4).stream() + .map(x -> x.getWho()).collect(Collectors.toList()); + assertEquals(all, more); + } + + @Test + public void allRefs() throws IOException { + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + ReftableConfig cfg = new ReftableConfig(); + cfg.setRefBlockSize(1024); + cfg.setLogBlockSize(1024); + cfg.setAlignBlocks(true); + ReftableWriter writer = new ReftableWriter(buffer) + .setMinUpdateIndex(1) + .setMaxUpdateIndex(1) + .setConfig(cfg) + .begin(); + PersonIdent who = new PersonIdent("Log", "Ger", 1500079709, -8 * 60); + + // Fill out the 1st ref block. + List<String> names = new ArrayList<>(); + for (int i = 0; i < 4; i++) { + @SuppressWarnings("boxing") + String name = new String(new char[220]).replace("\0", String.format("%c", i + 'a')); + names.add(name); + writer.writeRef(ref(name, i)); + } + + // Add some log data. + writer.writeLog(MASTER, 1, who, ObjectId.zeroId(), id(1), "msg"); + writer.finish(); + byte[] table = buffer.toByteArray(); + + ReftableReader t = read(table); + RefCursor c = t.allRefs(); + + int j = 0; + while (c.next()) { + assertEquals(names.get(j), c.getRef().getName()); + j++; + } + } + + + @Test public void reflogSeek() throws IOException { PersonIdent who = new PersonIdent("Log", "Ger", 1500079709, -8 * 60); String msg = "test"; String msgNext = "test next"; ByteArrayOutputStream buffer = new ByteArrayOutputStream(); - ReftableWriter writer = new ReftableWriter() + ReftableWriter writer = new ReftableWriter(buffer) .setMinUpdateIndex(1) .setMaxUpdateIndex(1) - .begin(buffer); + .begin(); writer.writeLog(MASTER, 1, who, ObjectId.zeroId(), id(1), msg); writer.writeLog(NEXT, 1, who, ObjectId.zeroId(), id(2), msgNext); @@ -572,10 +725,10 @@ public class ReftableTest { PersonIdent who = new PersonIdent("Log", "Ger", 1500079709, -8 * 60); ByteArrayOutputStream buffer = new ByteArrayOutputStream(); - ReftableWriter writer = new ReftableWriter() + ReftableWriter writer = new ReftableWriter(buffer) .setMinUpdateIndex(1) .setMaxUpdateIndex(1) - .begin(buffer); + .begin(); writer.writeLog("branchname", 1, who, ObjectId.zeroId(), id(1), "branchname"); @@ -596,10 +749,10 @@ public class ReftableTest { String msg = "test"; ByteArrayOutputStream buffer = new ByteArrayOutputStream(); - ReftableWriter writer = new ReftableWriter() + ReftableWriter writer = new ReftableWriter(buffer) .setMinUpdateIndex(1) .setMaxUpdateIndex(1) - .begin(buffer); + .begin(); writer.writeLog(MASTER, 1, who, ObjectId.zeroId(), id(1), msg); writer.writeLog(NEXT, 1, who, ObjectId.zeroId(), id(2), msg); writer.finish(); @@ -640,7 +793,6 @@ public class ReftableTest { } } - @SuppressWarnings("boxing") @Test public void logScan() throws IOException { ReftableConfig cfg = new ReftableConfig(); @@ -648,11 +800,12 @@ public class ReftableTest { cfg.setLogBlockSize(2048); ByteArrayOutputStream buffer = new ByteArrayOutputStream(); - ReftableWriter writer = new ReftableWriter(cfg); - writer.setMinUpdateIndex(1).setMaxUpdateIndex(1).begin(buffer); + ReftableWriter writer = new ReftableWriter(cfg, buffer); + writer.setMinUpdateIndex(1).setMaxUpdateIndex(1).begin(); List<Ref> refs = new ArrayList<>(); for (int i = 1; i <= 5670; i++) { + @SuppressWarnings("boxing") Ref ref = ref(String.format("refs/heads/%04d", i), i); refs.add(ref); writer.writeRef(ref); @@ -685,12 +838,13 @@ public class ReftableTest { } } - @SuppressWarnings("boxing") @Test public void byObjectIdOneRefNoIndex() throws IOException { List<Ref> refs = new ArrayList<>(); for (int i = 1; i <= 200; i++) { - refs.add(ref(String.format("refs/heads/%02d", i), i)); + @SuppressWarnings("boxing") + Ref ref = ref(String.format("refs/heads/%02d", i), i); + refs.add(ref); } refs.add(ref("refs/heads/master", 100)); @@ -718,12 +872,13 @@ public class ReftableTest { } } - @SuppressWarnings("boxing") @Test public void byObjectIdOneRefWithIndex() throws IOException { List<Ref> refs = new ArrayList<>(); for (int i = 1; i <= 5200; i++) { - refs.add(ref(String.format("refs/heads/%02d", i), i)); + @SuppressWarnings("boxing") + Ref ref = ref(String.format("refs/heads/%02d", i), i); + refs.add(ref); } refs.add(ref("refs/heads/master", 100)); @@ -768,7 +923,7 @@ public class ReftableTest { cfg.setRefBlockSize(64); ByteArrayOutputStream buffer = new ByteArrayOutputStream(); - ReftableWriter writer = new ReftableWriter(cfg).begin(buffer); + ReftableWriter writer = new ReftableWriter(cfg, buffer).begin(); writer.writeRef(ref("refs/heads/i-am-not-a-teapot", 1)); writer.finish(); fail("expected BlockSizeTooSmallException"); @@ -852,9 +1007,14 @@ public class ReftableTest { } private byte[] write(Collection<Ref> refs) throws IOException { + return write(refs, new ReftableConfig()); + } + + private byte[] write(Collection<Ref> refs, ReftableConfig cfg) throws IOException { ByteArrayOutputStream buffer = new ByteArrayOutputStream(); - stats = new ReftableWriter() - .begin(buffer) + stats = new ReftableWriter(buffer) + .setConfig(cfg) + .begin() .sortAndWriteRefs(refs) .finish() .getStats(); 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 index c3f5baa67b..50e0ed27c0 100644 --- 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 @@ -441,8 +441,9 @@ public class RefTreeDatabaseTest { ReceiveCommand cmd = command(null, B, "refs/txn/tmp"); BatchRefUpdate batch = refdb.newBatchUpdate(); batch.addCommand(cmd); - batch.execute(new RevWalk(repo), NullProgressMonitor.INSTANCE); - + try (RevWalk rw = new RevWalk(repo)) { + batch.execute(rw, NullProgressMonitor.INSTANCE); + } assertEquals(REJECTED_OTHER_REASON, cmd.getResult()); assertEquals(MessageFormat.format(JGitText.get().invalidRefName, "refs/txn/tmp"), cmd.getMessage()); @@ -461,8 +462,9 @@ public class RefTreeDatabaseTest { ReceiveCommand cmd = command(null, B, "refs/heads/pu.lock"); BatchRefUpdate batch = refdb.newBatchUpdate(); batch.addCommand(cmd); - batch.execute(new RevWalk(repo), NullProgressMonitor.INSTANCE); - + try (RevWalk rw = new RevWalk(repo)) { + batch.execute(rw, NullProgressMonitor.INSTANCE); + } assertEquals(REJECTED_OTHER_REASON, cmd.getResult()); assertEquals(JGitText.get().funnyRefname, cmd.getMessage()); assertEquals(txnId, getTxnCommitted()); @@ -481,7 +483,9 @@ public class RefTreeDatabaseTest { ReceiveCommand cmd = command(null, B, ORIG_HEAD); BatchRefUpdate batch = refdb.newBatchUpdate(); batch.addCommand(cmd); - batch.execute(new RevWalk(repo), NullProgressMonitor.INSTANCE); + try (RevWalk rw = new RevWalk(repo)) { + batch.execute(rw, NullProgressMonitor.INSTANCE); + } assertEquals(REJECTED_OTHER_REASON, cmd.getResult()); assertEquals( MessageFormat.format(JGitText.get().invalidRefName, ORIG_HEAD), @@ -500,7 +504,9 @@ public class RefTreeDatabaseTest { command(B, A, "refs/heads/masters")); BatchRefUpdate batchUpdate = refdb.newBatchUpdate(); batchUpdate.addCommand(commands); - batchUpdate.execute(new RevWalk(repo), NullProgressMonitor.INSTANCE); + try (RevWalk rw = new RevWalk(repo)) { + batchUpdate.execute(rw, NullProgressMonitor.INSTANCE); + } assertEquals(txnId, getTxnCommitted()); assertEquals(REJECTED_NONFASTFORWARD, @@ -523,7 +529,9 @@ public class RefTreeDatabaseTest { BatchRefUpdate batchUpdate = refdb.newBatchUpdate(); batchUpdate.setAllowNonFastForwards(true); batchUpdate.addCommand(commands); - batchUpdate.execute(new RevWalk(repo), NullProgressMonitor.INSTANCE); + try (RevWalk rw = new RevWalk(repo)) { + batchUpdate.execute(rw, NullProgressMonitor.INSTANCE); + } assertNotEquals(txnId, getTxnCommitted()); Map<String, Ref> refs = refdb.getRefs(ALL); @@ -547,13 +555,15 @@ public class RefTreeDatabaseTest { BatchRefUpdate batchUpdate = refdb.newBatchUpdate(); batchUpdate.setAllowNonFastForwards(true); batchUpdate.addCommand(commands); - batchUpdate.execute(new RevWalk(repo) { + try (RevWalk rw = new RevWalk(repo) { @Override public boolean isMergedInto(RevCommit base, RevCommit tip) { fail("isMergedInto() should not be called"); return false; } - }, NullProgressMonitor.INSTANCE); + }) { + batchUpdate.execute(rw, NullProgressMonitor.INSTANCE); + } assertNotEquals(txnId, getTxnCommitted()); Map<String, Ref> refs = refdb.getRefs(ALL); @@ -574,7 +584,9 @@ public class RefTreeDatabaseTest { BatchRefUpdate batchUpdate = refdb.newBatchUpdate(); batchUpdate.setAllowNonFastForwards(true); batchUpdate.addCommand(commands); - batchUpdate.execute(new RevWalk(repo), NullProgressMonitor.INSTANCE); + try (RevWalk rw = new RevWalk(repo)) { + batchUpdate.execute(rw, NullProgressMonitor.INSTANCE); + } assertEquals(txnId, getTxnCommitted()); assertEquals(LOCK_FAILURE, commands.get(0).getResult()); @@ -601,7 +613,9 @@ public class RefTreeDatabaseTest { BatchRefUpdate batchUpdate = refdb.newBatchUpdate(); batchUpdate.setAllowNonFastForwards(true); batchUpdate.addCommand(commands); - batchUpdate.execute(new RevWalk(repo), NullProgressMonitor.INSTANCE); + try (RevWalk rw = new RevWalk(repo)) { + batchUpdate.execute(rw, NullProgressMonitor.INSTANCE); + } assertNotEquals(txnId, getTxnCommitted()); assertEquals(OK, commands.get(0).getResult()); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/DirCacheCheckoutMaliciousPathTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/DirCacheCheckoutMaliciousPathTest.java index 057e0c881b..46fd902b6c 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/DirCacheCheckoutMaliciousPathTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/DirCacheCheckoutMaliciousPathTest.java @@ -341,48 +341,56 @@ public class DirCacheCheckoutMaliciousPathTest extends RepositoryTestCase { String... path) throws GitAPIException, IOException { try (Git git = new Git(db); RevWalk revWalk = new RevWalk(git.getRepository())) { - ObjectInserter newObjectInserter; - newObjectInserter = git.getRepository().newObjectInserter(); - ObjectId blobId = newObjectInserter.insert(Constants.OBJ_BLOB, + ObjectId blobId; + try (ObjectInserter newObjectInserter = git.getRepository() + .newObjectInserter()) { + blobId = newObjectInserter.insert(Constants.OBJ_BLOB, "data".getBytes(UTF_8)); - newObjectInserter = git.getRepository().newObjectInserter(); + } FileMode mode = FileMode.REGULAR_FILE; ObjectId insertId = blobId; - for (int i = path.length - 1; i >= 0; --i) { - TreeFormatter treeFormatter = new TreeFormatter(); - treeFormatter.append("goodpath", mode, insertId); - insertId = newObjectInserter.insert(treeFormatter); - mode = FileMode.TREE; + try (ObjectInserter newObjectInserter = git.getRepository() + .newObjectInserter()) { + for (int i = path.length - 1; i >= 0; --i) { + TreeFormatter treeFormatter = new TreeFormatter(); + treeFormatter.append("goodpath", mode, insertId); + insertId = newObjectInserter.insert(treeFormatter); + mode = FileMode.TREE; + } } - newObjectInserter = git.getRepository().newObjectInserter(); - CommitBuilder commitBuilder = new CommitBuilder(); - commitBuilder.setAuthor(author); - commitBuilder.setCommitter(committer); - commitBuilder.setMessage("foo#1"); - commitBuilder.setTreeId(insertId); - ObjectId firstCommitId = newObjectInserter.insert(commitBuilder); - - newObjectInserter = git.getRepository().newObjectInserter(); - mode = FileMode.REGULAR_FILE; - insertId = blobId; - for (int i = path.length - 1; i >= 0; --i) { - TreeFormatter treeFormatter = new TreeFormatter(); - treeFormatter.append(path[i].getBytes(UTF_8), 0, - path[i].getBytes(UTF_8).length, - mode, insertId, true); - insertId = newObjectInserter.insert(treeFormatter); - mode = FileMode.TREE; + ObjectId firstCommitId; + try (ObjectInserter newObjectInserter = git.getRepository() + .newObjectInserter()) { + CommitBuilder commitBuilder = new CommitBuilder(); + commitBuilder.setAuthor(author); + commitBuilder.setCommitter(committer); + commitBuilder.setMessage("foo#1"); + commitBuilder.setTreeId(insertId); + firstCommitId = newObjectInserter.insert(commitBuilder); } + ObjectId commitId; + try (ObjectInserter newObjectInserter = git.getRepository() + .newObjectInserter()) { + mode = FileMode.REGULAR_FILE; + insertId = blobId; + for (int i = path.length - 1; i >= 0; --i) { + TreeFormatter treeFormatter = new TreeFormatter(); + treeFormatter.append(path[i].getBytes(UTF_8), 0, + path[i].getBytes(UTF_8).length, mode, insertId, + true); + insertId = newObjectInserter.insert(treeFormatter); + mode = FileMode.TREE; + } - // Create another commit - commitBuilder = new CommitBuilder(); - commitBuilder.setAuthor(author); - commitBuilder.setCommitter(committer); - commitBuilder.setMessage("foo#2"); - commitBuilder.setTreeId(insertId); - commitBuilder.setParentId(firstCommitId); - ObjectId commitId = newObjectInserter.insert(commitBuilder); - + // Create another commit + CommitBuilder commitBuilder = new CommitBuilder(); + commitBuilder.setAuthor(author); + commitBuilder.setCommitter(committer); + commitBuilder.setMessage("foo#2"); + commitBuilder.setTreeId(insertId); + commitBuilder.setParentId(firstCommitId); + commitId = newObjectInserter.insert(commitBuilder); + } if (!secondCheckout) git.checkout().setStartPoint(revWalk.parseCommit(firstCommitId)) .setName("refs/heads/master").setCreateBranch(true).call(); 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 8092c3134b..a272c8f2ee 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 @@ -349,9 +349,11 @@ public class DirCacheCheckoutTest extends RepositoryTestCase { DirCacheEditor editor = dirCache.editor(); for (java.util.Map.Entry<String,String> e : indexEntries.entrySet()) { writeTrashFile(e.getKey(), e.getValue()); - ObjectInserter inserter = db.newObjectInserter(); - final ObjectId id = inserter.insert(Constants.OBJ_BLOB, + ObjectId id; + try (ObjectInserter inserter = db.newObjectInserter()) { + id = inserter.insert(Constants.OBJ_BLOB, Constants.encode(e.getValue())); + } editor.add(new DirCacheEditor.DeletePath(e.getKey())); editor.add(new DirCacheEditor.PathEdit(e.getKey()) { @Override diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/IndexDiffSubmoduleTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/IndexDiffSubmoduleTest.java index fa7f5ab522..014a587723 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/IndexDiffSubmoduleTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/IndexDiffSubmoduleTest.java @@ -60,9 +60,11 @@ import org.eclipse.jgit.errors.NoWorkTreeException; import org.eclipse.jgit.internal.storage.file.FileRepository; import org.eclipse.jgit.junit.JGitTestUtil; import org.eclipse.jgit.junit.RepositoryTestCase; +import org.eclipse.jgit.storage.file.FileBasedConfig; import org.eclipse.jgit.submodule.SubmoduleWalk.IgnoreSubmoduleMode; import org.eclipse.jgit.treewalk.FileTreeIterator; import org.junit.Before; +import org.junit.Test; import org.junit.experimental.theories.DataPoints; import org.junit.experimental.theories.Theories; import org.junit.experimental.theories.Theory; @@ -295,4 +297,79 @@ public class IndexDiffSubmoduleTest extends RepositoryTestCase { indexDiff.getAdded().toString()); } + @Test + public void testIndexDiffTwoSubmodules() throws Exception { + // Create a second submodule + try (Repository submodule2 = createWorkRepository()) { + JGitTestUtil.writeTrashFile(submodule2, "fileInSubmodule2", + "submodule2"); + Git subGit = Git.wrap(submodule2); + subGit.add().addFilepattern("fileInSubmodule2").call(); + subGit.commit().setMessage("add file to submodule2").call(); + + try (Repository sub2 = Git.wrap(db) + .submoduleAdd().setPath("modules/submodule2") + .setURI(submodule2.getDirectory().toURI().toString()) + .call()) { + writeTrashFile("fileInRoot", "root+"); + Git rootGit = Git.wrap(db); + rootGit.add().addFilepattern("fileInRoot").call(); + rootGit.commit().setMessage("add submodule2 and root file") + .call(); + // Now change files in both submodules + JGitTestUtil.writeTrashFile(submodule_db, "fileInSubmodule", + "submodule changed"); + JGitTestUtil.writeTrashFile(sub2, "fileInSubmodule2", + "submodule2 changed"); + // Set up .gitmodules + FileBasedConfig gitmodules = new FileBasedConfig( + new File(db.getWorkTree(), Constants.DOT_GIT_MODULES), + db.getFS()); + gitmodules.load(); + gitmodules.setString(ConfigConstants.CONFIG_SUBMODULE_SECTION, + "modules/submodule", ConfigConstants.CONFIG_KEY_IGNORE, + "all"); + gitmodules.setString(ConfigConstants.CONFIG_SUBMODULE_SECTION, + "modules/submodule2", ConfigConstants.CONFIG_KEY_IGNORE, + "none"); + gitmodules.save(); + IndexDiff indexDiff = new IndexDiff(db, Constants.HEAD, + new FileTreeIterator(db)); + assertTrue(indexDiff.diff()); + String[] modified = indexDiff.getModified() + .toArray(new String[0]); + Arrays.sort(modified); + assertEquals("[.gitmodules, modules/submodule2]", + Arrays.toString(modified)); + // Try again with "dirty" + gitmodules.setString(ConfigConstants.CONFIG_SUBMODULE_SECTION, + "modules/submodule", ConfigConstants.CONFIG_KEY_IGNORE, + "dirty"); + gitmodules.save(); + indexDiff = new IndexDiff(db, Constants.HEAD, + new FileTreeIterator(db)); + assertTrue(indexDiff.diff()); + modified = indexDiff.getModified().toArray(new String[0]); + Arrays.sort(modified); + assertEquals("[.gitmodules, modules/submodule2]", + Arrays.toString(modified)); + // Test the config override + StoredConfig cfg = db.getConfig(); + cfg.setString(ConfigConstants.CONFIG_SUBMODULE_SECTION, + "modules/submodule", ConfigConstants.CONFIG_KEY_IGNORE, + "none"); + cfg.setString(ConfigConstants.CONFIG_SUBMODULE_SECTION, + "modules/submodule2", ConfigConstants.CONFIG_KEY_IGNORE, + "all"); + cfg.save(); + indexDiff = new IndexDiff(db, Constants.HEAD, + new FileTreeIterator(db)); + assertTrue(indexDiff.diff()); + modified = indexDiff.getModified().toArray(new String[0]); + Arrays.sort(modified); + assertEquals("[.gitmodules, modules/submodule]", + Arrays.toString(modified)); + } + } + } } 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 ba5aaf1b18..cf954070e0 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 @@ -81,10 +81,12 @@ public class IndexDiffTest extends RepositoryTestCase { static PathEdit add(final Repository db, final File workdir, final String path) throws FileNotFoundException, IOException { - ObjectInserter inserter = db.newObjectInserter(); final File f = new File(workdir, path); - final ObjectId id = inserter.insert(Constants.OBJ_BLOB, + ObjectId id; + try (ObjectInserter inserter = db.newObjectInserter()) { + id = inserter.insert(Constants.OBJ_BLOB, IO.readFully(f)); + } return new PathEdit(path) { @Override public void apply(DirCacheEntry ent) { @@ -122,9 +124,11 @@ public class IndexDiffTest extends RepositoryTestCase { public void testMissing() throws Exception { File file2 = writeTrashFile("file2", "file2"); File file3 = writeTrashFile("dir/file3", "dir/file3"); - Git git = Git.wrap(db); - git.add().addFilepattern("file2").addFilepattern("dir/file3").call(); - git.commit().setMessage("commit").call(); + try (Git git = new Git(db)) { + git.add().addFilepattern("file2").addFilepattern("dir/file3") + .call(); + git.commit().setMessage("commit").call(); + } assertTrue(file2.delete()); assertTrue(file3.delete()); IndexDiff diff = new IndexDiff(db, Constants.HEAD, diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ObjectIdSerializerTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ObjectIdSerializerTest.java index d98b792d75..f0733f4782 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ObjectIdSerializerTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ObjectIdSerializerTest.java @@ -88,9 +88,8 @@ public class ObjectIdSerializerTest { try (InputStream in = new FileInputStream(file)) { if (objectId == null) { return ObjectIdSerializer.read(in); - } else { - return ObjectIdSerializer.readWithoutMarker(in); } + return ObjectIdSerializer.readWithoutMarker(in); } } } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/RefDatabaseConflictingNamesTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/RefDatabaseConflictingNamesTest.java index cbb47fa829..3f77ca25a3 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/RefDatabaseConflictingNamesTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/RefDatabaseConflictingNamesTest.java @@ -67,9 +67,8 @@ public class RefDatabaseConflictingNamesTest { existing.put("refs/heads/a/b", null /* not used */); existing.put("refs/heads/q", null /* not used */); return existing; - } else { - return Collections.emptyMap(); } + return Collections.emptyMap(); } @Override diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ReflogConfigTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ReflogConfigTest.java index f2f277c6ea..9be71c3a02 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ReflogConfigTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ReflogConfigTest.java @@ -45,7 +45,7 @@ package org.eclipse.jgit.lib; -import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import java.io.IOException; @@ -78,7 +78,10 @@ public class ReflogConfigTest extends RepositoryTestCase { // set the logAllRefUpdates parameter to true and check it cfg.setBoolean("core", null, "logallrefupdates", true); cfg.save(); - assertTrue(cfg.get(CoreConfig.KEY).isLogAllRefUpdates()); + assertEquals(CoreConfig.LogRefUpdates.TRUE, + cfg.getEnum(ConfigConstants.CONFIG_CORE_SECTION, null, + ConfigConstants.CONFIG_KEY_LOGALLREFUPDATES, + CoreConfig.LogRefUpdates.FALSE)); // do one commit and check that reflog size is increased to 1 commit("A Commit\n", commitTime, tz); @@ -90,13 +93,32 @@ public class ReflogConfigTest extends RepositoryTestCase { // set the logAllRefUpdates parameter to false and check it cfg.setBoolean("core", null, "logallrefupdates", false); cfg.save(); - assertFalse(cfg.get(CoreConfig.KEY).isLogAllRefUpdates()); + assertEquals(CoreConfig.LogRefUpdates.FALSE, + cfg.getEnum(ConfigConstants.CONFIG_CORE_SECTION, null, + ConfigConstants.CONFIG_KEY_LOGALLREFUPDATES, + CoreConfig.LogRefUpdates.TRUE)); // do one commit and check that reflog size is 2 commit("A Commit\n", commitTime, tz); + commitTime += 60 * 1000; assertTrue( "Reflog for HEAD should contain two entries", db.getReflogReader(Constants.HEAD).getReverseEntries().size() == 2); + + // set the logAllRefUpdates parameter to false and check it + cfg.setEnum("core", null, "logallrefupdates", + CoreConfig.LogRefUpdates.ALWAYS); + cfg.save(); + assertEquals(CoreConfig.LogRefUpdates.ALWAYS, + cfg.getEnum(ConfigConstants.CONFIG_CORE_SECTION, null, + ConfigConstants.CONFIG_KEY_LOGALLREFUPDATES, + CoreConfig.LogRefUpdates.FALSE)); + + // do one commit and check that reflog size is 3 + commit("A Commit\n", commitTime, tz); + assertTrue("Reflog for HEAD should contain three entries", + db.getReflogReader(Constants.HEAD).getReverseEntries() + .size() == 3); } private void commit(String commitMsg, long commitTime, int tz) diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/internal/BouncyCastleGpgKeyLocatorTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/internal/BouncyCastleGpgKeyLocatorTest.java new file mode 100644 index 0000000000..220b2becba --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/internal/BouncyCastleGpgKeyLocatorTest.java @@ -0,0 +1,167 @@ +/* + * Copyright (C) 2019, Thomas Wolf <thomas.wolf@paranor.ch> + * 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.internal; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.util.Locale; + +import org.junit.Test; + +public class BouncyCastleGpgKeyLocatorTest { + + private static final String USER_ID = "Heinrich Heine <heinrichh@uni-duesseldorf.de>"; + + private static boolean match(String userId, String pattern) { + return BouncyCastleGpgKeyLocator.containsSigningKey(userId, pattern); + } + + @Test + public void testFullMatch() throws Exception { + assertTrue(match(USER_ID, + "=Heinrich Heine <heinrichh@uni-duesseldorf.de>")); + assertFalse(match(USER_ID, "=Heinrich Heine")); + assertFalse(match(USER_ID, "= ")); + assertFalse(match(USER_ID, "=heinrichh@uni-duesseldorf.de")); + } + + @Test + public void testEmpty() throws Exception { + assertFalse(match(USER_ID, "")); + assertFalse(match(USER_ID, null)); + assertFalse(match("", "")); + assertFalse(match(null, "")); + assertFalse(match(null, null)); + assertFalse(match("", "something")); + assertFalse(match(null, "something")); + } + + @Test + public void testFullEmail() throws Exception { + assertTrue(match(USER_ID, "<heinrichh@uni-duesseldorf.de>")); + assertTrue(match(USER_ID + " ", "<heinrichh@uni-duesseldorf.de>")); + assertFalse(match(USER_ID, "<>")); + assertFalse(match(USER_ID, "<h>")); + assertFalse(match(USER_ID, "<heinrichh>")); + assertFalse(match(USER_ID, "<uni-duesseldorf>")); + assertFalse(match(USER_ID, "<h@u>")); + assertFalse(match(USER_ID, "<HeinrichH@uni-duesseldorf.de>")); + assertFalse(match(USER_ID.substring(0, USER_ID.length() - 1), + "<heinrichh@uni-duesseldorf.de>")); + assertFalse(match("", "<>")); + assertFalse(match("", "<heinrichh@uni-duesseldorf.de>")); + } + + @Test + public void testPartialEmail() throws Exception { + assertTrue(match(USER_ID, "@heinrichh@uni-duesseldorf.de")); + assertTrue(match(USER_ID, "@heinrichh")); + assertTrue(match(USER_ID, "@duesseldorf")); + assertTrue(match(USER_ID, "@uni-d")); + assertTrue(match(USER_ID, "@h")); + assertTrue(match(USER_ID, "@.")); + assertTrue(match(USER_ID, "@h@u")); + assertFalse(match(USER_ID, "@ ")); + assertFalse(match(USER_ID, "@")); + assertFalse(match(USER_ID, "@Heine")); + assertFalse(match(USER_ID, "@HeinrichH")); + assertFalse(match(USER_ID, "@Heinrich")); + assertFalse(match("", "@")); + assertFalse(match("", "@h")); + } + + private void substringTests(String prefix) throws Exception { + assertTrue(match(USER_ID, prefix + "heinrichh@uni-duesseldorf.de")); + assertTrue(match(USER_ID, prefix + "heinrich")); + assertTrue(match(USER_ID, prefix + "HEIN")); + assertTrue(match(USER_ID, prefix + "Heine <")); + assertTrue(match(USER_ID, prefix + "UNI")); + assertTrue(match(USER_ID, prefix + "uni")); + assertTrue(match(USER_ID, prefix + "rich He")); + assertTrue(match(USER_ID, prefix + "h@u")); + assertTrue(match(USER_ID, prefix + USER_ID)); + assertTrue(match(USER_ID, prefix + USER_ID.toUpperCase(Locale.ROOT))); + assertFalse(match(USER_ID, prefix + "")); + assertFalse(match(USER_ID, prefix + " ")); + assertFalse(match(USER_ID, prefix + "yy")); + assertFalse(match("", prefix + "")); + assertFalse(match("", prefix + "uni")); + } + + @Test + public void testSubstringPlain() throws Exception { + substringTests(""); + } + + @Test + public void testSubstringAsterisk() throws Exception { + substringTests("*"); + } + + @Test + public void testExplicitFingerprint() throws Exception { + assertFalse(match("John Fade <j.fade@example.com>", "0xfade")); + assertFalse(match("John Fade <0xfade@example.com>", "0xfade")); + assertFalse(match("", "0xfade")); + } + + @Test + public void testImplicitFingerprint() throws Exception { + assertTrue(match("John Fade <j.fade@example.com>", "fade")); + assertTrue(match("John Fade <0xfade@example.com>", "fade")); + assertTrue(match("John Fade <j.fade@example.com>", "FADE")); + assertTrue(match("John Fade <0xfade@example.com>", "FADE")); + } + + @Test + public void testZeroX() throws Exception { + assertTrue(match("John Fade <0xfade@example.com>", "0x")); + assertTrue(match("John Fade <0xfade@example.com>", "*0x")); + assertTrue(match("John Fade <0xfade@example.com>", "*0xfade")); + assertTrue(match("John Fade <0xfade@example.com>", "*0xFADE")); + assertTrue(match("John Fade <0xfade@example.com>", "@0xfade")); + assertFalse(match("John Fade <0xfade@example.com>", "@0xFADE")); + assertFalse(match("", "0x")); + } +} diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/CherryPickTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/CherryPickTest.java index 19f6dcbc59..aa4392fcac 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/CherryPickTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/CherryPickTest.java @@ -106,23 +106,24 @@ public class CherryPickTest extends RepositoryTestCase { boolean merge = twm.merge(new ObjectId[] { O, T }); assertTrue(merge); - final TreeWalk tw = new TreeWalk(db); - tw.setRecursive(true); - tw.reset(twm.getResultTreeId()); + try (TreeWalk tw = new TreeWalk(db)) { + tw.setRecursive(true); + tw.reset(twm.getResultTreeId()); - assertTrue(tw.next()); - assertEquals("a", tw.getPathString()); - assertCorrectId(treeO, tw); + assertTrue(tw.next()); + assertEquals("a", tw.getPathString()); + assertCorrectId(treeO, tw); - assertTrue(tw.next()); - assertEquals("o", tw.getPathString()); - assertCorrectId(treeO, tw); + assertTrue(tw.next()); + assertEquals("o", tw.getPathString()); + assertCorrectId(treeO, tw); - assertTrue(tw.next()); - assertEquals("t", tw.getPathString()); - assertCorrectId(treeT, tw); + assertTrue(tw.next()); + assertEquals("t", tw.getPathString()); + assertCorrectId(treeT, tw); - assertFalse(tw.next()); + assertFalse(tw.next()); + } } @Test @@ -168,19 +169,20 @@ public class CherryPickTest extends RepositoryTestCase { boolean merge = twm.merge(new ObjectId[] { B, T }); assertTrue(merge); - final TreeWalk tw = new TreeWalk(db); - tw.setRecursive(true); - tw.reset(twm.getResultTreeId()); + try (TreeWalk tw = new TreeWalk(db)) { + tw.setRecursive(true); + tw.reset(twm.getResultTreeId()); - assertTrue(tw.next()); - assertEquals("a", tw.getPathString()); - assertCorrectId(treeB, tw); + assertTrue(tw.next()); + assertEquals("a", tw.getPathString()); + assertCorrectId(treeB, tw); - assertTrue(tw.next()); - assertEquals("t", tw.getPathString()); - assertCorrectId(treeT, tw); + assertTrue(tw.next()); + assertEquals("t", tw.getPathString()); + assertCorrectId(treeT, tw); - assertFalse(tw.next()); + assertFalse(tw.next()); + } } private static void assertCorrectId(DirCache treeT, TreeWalk tw) { diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/CrissCrossMergeTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/CrissCrossMergeTest.java index a67c750dba..5c6636c89e 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/CrissCrossMergeTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/CrissCrossMergeTest.java @@ -881,9 +881,9 @@ public class CrissCrossMergeTest extends RepositoryTestCase { } StringBuilder result = new StringBuilder(); - ObjectReader or = r.newObjectReader(); - try (BufferedReader br = new BufferedReader( - new InputStreamReader(or.open(blobId).openStream(), UTF_8))) { + try (ObjectReader or = r.newObjectReader(); + BufferedReader br = new BufferedReader(new InputStreamReader( + or.open(blobId).openStream(), UTF_8))) { String line; boolean first = true; while ((line = br.readLine()) != null) { diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/MergerTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/MergerTest.java index 62495fb023..3379a25377 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/MergerTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/MergerTest.java @@ -1365,8 +1365,8 @@ public class MergerTest extends RepositoryTestCase { } private String readBlob(ObjectId treeish, String path) throws Exception { - try (TestRepository<?> tr = new TestRepository<>(db)) { - RevWalk rw = tr.getRevWalk(); + try (TestRepository<?> tr = new TestRepository<>(db); + RevWalk rw = tr.getRevWalk()) { RevTree tree = rw.parseTree(treeish); RevObject obj = tr.get(tree, path); if (obj == null) { diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/SimpleMergeTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/SimpleMergeTest.java index dd2c2e84b6..6c0b165a4f 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/SimpleMergeTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/SimpleMergeTest.java @@ -174,23 +174,24 @@ public class SimpleMergeTest extends SampleDataRepositoryTestCase { boolean merge = ourMerger.merge(new ObjectId[] { o, t }); assertTrue(merge); - final TreeWalk tw = new TreeWalk(db); - tw.setRecursive(true); - tw.reset(ourMerger.getResultTreeId()); + try (TreeWalk tw = new TreeWalk(db)) { + tw.setRecursive(true); + tw.reset(ourMerger.getResultTreeId()); - assertTrue(tw.next()); - assertEquals("Makefile", tw.getPathString()); - assertCorrectId(treeO, tw); + assertTrue(tw.next()); + assertEquals("Makefile", tw.getPathString()); + assertCorrectId(treeO, tw); - assertTrue(tw.next()); - assertEquals("libelf-po/a", tw.getPathString()); - assertCorrectId(treeO, tw); + assertTrue(tw.next()); + assertEquals("libelf-po/a", tw.getPathString()); + assertCorrectId(treeO, tw); - assertTrue(tw.next()); - assertEquals("libelf/c", tw.getPathString()); - assertCorrectId(treeT, tw); + assertTrue(tw.next()); + assertEquals("libelf/c", tw.getPathString()); + assertCorrectId(treeT, tw); - assertFalse(tw.next()); + assertFalse(tw.next()); + } } @Test @@ -226,19 +227,20 @@ public class SimpleMergeTest extends SampleDataRepositoryTestCase { boolean merge = ourMerger.merge(new ObjectId[] { o, t }); assertTrue(merge); - final TreeWalk tw = new TreeWalk(db); - tw.setRecursive(true); - tw.reset(ourMerger.getResultTreeId()); + try (TreeWalk tw = new TreeWalk(db)) { + tw.setRecursive(true); + tw.reset(ourMerger.getResultTreeId()); - assertTrue(tw.next()); - assertEquals("d/o", tw.getPathString()); - assertCorrectId(treeO, tw); + assertTrue(tw.next()); + assertEquals("d/o", tw.getPathString()); + assertCorrectId(treeO, tw); - assertTrue(tw.next()); - assertEquals("d/t", tw.getPathString()); - assertCorrectId(treeT, tw); + assertTrue(tw.next()); + assertEquals("d/t", tw.getPathString()); + assertCorrectId(treeT, tw); - assertFalse(tw.next()); + assertFalse(tw.next()); + } } @Test diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revplot/AbstractPlotRendererTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revplot/AbstractPlotRendererTest.java index f265315338..ac157b6b87 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revplot/AbstractPlotRendererTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revplot/AbstractPlotRendererTest.java @@ -44,7 +44,6 @@ package org.eclipse.jgit.revplot; import static org.junit.Assert.assertEquals; -import java.io.IOException; import java.util.LinkedList; import java.util.List; @@ -55,7 +54,6 @@ import org.eclipse.jgit.api.errors.GitAPIException; import org.eclipse.jgit.junit.RepositoryTestCase; import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.Ref; -import org.eclipse.jgit.lib.Repository; import org.junit.Before; import org.junit.Test; @@ -83,23 +81,18 @@ public class AbstractPlotRendererTest extends RepositoryTestCase { git.commit().setMessage("commit on master").call(); MergeResult mergeCall = merge(db.resolve("topic")); ObjectId start = mergeCall.getNewHead(); - PlotCommitList<PlotLane> commitList = createCommitList(start); + try (PlotWalk walk = new PlotWalk(db)) { + walk.markStart(walk.parseCommit(start)); + PlotCommitList<PlotLane> commitList = new PlotCommitList<>(); + commitList.source(walk); + commitList.fillTo(1000); - for (int i = 0; i < commitList.size(); i++) - plotRenderer.paintCommit(commitList.get(i), 30); + for (int i = 0; i < commitList.size(); i++) + plotRenderer.paintCommit(commitList.get(i), 30); - List<Integer> indentations = plotRenderer.indentations; - assertEquals(indentations.get(2), indentations.get(3)); - } - - private PlotCommitList<PlotLane> createCommitList(ObjectId start) - throws IOException { - TestPlotWalk walk = new TestPlotWalk(db); - walk.markStart(walk.parseCommit(start)); - PlotCommitList<PlotLane> commitList = new PlotCommitList<>(); - commitList.source(walk); - commitList.fillTo(1000); - return commitList; + List<Integer> indentations = plotRenderer.indentations; + assertEquals(indentations.get(2), indentations.get(3)); + } } private MergeResult merge(ObjectId includeId) throws GitAPIException { @@ -107,12 +100,6 @@ public class AbstractPlotRendererTest extends RepositoryTestCase { .include(includeId).call(); } - private static class TestPlotWalk extends PlotWalk { - public TestPlotWalk(Repository repo) { - super(repo); - } - } - private static class TestPlotRenderer extends AbstractPlotRenderer<PlotLane, Object> { diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revplot/PlotCommitListTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revplot/PlotCommitListTest.java index 7297de3646..0c367f457e 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revplot/PlotCommitListTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revplot/PlotCommitListTest.java @@ -135,18 +135,19 @@ public class PlotCommitListTest extends RevWalkTestCase { final RevCommit b = commit(a); final RevCommit c = commit(b); - PlotWalk pw = new PlotWalk(db); - pw.markStart(pw.lookupCommit(c.getId())); - - PlotCommitList<PlotLane> pcl = new PlotCommitList<>(); - pcl.source(pw); - pcl.fillTo(Integer.MAX_VALUE); - - CommitListAssert test = new CommitListAssert(pcl); - test.commit(c).lanePos(0).parents(b); - test.commit(b).lanePos(0).parents(a); - test.commit(a).lanePos(0).parents(); - test.noMoreCommits(); + try (PlotWalk pw = new PlotWalk(db)) { + pw.markStart(pw.lookupCommit(c.getId())); + + PlotCommitList<PlotLane> pcl = new PlotCommitList<>(); + pcl.source(pw); + pcl.fillTo(Integer.MAX_VALUE); + + CommitListAssert test = new CommitListAssert(pcl); + test.commit(c).lanePos(0).parents(b); + test.commit(b).lanePos(0).parents(a); + test.commit(a).lanePos(0).parents(); + test.noMoreCommits(); + } } @Test @@ -156,19 +157,20 @@ public class PlotCommitListTest extends RevWalkTestCase { final RevCommit c = commit(a); final RevCommit d = commit(b, c); - PlotWalk pw = new PlotWalk(db); - pw.markStart(pw.lookupCommit(d.getId())); + try (PlotWalk pw = new PlotWalk(db)) { + pw.markStart(pw.lookupCommit(d.getId())); - PlotCommitList<PlotLane> pcl = new PlotCommitList<>(); - pcl.source(pw); - pcl.fillTo(Integer.MAX_VALUE); + PlotCommitList<PlotLane> pcl = new PlotCommitList<>(); + pcl.source(pw); + pcl.fillTo(Integer.MAX_VALUE); - CommitListAssert test = new CommitListAssert(pcl); - test.commit(d).lanePos(0).parents(b, c); - test.commit(c).lanePos(1).parents(a); - test.commit(b).lanePos(0).parents(a); - test.commit(a).lanePos(0).parents(); - test.noMoreCommits(); + CommitListAssert test = new CommitListAssert(pcl); + test.commit(d).lanePos(0).parents(b, c); + test.commit(c).lanePos(1).parents(a); + test.commit(b).lanePos(0).parents(a); + test.commit(a).lanePos(0).parents(); + test.noMoreCommits(); + } } @Test @@ -177,20 +179,21 @@ public class PlotCommitListTest extends RevWalkTestCase { final RevCommit b = commit(a); final RevCommit c = commit(a); - PlotWalk pw = new PlotWalk(db); - pw.markStart(pw.lookupCommit(b.getId())); - pw.markStart(pw.lookupCommit(c.getId())); + try (PlotWalk pw = new PlotWalk(db)) { + pw.markStart(pw.lookupCommit(b.getId())); + pw.markStart(pw.lookupCommit(c.getId())); - PlotCommitList<PlotLane> pcl = new PlotCommitList<>(); - pcl.source(pw); - pcl.fillTo(Integer.MAX_VALUE); + PlotCommitList<PlotLane> pcl = new PlotCommitList<>(); + pcl.source(pw); + pcl.fillTo(Integer.MAX_VALUE); - Set<Integer> childPositions = asSet(0, 1); - CommitListAssert test = new CommitListAssert(pcl); - test.commit(c).lanePos(childPositions).parents(a); - test.commit(b).lanePos(childPositions).parents(a); - test.commit(a).lanePos(0).parents(); - test.noMoreCommits(); + Set<Integer> childPositions = asSet(0, 1); + CommitListAssert test = new CommitListAssert(pcl); + test.commit(c).lanePos(childPositions).parents(a); + test.commit(b).lanePos(childPositions).parents(a); + test.commit(a).lanePos(0).parents(); + test.noMoreCommits(); + } } @Test @@ -200,22 +203,23 @@ public class PlotCommitListTest extends RevWalkTestCase { final RevCommit c = commit(a); final RevCommit d = commit(a); - PlotWalk pw = new PlotWalk(db); - pw.markStart(pw.lookupCommit(b.getId())); - pw.markStart(pw.lookupCommit(c.getId())); - pw.markStart(pw.lookupCommit(d.getId())); - - PlotCommitList<PlotLane> pcl = new PlotCommitList<>(); - pcl.source(pw); - pcl.fillTo(Integer.MAX_VALUE); - - Set<Integer> childPositions = asSet(0, 1, 2); - CommitListAssert test = new CommitListAssert(pcl); - test.commit(d).lanePos(childPositions).parents(a); - test.commit(c).lanePos(childPositions).parents(a); - test.commit(b).lanePos(childPositions).parents(a); - test.commit(a).lanePos(0).parents(); - test.noMoreCommits(); + try (PlotWalk pw = new PlotWalk(db)) { + pw.markStart(pw.lookupCommit(b.getId())); + pw.markStart(pw.lookupCommit(c.getId())); + pw.markStart(pw.lookupCommit(d.getId())); + + PlotCommitList<PlotLane> pcl = new PlotCommitList<>(); + pcl.source(pw); + pcl.fillTo(Integer.MAX_VALUE); + + Set<Integer> childPositions = asSet(0, 1, 2); + CommitListAssert test = new CommitListAssert(pcl); + test.commit(d).lanePos(childPositions).parents(a); + test.commit(c).lanePos(childPositions).parents(a); + test.commit(b).lanePos(childPositions).parents(a); + test.commit(a).lanePos(0).parents(); + test.noMoreCommits(); + } } @Test @@ -228,34 +232,35 @@ public class PlotCommitListTest extends RevWalkTestCase { final RevCommit f = commit(a); final RevCommit g = commit(f); - PlotWalk pw = new PlotWalk(db); - // TODO: when we add unnecessary commit's as tips (e.g. a commit which - // is a parent of another tip) the walk will return those commits twice. - // Find out why! - // pw.markStart(pw.lookupCommit(a.getId())); - pw.markStart(pw.lookupCommit(b.getId())); - pw.markStart(pw.lookupCommit(c.getId())); - pw.markStart(pw.lookupCommit(d.getId())); - pw.markStart(pw.lookupCommit(e.getId())); - // pw.markStart(pw.lookupCommit(f.getId())); - pw.markStart(pw.lookupCommit(g.getId())); - - PlotCommitList<PlotLane> pcl = new PlotCommitList<>(); - pcl.source(pw); - pcl.fillTo(Integer.MAX_VALUE); - - Set<Integer> childPositions = asSet(0, 1, 2, 3, 4); - CommitListAssert test = new CommitListAssert(pcl); - int posG = test.commit(g).lanePos(childPositions).parents(f) - .getLanePos(); - test.commit(f).lanePos(posG).parents(a); - - test.commit(e).lanePos(childPositions).parents(a); - test.commit(d).lanePos(childPositions).parents(a); - test.commit(c).lanePos(childPositions).parents(a); - test.commit(b).lanePos(childPositions).parents(a); - test.commit(a).lanePos(0).parents(); - test.noMoreCommits(); + try (PlotWalk pw = new PlotWalk(db)) { + // TODO: when we add unnecessary commit's as tips (e.g. a commit + // which is a parent of another tip) the walk will return those + // commits twice. Find out why! + // pw.markStart(pw.lookupCommit(a.getId())); + pw.markStart(pw.lookupCommit(b.getId())); + pw.markStart(pw.lookupCommit(c.getId())); + pw.markStart(pw.lookupCommit(d.getId())); + pw.markStart(pw.lookupCommit(e.getId())); + // pw.markStart(pw.lookupCommit(f.getId())); + pw.markStart(pw.lookupCommit(g.getId())); + + PlotCommitList<PlotLane> pcl = new PlotCommitList<>(); + pcl.source(pw); + pcl.fillTo(Integer.MAX_VALUE); + + Set<Integer> childPositions = asSet(0, 1, 2, 3, 4); + CommitListAssert test = new CommitListAssert(pcl); + int posG = test.commit(g).lanePos(childPositions).parents(f) + .getLanePos(); + test.commit(f).lanePos(posG).parents(a); + + test.commit(e).lanePos(childPositions).parents(a); + test.commit(d).lanePos(childPositions).parents(a); + test.commit(c).lanePos(childPositions).parents(a); + test.commit(b).lanePos(childPositions).parents(a); + test.commit(a).lanePos(0).parents(); + test.noMoreCommits(); + } } @Test @@ -270,25 +275,26 @@ public class PlotCommitListTest extends RevWalkTestCase { final RevCommit h = commit(f); final RevCommit i = commit(h); - PlotWalk pw = new PlotWalk(db); - pw.markStart(pw.lookupCommit(i.getId())); - pw.markStart(pw.lookupCommit(g.getId())); - - PlotCommitList<PlotLane> pcl = new PlotCommitList<>(); - pcl.source(pw); - pcl.fillTo(Integer.MAX_VALUE); - Set<Integer> childPositions = asSet(0, 1); - CommitListAssert test = new CommitListAssert(pcl); - int posI = test.commit(i).lanePos(childPositions).parents(h) - .getLanePos(); - test.commit(h).lanePos(posI).parents(f); - test.commit(g).lanePos(childPositions).parents(a); - test.commit(f).lanePos(posI).parents(e, d); - test.commit(e).lanePos(posI).parents(c); - test.commit(d).lanePos(2).parents(b); - test.commit(c).lanePos(posI).parents(b); - test.commit(b).lanePos(posI).parents(a); - test.commit(a).lanePos(0).parents(); + try (PlotWalk pw = new PlotWalk(db)) { + pw.markStart(pw.lookupCommit(i.getId())); + pw.markStart(pw.lookupCommit(g.getId())); + + PlotCommitList<PlotLane> pcl = new PlotCommitList<>(); + pcl.source(pw); + pcl.fillTo(Integer.MAX_VALUE); + Set<Integer> childPositions = asSet(0, 1); + CommitListAssert test = new CommitListAssert(pcl); + int posI = test.commit(i).lanePos(childPositions).parents(h) + .getLanePos(); + test.commit(h).lanePos(posI).parents(f); + test.commit(g).lanePos(childPositions).parents(a); + test.commit(f).lanePos(posI).parents(e, d); + test.commit(e).lanePos(posI).parents(c); + test.commit(d).lanePos(2).parents(b); + test.commit(c).lanePos(posI).parents(b); + test.commit(b).lanePos(posI).parents(a); + test.commit(a).lanePos(0).parents(); + } } // test the history of the egit project between 9fdaf3c1 and e76ad9170f @@ -330,67 +336,71 @@ public class PlotCommitListTest extends RevWalkTestCase { final RevCommit merge_fixed_logged_npe = commit(sort_roots, fix_logged_npe); - PlotWalk pw = new PlotWalk(db); - pw.markStart(pw.lookupCommit(merge_fixed_logged_npe.getId())); - - PlotCommitList<PlotLane> pcl = new PlotCommitList<>(); - pcl.source(pw); - pcl.fillTo(Integer.MAX_VALUE); - - CommitListAssert test = new CommitListAssert(pcl); - - // Note: all positions of side branches are rather arbitrary, but some - // may not overlap. Testing for the positions yielded by the current - // implementation, which was manually checked to not overlap. - final int mainPos = 0; - test.commit(merge_fixed_logged_npe).parents(sort_roots, fix_logged_npe) - .lanePos(mainPos); - test.commit(fix_logged_npe).parents(merge_changeset_implementation) - .lanePos(1); - test.commit(sort_roots).parents(merge_update_eclipse).lanePos(mainPos); - test.commit(merge_update_eclipse).parents(add_a_clear, update_eclipse) - .lanePos(mainPos); - test.commit(add_a_clear).parents(fix_broken).lanePos(mainPos); - test.commit(fix_broken).parents(merge_disable_comment).lanePos(mainPos); - test.commit(merge_disable_comment) - .parents(merge_resolve_handler, disable_comment) - .lanePos(mainPos); - test.commit(disable_comment).parents(clone_operation).lanePos(2); - test.commit(merge_resolve_handler) - .parents(clone_operation, resolve_handler).lanePos(mainPos); - test.commit(update_eclipse).parents(add_Maven).lanePos(3); - test.commit(clone_operation).parents(merge_changeset_implementation) - .lanePos(mainPos); - test.commit(merge_changeset_implementation) - .parents(merge_disable_source, changeset_implementation) - .lanePos(mainPos); - test.commit(merge_disable_source) - .parents(update_eclipse_iplog2, disable_source) - .lanePos(mainPos); - test.commit(update_eclipse_iplog2).parents(merge_use_remote) - .lanePos(mainPos); - test.commit(disable_source).parents(merge_use_remote).lanePos(1); - test.commit(merge_use_remote).parents(update_eclipse_iplog, use_remote) - .lanePos(mainPos); - test.commit(changeset_implementation).parents(clear_repositorycache) - .lanePos(2); - test.commit(update_eclipse_iplog).parents(merge_add_Maven) - .lanePos(mainPos); - test.commit(merge_add_Maven).parents(findToolBar_layout, add_Maven) - .lanePos(mainPos); - test.commit(findToolBar_layout).parents(clear_repositorycache) - .lanePos(mainPos); - test.commit(use_remote).parents(clear_repositorycache).lanePos(1); - test.commit(add_Maven).parents(clear_repositorycache).lanePos(3); - test.commit(clear_repositorycache).parents(merge_remove) - .lanePos(mainPos); - test.commit(resolve_handler).parents(merge_fix).lanePos(4); - test.commit(merge_remove).parents(add_simple, remove_unused) - .lanePos(mainPos); - test.commit(remove_unused).parents(merge_fix).lanePos(1); - test.commit(add_simple).parents(merge_fix).lanePos(mainPos); - test.commit(merge_fix).parents().lanePos(mainPos); - test.noMoreCommits(); + try (PlotWalk pw = new PlotWalk(db)) { + pw.markStart(pw.lookupCommit(merge_fixed_logged_npe.getId())); + + PlotCommitList<PlotLane> pcl = new PlotCommitList<>(); + pcl.source(pw); + pcl.fillTo(Integer.MAX_VALUE); + + CommitListAssert test = new CommitListAssert(pcl); + + // Note: all positions of side branches are rather arbitrary, but + // some + // may not overlap. Testing for the positions yielded by the current + // implementation, which was manually checked to not overlap. + final int mainPos = 0; + test.commit(merge_fixed_logged_npe) + .parents(sort_roots, fix_logged_npe).lanePos(mainPos); + test.commit(fix_logged_npe).parents(merge_changeset_implementation) + .lanePos(1); + test.commit(sort_roots).parents(merge_update_eclipse) + .lanePos(mainPos); + test.commit(merge_update_eclipse) + .parents(add_a_clear, update_eclipse).lanePos(mainPos); + test.commit(add_a_clear).parents(fix_broken).lanePos(mainPos); + test.commit(fix_broken).parents(merge_disable_comment) + .lanePos(mainPos); + test.commit(merge_disable_comment) + .parents(merge_resolve_handler, disable_comment) + .lanePos(mainPos); + test.commit(disable_comment).parents(clone_operation).lanePos(2); + test.commit(merge_resolve_handler) + .parents(clone_operation, resolve_handler).lanePos(mainPos); + test.commit(update_eclipse).parents(add_Maven).lanePos(3); + test.commit(clone_operation).parents(merge_changeset_implementation) + .lanePos(mainPos); + test.commit(merge_changeset_implementation) + .parents(merge_disable_source, changeset_implementation) + .lanePos(mainPos); + test.commit(merge_disable_source) + .parents(update_eclipse_iplog2, disable_source) + .lanePos(mainPos); + test.commit(update_eclipse_iplog2).parents(merge_use_remote) + .lanePos(mainPos); + test.commit(disable_source).parents(merge_use_remote).lanePos(1); + test.commit(merge_use_remote) + .parents(update_eclipse_iplog, use_remote).lanePos(mainPos); + test.commit(changeset_implementation).parents(clear_repositorycache) + .lanePos(2); + test.commit(update_eclipse_iplog).parents(merge_add_Maven) + .lanePos(mainPos); + test.commit(merge_add_Maven).parents(findToolBar_layout, add_Maven) + .lanePos(mainPos); + test.commit(findToolBar_layout).parents(clear_repositorycache) + .lanePos(mainPos); + test.commit(use_remote).parents(clear_repositorycache).lanePos(1); + test.commit(add_Maven).parents(clear_repositorycache).lanePos(3); + test.commit(clear_repositorycache).parents(merge_remove) + .lanePos(mainPos); + test.commit(resolve_handler).parents(merge_fix).lanePos(4); + test.commit(merge_remove).parents(add_simple, remove_unused) + .lanePos(mainPos); + test.commit(remove_unused).parents(merge_fix).lanePos(1); + test.commit(add_simple).parents(merge_fix).lanePos(mainPos); + test.commit(merge_fix).parents().lanePos(mainPos); + test.noMoreCommits(); + } } // test a history where a merge commit has two time the same parent @@ -403,20 +413,21 @@ public class PlotCommitListTest extends RevWalkTestCase { final RevCommit s1 = commit(m2); final RevCommit s2 = commit(s1); - PlotWalk pw = new PlotWalk(db); - pw.markStart(pw.lookupCommit(m3)); - pw.markStart(pw.lookupCommit(s2)); - PlotCommitList<PlotLane> pcl = new PlotCommitList<>(); - pcl.source(pw); - pcl.fillTo(Integer.MAX_VALUE); - - CommitListAssert test = new CommitListAssert(pcl); - test.commit(s2).nrOfPassingLanes(0); - test.commit(s1).nrOfPassingLanes(0); - test.commit(m3).nrOfPassingLanes(1); - test.commit(m2).nrOfPassingLanes(0); - test.commit(m1).nrOfPassingLanes(0); - test.noMoreCommits(); + try (PlotWalk pw = new PlotWalk(db)) { + pw.markStart(pw.lookupCommit(m3)); + pw.markStart(pw.lookupCommit(s2)); + PlotCommitList<PlotLane> pcl = new PlotCommitList<>(); + pcl.source(pw); + pcl.fillTo(Integer.MAX_VALUE); + + CommitListAssert test = new CommitListAssert(pcl); + test.commit(s2).nrOfPassingLanes(0); + test.commit(s1).nrOfPassingLanes(0); + test.commit(m3).nrOfPassingLanes(1); + test.commit(m2).nrOfPassingLanes(0); + test.commit(m1).nrOfPassingLanes(0); + test.noMoreCommits(); + } } /** @@ -465,30 +476,31 @@ public class PlotCommitListTest extends RevWalkTestCase { final RevCommit a4 = commit(a3); final RevCommit a5 = commit(a3, a4); - PlotWalk pw = new PlotWalk(db); - pw.markStart(pw.lookupCommit(b3.getId())); - pw.markStart(pw.lookupCommit(c.getId())); - pw.markStart(pw.lookupCommit(e.getId())); - pw.markStart(pw.lookupCommit(a5.getId())); - - PlotCommitList<PlotLane> pcl = new PlotCommitList<>(); - pcl.source(pw); - pcl.fillTo(Integer.MAX_VALUE); - - // test that the commits b1, b2 and b3 are on the same position - int bPos = pcl.get(9).lane.position; // b1 - assertEquals("b2 is an a different position", bPos, - pcl.get(7).lane.position); - assertEquals("b3 is on a different position", bPos, - pcl.get(4).lane.position); - - // test that nothing blocks the connections between b1, b2 and b3 - assertNotEquals("b lane is blocked by c", bPos, - pcl.get(8).lane.position); - assertNotEquals("b lane is blocked by a2", bPos, - pcl.get(6).lane.position); - assertNotEquals("b lane is blocked by d", bPos, - pcl.get(5).lane.position); + try (PlotWalk pw = new PlotWalk(db)) { + pw.markStart(pw.lookupCommit(b3.getId())); + pw.markStart(pw.lookupCommit(c.getId())); + pw.markStart(pw.lookupCommit(e.getId())); + pw.markStart(pw.lookupCommit(a5.getId())); + + PlotCommitList<PlotLane> pcl = new PlotCommitList<>(); + pcl.source(pw); + pcl.fillTo(Integer.MAX_VALUE); + + // test that the commits b1, b2 and b3 are on the same position + int bPos = pcl.get(9).lane.position; // b1 + assertEquals("b2 is an a different position", bPos, + pcl.get(7).lane.position); + assertEquals("b3 is on a different position", bPos, + pcl.get(4).lane.position); + + // test that nothing blocks the connections between b1, b2 and b3 + assertNotEquals("b lane is blocked by c", bPos, + pcl.get(8).lane.position); + assertNotEquals("b lane is blocked by a2", bPos, + pcl.get(6).lane.position); + assertNotEquals("b lane is blocked by d", bPos, + pcl.get(5).lane.position); + } } /** @@ -517,23 +529,24 @@ public class PlotCommitListTest extends RevWalkTestCase { final RevCommit a4 = commit(a3, b2); final RevCommit b3 = commit(b2); - PlotWalk pw = new PlotWalk(db); - pw.markStart(pw.lookupCommit(a4)); - pw.markStart(pw.lookupCommit(b3)); - PlotCommitList<PlotLane> pcl = new PlotCommitList<>(); - pcl.source(pw); - pcl.fillTo(Integer.MAX_VALUE); - - Set<Integer> positions = asSet(0, 1); - CommitListAssert test = new CommitListAssert(pcl); - int posB = test.commit(b3).lanePos(positions).getLanePos(); - int posA = test.commit(a4).lanePos(positions).getLanePos(); - test.commit(b2).lanePos(posB); - test.commit(a3).lanePos(posA); - test.commit(a2).lanePos(posA); - test.commit(b1).lanePos(posB); - test.commit(a1).lanePos(posA); - test.noMoreCommits(); + try (PlotWalk pw = new PlotWalk(db)) { + pw.markStart(pw.lookupCommit(a4)); + pw.markStart(pw.lookupCommit(b3)); + PlotCommitList<PlotLane> pcl = new PlotCommitList<>(); + pcl.source(pw); + pcl.fillTo(Integer.MAX_VALUE); + + Set<Integer> positions = asSet(0, 1); + CommitListAssert test = new CommitListAssert(pcl); + int posB = test.commit(b3).lanePos(positions).getLanePos(); + int posA = test.commit(a4).lanePos(positions).getLanePos(); + test.commit(b2).lanePos(posB); + test.commit(a3).lanePos(posA); + test.commit(a2).lanePos(posA); + test.commit(b1).lanePos(posB); + test.commit(a1).lanePos(posA); + test.noMoreCommits(); + } } /** @@ -562,25 +575,26 @@ public class PlotCommitListTest extends RevWalkTestCase { final RevCommit b3 = commit(b2); final RevCommit a4 = commit(a3); - PlotWalk pw = new PlotWalk(db); - pw.markStart(pw.lookupCommit(a4)); - pw.markStart(pw.lookupCommit(b3)); - PlotCommitList<PlotLane> pcl = new PlotCommitList<>(); - pcl.source(pw); - pcl.fillTo(Integer.MAX_VALUE); - - Set<Integer> positions = asSet(0, 1); - CommitListAssert test = new CommitListAssert(pcl); - int posA = test.commit(a4).lanePos(positions).getLanePos(); - int posB = test.commit(b3).lanePos(positions).getLanePos(); - test.commit(a3).lanePos(posA); - test.commit(b2).lanePos(posB); - test.commit(a2).lanePos(posA); - // b1 is not repositioned, uses "detour lane" - // (drawn as a double arc in the ascii graph above) - test.commit(b1).lanePos(posB); - test.commit(a1).lanePos(posA); - test.noMoreCommits(); + try (PlotWalk pw = new PlotWalk(db)) { + pw.markStart(pw.lookupCommit(a4)); + pw.markStart(pw.lookupCommit(b3)); + PlotCommitList<PlotLane> pcl = new PlotCommitList<>(); + pcl.source(pw); + pcl.fillTo(Integer.MAX_VALUE); + + Set<Integer> positions = asSet(0, 1); + CommitListAssert test = new CommitListAssert(pcl); + int posA = test.commit(a4).lanePos(positions).getLanePos(); + int posB = test.commit(b3).lanePos(positions).getLanePos(); + test.commit(a3).lanePos(posA); + test.commit(b2).lanePos(posB); + test.commit(a2).lanePos(posA); + // b1 is not repositioned, uses "detour lane" + // (drawn as a double arc in the ascii graph above) + test.commit(b1).lanePos(posB); + test.commit(a1).lanePos(posA); + test.noMoreCommits(); + } } /** @@ -611,24 +625,25 @@ public class PlotCommitListTest extends RevWalkTestCase { final RevCommit a4 = commit(a3, b1); final RevCommit b2 = commit(b1); - PlotWalk pw = new PlotWalk(db); - pw.markStart(pw.lookupCommit(a4)); - pw.markStart(pw.lookupCommit(b2)); - pw.markStart(pw.lookupCommit(c)); - PlotCommitList<PlotLane> pcl = new PlotCommitList<>(); - pcl.source(pw); - pcl.fillTo(Integer.MAX_VALUE); - - Set<Integer> positions = asSet(0, 1, 2); - CommitListAssert test = new CommitListAssert(pcl); - int posB = test.commit(b2).lanePos(positions).getLanePos(); - int posA = test.commit(a4).lanePos(positions).getLanePos(); - test.commit(a3).lanePos(posA); - test.commit(c).lanePos(positions); - test.commit(a2).lanePos(posA); - test.commit(b1).lanePos(posB); // repositioned to go around c - test.commit(a1).lanePos(posA); - test.noMoreCommits(); + try (PlotWalk pw = new PlotWalk(db)) { + pw.markStart(pw.lookupCommit(a4)); + pw.markStart(pw.lookupCommit(b2)); + pw.markStart(pw.lookupCommit(c)); + PlotCommitList<PlotLane> pcl = new PlotCommitList<>(); + pcl.source(pw); + pcl.fillTo(Integer.MAX_VALUE); + + Set<Integer> positions = asSet(0, 1, 2); + CommitListAssert test = new CommitListAssert(pcl); + int posB = test.commit(b2).lanePos(positions).getLanePos(); + int posA = test.commit(a4).lanePos(positions).getLanePos(); + test.commit(a3).lanePos(posA); + test.commit(c).lanePos(positions); + test.commit(a2).lanePos(posA); + test.commit(b1).lanePos(posB); // repositioned to go around c + test.commit(a1).lanePos(posA); + test.noMoreCommits(); + } } /** @@ -651,22 +666,24 @@ public class PlotCommitListTest extends RevWalkTestCase { final RevCommit a3 = commit(a2); final RevCommit b1 = commit(a1); - PlotWalk pw = new PlotWalk(db); - pw.markStart(pw.lookupCommit(a3)); - pw.markStart(pw.lookupCommit(b1)); - PlotCommitList<PlotLane> pcl = new PlotCommitList<>(); - pcl.source(pw); - pcl.fillTo(2); // don't process a1 - - Set<Integer> positions = asSet(0, 1); - CommitListAssert test = new CommitListAssert(pcl); - PlotLane laneB = test.commit(b1).lanePos(positions).current.getLane(); - int posA = test.commit(a3).lanePos(positions).getLanePos(); - test.commit(a2).lanePos(posA); - assertArrayEquals( - "Although the parent of b1, a1, is not processed yet, the b lane should still be drawn", - new PlotLane[] { laneB }, test.current.passingLanes); - test.noMoreCommits(); + try (PlotWalk pw = new PlotWalk(db)) { + pw.markStart(pw.lookupCommit(a3)); + pw.markStart(pw.lookupCommit(b1)); + PlotCommitList<PlotLane> pcl = new PlotCommitList<>(); + pcl.source(pw); + pcl.fillTo(2); // don't process a1 + + Set<Integer> positions = asSet(0, 1); + CommitListAssert test = new CommitListAssert(pcl); + PlotLane laneB = test.commit(b1).lanePos(positions).current + .getLane(); + int posA = test.commit(a3).lanePos(positions).getLanePos(); + test.commit(a2).lanePos(posA); + assertArrayEquals( + "Although the parent of b1, a1, is not processed yet, the b lane should still be drawn", + new PlotLane[] { laneB }, test.current.passingLanes); + test.noMoreCommits(); + } } @Test @@ -674,17 +691,18 @@ public class PlotCommitListTest extends RevWalkTestCase { final RevCommit a = commit(); final RevCommit b = commit(); - PlotWalk pw = new PlotWalk(db); - pw.markStart(pw.lookupCommit(a)); - pw.markStart(pw.lookupCommit(b)); - PlotCommitList<PlotLane> pcl = new PlotCommitList<>(); - pcl.source(pw); - pcl.fillTo(Integer.MAX_VALUE); - - CommitListAssert test = new CommitListAssert(pcl); - test.commit(b).lanePos(0); - test.commit(a).lanePos(0); - test.noMoreCommits(); + try (PlotWalk pw = new PlotWalk(db)) { + pw.markStart(pw.lookupCommit(a)); + pw.markStart(pw.lookupCommit(b)); + PlotCommitList<PlotLane> pcl = new PlotCommitList<>(); + pcl.source(pw); + pcl.fillTo(Integer.MAX_VALUE); + + CommitListAssert test = new CommitListAssert(pcl); + test.commit(b).lanePos(0); + test.commit(a).lanePos(0); + test.noMoreCommits(); + } } @Test @@ -693,17 +711,18 @@ public class PlotCommitListTest extends RevWalkTestCase { final RevCommit b1 = commit(); final RevCommit b2 = commit(b1); - PlotWalk pw = new PlotWalk(db); - pw.markStart(pw.lookupCommit(a)); - pw.markStart(pw.lookupCommit(b2)); - PlotCommitList<PlotLane> pcl = new PlotCommitList<>(); - pcl.source(pw); - pcl.fillTo(Integer.MAX_VALUE); - - CommitListAssert test = new CommitListAssert(pcl); - test.commit(b2).lanePos(0); - test.commit(b1).lanePos(0); - test.commit(a).lanePos(0); - test.noMoreCommits(); + try (PlotWalk pw = new PlotWalk(db)) { + pw.markStart(pw.lookupCommit(a)); + pw.markStart(pw.lookupCommit(b2)); + PlotCommitList<PlotLane> pcl = new PlotCommitList<>(); + pcl.source(pw); + pcl.fillTo(Integer.MAX_VALUE); + + CommitListAssert test = new CommitListAssert(pcl); + test.commit(b2).lanePos(0); + test.commit(b1).lanePos(0); + test.commit(a).lanePos(0); + test.noMoreCommits(); + } } } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/BitmapCalculatorTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/BitmapCalculatorTest.java deleted file mode 100644 index c5d4d4238d..0000000000 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/BitmapCalculatorTest.java +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Copyright (C) 2019, Google LLC. - * 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.revwalk; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import org.eclipse.jgit.internal.storage.file.FileRepository; -import org.eclipse.jgit.internal.storage.file.GC; -import org.eclipse.jgit.junit.LocalDiskRepositoryTestCase; -import org.eclipse.jgit.junit.TestRepository; -import org.eclipse.jgit.lib.BitmapIndex.BitmapBuilder; -import org.eclipse.jgit.lib.NullProgressMonitor; -import org.eclipse.jgit.lib.ProgressMonitor; -import org.junit.Before; -import org.junit.Test; - -public class BitmapCalculatorTest extends LocalDiskRepositoryTestCase { - TestRepository<FileRepository> repo; - - /** {@inheritDoc} */ - @Override - @Before - public void setUp() throws Exception { - super.setUp(); - FileRepository db = createWorkRepository(); - repo = new TestRepository<>(db); - } - - @Test - public void addOnlyCommits() throws Exception { - RevBlob abBlob = repo.blob("a_b_content"); - RevCommit root = repo.commit().add("a/b", abBlob).create(); - repo.update("refs/heads/master", root); - - // GC creates bitmap index with ALL objects - GC gc = new GC(repo.getRepository()); - gc.setAuto(false); - gc.gc(); - - // These objects are not in the bitmap index. - RevBlob acBlob = repo.blob("a_c_content"); - RevCommit head = repo.commit().parent(root).add("a/c", acBlob).create(); - repo.update("refs/heads/master", head); - - BitmapCalculator bitmapWalker = new BitmapCalculator(repo.getRevWalk()); - BitmapBuilder bitmap = bitmapWalker - .getBitmap(head, NullProgressMonitor.INSTANCE); - - assertTrue(bitmap.contains(root.getId())); - assertTrue(bitmap.contains(root.getTree().getId())); - assertTrue(bitmap.contains(abBlob.getId())); - - // BitmapCalculator added only the commit, no other objects. - assertTrue(bitmap.contains(head.getId())); - assertFalse(bitmap.contains(head.getTree().getId())); - assertFalse(bitmap.contains(acBlob.getId())); - } - - @Test - public void walkUntilBitmap() throws Exception { - RevCommit root = repo.commit().create(); - repo.update("refs/heads/master", root); - - // GC creates bitmap index with ALL objects - GC gc = new GC(repo.getRepository()); - gc.setAuto(false); - gc.gc(); - - // These objects are not in the bitmap index. - RevCommit commit1 = repo.commit(root); - RevCommit commit2 = repo.commit(commit1); - repo.update("refs/heads/master", commit2); - - CounterProgressMonitor monitor = new CounterProgressMonitor(); - BitmapCalculator bitmapWalker = new BitmapCalculator(repo.getRevWalk()); - BitmapBuilder bitmap = bitmapWalker.getBitmap(commit2, monitor); - - assertTrue(bitmap.contains(root)); - assertTrue(bitmap.contains(commit1)); - assertTrue(bitmap.contains(commit2)); - assertEquals(2, monitor.getUpdates()); - } - - @Test - public void noNeedToWalk() throws Exception { - RevCommit root = repo.commit().create(); - RevCommit commit1 = repo.commit(root); - RevCommit commit2 = repo.commit(commit1); - repo.update("refs/heads/master", commit2); - - // GC creates bitmap index with ALL objects - GC gc = new GC(repo.getRepository()); - gc.setAuto(false); - gc.gc(); - - CounterProgressMonitor monitor = new CounterProgressMonitor(); - BitmapCalculator bitmapWalker = new BitmapCalculator(repo.getRevWalk()); - BitmapBuilder bitmap = bitmapWalker.getBitmap(commit2, monitor); - - assertTrue(bitmap.contains(root)); - assertTrue(bitmap.contains(commit1)); - assertTrue(bitmap.contains(commit2)); - assertEquals(0, monitor.getUpdates()); - } - - private static class CounterProgressMonitor implements ProgressMonitor { - - private int counter; - - @Override - public void start(int totalTasks) { - // Nothing to do in tests - } - - @Override - public void beginTask(String title, int totalWork) { - // Nothing to to in tests - } - - @Override - public void update(int completed) { - counter += 1; - } - - @Override - public void endTask() { - // Nothing to do in tests - } - - @Override - public boolean isCancelled() { - return false; - } - - int getUpdates() { - return counter; - } - } -}
\ No newline at end of file diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/FirstParentRevWalkTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/FirstParentRevWalkTest.java index 1fc7a55457..d46f48bcd9 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/FirstParentRevWalkTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/FirstParentRevWalkTest.java @@ -49,6 +49,7 @@ import static org.junit.Assert.assertNull; import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.revwalk.filter.MessageRevFilter; import org.eclipse.jgit.revwalk.filter.RevFilter; +import org.eclipse.jgit.treewalk.filter.PathFilterGroup; import org.junit.Test; public class FirstParentRevWalkTest extends RevWalkTestCase { @@ -425,4 +426,39 @@ public class FirstParentRevWalkTest extends RevWalkTestCase { markStart(a); assertNull(rw.next()); } + + @Test + public void testWithTopoSortAndTreeFilter() throws Exception { + RevCommit a = commit(); + RevCommit b = commit(tree(file("0", blob("b"))), a); + RevCommit c = commit(tree(file("0", blob("c"))), b, a); + RevCommit d = commit(tree(file("0", blob("d"))), c); + + rw.reset(); + rw.setFirstParent(true); + rw.sort(RevSort.TOPO, true); + rw.setTreeFilter(PathFilterGroup.createFromStrings("0")); + markStart(d); + assertCommit(d, rw.next()); + assertCommit(c, rw.next()); + assertCommit(b, rw.next()); + assertNull(rw.next()); + } + + @Test + public void testWithTopoSortAndTreeFilter2() throws Exception { + RevCommit a = commit(); + RevCommit b = commit(tree(file("0", blob("b"))), a); + RevCommit c = commit(tree(file("0", blob("c"))), a, b); + RevCommit d = commit(tree(file("0", blob("d"))), c); + + rw.reset(); + rw.setFirstParent(true); + rw.sort(RevSort.TOPO, true); + rw.setTreeFilter(PathFilterGroup.createFromStrings("0")); + markStart(d); + assertCommit(d, rw.next()); + assertCommit(c, rw.next()); + assertNull(rw.next()); + } } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/ReachabilityCheckerTestCase.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/ReachabilityCheckerTestCase.java index dd73e35727..092033449b 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/ReachabilityCheckerTestCase.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/ReachabilityCheckerTestCase.java @@ -47,6 +47,7 @@ import static org.junit.Assert.assertTrue; import java.util.Arrays; import java.util.Optional; +import java.util.stream.Stream; import org.eclipse.jgit.internal.storage.file.FileRepository; import org.eclipse.jgit.junit.LocalDiskRepositoryTestCase; @@ -83,11 +84,11 @@ public abstract class ReachabilityCheckerTestCase ReachabilityChecker checker = getChecker(repo); assertReachable("reachable from one tip", - checker.areAllReachable(Arrays.asList(a), Arrays.asList(c2))); + checker.areAllReachable(Arrays.asList(a), Stream.of(c2))); assertReachable("reachable from another tip", - checker.areAllReachable(Arrays.asList(a), Arrays.asList(b2))); + checker.areAllReachable(Arrays.asList(a), Stream.of(b2))); assertReachable("reachable from itself", - checker.areAllReachable(Arrays.asList(a), Arrays.asList(b2))); + checker.areAllReachable(Arrays.asList(a), Stream.of(b2))); } @Test @@ -104,13 +105,13 @@ public abstract class ReachabilityCheckerTestCase assertReachable("reachable through one branch", checker.areAllReachable(Arrays.asList(b1), - Arrays.asList(merge))); + Stream.of(merge))); assertReachable("reachable through another branch", checker.areAllReachable(Arrays.asList(c1), - Arrays.asList(merge))); + Stream.of(merge))); assertReachable("reachable, before the branching", checker.areAllReachable(Arrays.asList(a), - Arrays.asList(merge))); + Stream.of(merge))); } @Test @@ -123,7 +124,7 @@ public abstract class ReachabilityCheckerTestCase ReachabilityChecker checker = getChecker(repo); assertUnreachable("unreachable from the future", - checker.areAllReachable(Arrays.asList(b2), Arrays.asList(b1))); + checker.areAllReachable(Arrays.asList(b2), Stream.of(b1))); } @Test @@ -137,7 +138,7 @@ public abstract class ReachabilityCheckerTestCase ReachabilityChecker checker = getChecker(repo); assertUnreachable("unreachable from different branch", - checker.areAllReachable(Arrays.asList(c1), Arrays.asList(b2))); + checker.areAllReachable(Arrays.asList(c1), Stream.of(b2))); } @Test @@ -152,7 +153,7 @@ public abstract class ReachabilityCheckerTestCase ReachabilityChecker checker = getChecker(repo); assertReachable("reachable with long chain in the middle", checker - .areAllReachable(Arrays.asList(root), Arrays.asList(head))); + .areAllReachable(Arrays.asList(root), Stream.of(head))); } private static void assertReachable(String msg, @@ -164,5 +165,4 @@ public abstract class ReachabilityCheckerTestCase Optional<RevCommit> result) { assertTrue(msg, result.isPresent()); } - } 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 b814984935..d6b63ab236 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 @@ -107,18 +107,18 @@ public class RevCommitParseTest extends RepositoryTestCase { body.append("\n"); - final RevWalk rw = new RevWalk(db); final RevCommit c; c = new RevCommit(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67")); assertNull(c.getTree()); assertNull(c.parents); - c.parseCanonical(rw, body.toString().getBytes(UTF_8)); - assertNotNull(c.getTree()); - assertEquals(treeId, c.getTree().getId()); - assertSame(rw.lookupTree(treeId), c.getTree()); - + try (RevWalk rw = new RevWalk(db)) { + c.parseCanonical(rw, body.toString().getBytes(UTF_8)); + assertNotNull(c.getTree()); + assertEquals(treeId, c.getTree().getId()); + assertSame(rw.lookupTree(treeId), c.getTree()); + } assertNotNull(c.parents); assertEquals(0, c.parents.length); assertEquals("", c.getFullMessage()); @@ -148,8 +148,10 @@ public class RevCommitParseTest extends RepositoryTestCase { final RevCommit c; c = new RevCommit(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67")); - c.parseCanonical(new RevWalk(db), b.toString().getBytes(UTF_8)); - return c; + try (RevWalk rw = new RevWalk(db)) { + c.parseCanonical(rw, b.toString().getBytes(UTF_8)); + return c; + } } @Test @@ -161,8 +163,9 @@ public class RevCommitParseTest extends RepositoryTestCase { final RevCommit c; c = new RevCommit(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67")); - c.parseCanonical(new RevWalk(db), b.toString().getBytes(UTF_8)); - + try (RevWalk rw = new RevWalk(db)) { + c.parseCanonical(rw, b.toString().getBytes(UTF_8)); + } assertEquals("", c.getFullMessage()); assertEquals("", c.getShortMessage()); } @@ -176,8 +179,9 @@ public class RevCommitParseTest extends RepositoryTestCase { final RevCommit c; c = new RevCommit(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67")); - c.parseCanonical(new RevWalk(db), b.toString().getBytes(UTF_8)); - + try (RevWalk rw = new RevWalk(db)) { + c.parseCanonical(rw, b.toString().getBytes(UTF_8)); + } assertEquals(new PersonIdent("", "a_u_thor@example.com", 1218123387000l, 7), c.getAuthorIdent()); assertEquals(new PersonIdent("", "", 1218123390000l, -5), c.getCommitterIdent()); } @@ -194,8 +198,9 @@ public class RevCommitParseTest extends RepositoryTestCase { b.write("\u304d\u308c\u3044\n".getBytes(UTF_8)); final RevCommit c; c = new RevCommit(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67")); // bogus id - c.parseCanonical(new RevWalk(db), b.toByteArray()); - + try (RevWalk rw = new RevWalk(db)) { + c.parseCanonical(rw, b.toByteArray()); + } assertSame(UTF_8, c.getEncoding()); assertEquals("F\u00f6r fattare", c.getAuthorIdent().getName()); assertEquals("Sm\u00f6rg\u00e5sbord", c.getShortMessage()); @@ -214,8 +219,9 @@ public class RevCommitParseTest extends RepositoryTestCase { b.write("\u304d\u308c\u3044\n".getBytes(UTF_8)); final RevCommit c; c = new RevCommit(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67")); // bogus id - c.parseCanonical(new RevWalk(db), b.toByteArray()); - + try (RevWalk rw = new RevWalk(db)) { + c.parseCanonical(rw, b.toByteArray()); + } assertSame(UTF_8, c.getEncoding()); assertEquals("F\u00f6r fattare", c.getAuthorIdent().getName()); assertEquals("Sm\u00f6rg\u00e5sbord", c.getShortMessage()); @@ -240,7 +246,9 @@ public class RevCommitParseTest extends RepositoryTestCase { b.write("Hi\n".getBytes("EUC-JP")); final RevCommit c; c = new RevCommit(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67")); // bogus id - c.parseCanonical(new RevWalk(db), b.toByteArray()); + try (RevWalk rw = new RevWalk(db)) { + c.parseCanonical(rw, b.toByteArray()); + } assertEquals("EUC-JP", c.getEncoding().name()); assertEquals("F\u00f6r fattare", c.getAuthorIdent().getName()); @@ -270,7 +278,9 @@ public class RevCommitParseTest extends RepositoryTestCase { b.write("Hi\n".getBytes(UTF_8)); final RevCommit c; c = new RevCommit(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67")); // bogus id - c.parseCanonical(new RevWalk(db), b.toByteArray()); + try (RevWalk rw = new RevWalk(db)) { + c.parseCanonical(rw, b.toByteArray()); + } assertEquals("EUC-JP", c.getEncoding().name()); assertEquals("F\u00f6r fattare", c.getAuthorIdent().getName()); @@ -301,7 +311,9 @@ public class RevCommitParseTest extends RepositoryTestCase { b.write("Hi\n".getBytes(UTF_8)); final RevCommit c; c = new RevCommit(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67")); // bogus id - c.parseCanonical(new RevWalk(db), b.toByteArray()); + try (RevWalk rw = new RevWalk(db)) { + c.parseCanonical(rw, b.toByteArray()); + } assertEquals("ISO-8859-1", c.getEncoding().name()); assertEquals("F\u00f6r fattare", c.getAuthorIdent().getName()); @@ -323,7 +335,9 @@ public class RevCommitParseTest extends RepositoryTestCase { RevCommit c = new RevCommit( id("9473095c4cb2f12aefe1db8a355fe3fafba42f67")); - c.parseCanonical(new RevWalk(db), b.toByteArray()); + try (RevWalk rw = new RevWalk(db)) { + c.parseCanonical(rw, b.toByteArray()); + } assertEquals("'utf8'", c.getEncodingName()); assertEquals("Sm\u00f6rg\u00e5sbord\n", c.getFullMessage()); @@ -347,7 +361,9 @@ public class RevCommitParseTest extends RepositoryTestCase { RevCommit c = new RevCommit( id("9473095c4cb2f12aefe1db8a355fe3fafba42f67")); - c.parseCanonical(new RevWalk(db), b.toByteArray()); + try (RevWalk rw = new RevWalk(db)) { + c.parseCanonical(rw, b.toByteArray()); + } assertEquals("utf-8logoutputencoding=gbk", c.getEncodingName()); assertEquals("message\n", c.getFullMessage()); assertEquals("message", c.getShortMessage()); @@ -374,7 +390,9 @@ public class RevCommitParseTest extends RepositoryTestCase { RevCommit c = new RevCommit( id("9473095c4cb2f12aefe1db8a355fe3fafba42f67")); - c.parseCanonical(new RevWalk(db), b.toByteArray()); + try (RevWalk rw = new RevWalk(db)) { + c.parseCanonical(rw, b.toByteArray()); + } assertEquals("it_IT.UTF8", c.getEncodingName()); assertEquals("message\n", c.getFullMessage()); assertEquals("message", c.getShortMessage()); @@ -507,7 +525,9 @@ public class RevCommitParseTest extends RepositoryTestCase { final RevCommit c; c = new RevCommit(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67")); - c.parseCanonical(new RevWalk(db), commit.getBytes(UTF_8)); + try (RevWalk rw = new RevWalk(db)) { + c.parseCanonical(rw, commit.getBytes(UTF_8)); + } String gpgSig = new String(c.getRawGpgSignature(), UTF_8); assertTrue(gpgSig.startsWith("-----BEGIN")); assertTrue(gpgSig.endsWith("END PGP SIGNATURE-----")); 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 1b45473066..bbc559b2db 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 @@ -91,17 +91,18 @@ public class RevTagParseTest extends RepositoryTestCase { b.append("tagger A U. Thor <a_u_thor@example.com> 1218123387 +0700\n"); b.append("\n"); - final RevWalk rw = new RevWalk(db); final RevTag c; c = new RevTag(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67")); assertNull(c.getObject()); assertNull(c.getTagName()); - c.parseCanonical(rw, b.toString().getBytes(UTF_8)); - assertNotNull(c.getObject()); - assertEquals(id, c.getObject().getId()); - assertSame(rw.lookupAny(id, typeCode), c.getObject()); + try (RevWalk rw = new RevWalk(db)) { + c.parseCanonical(rw, b.toString().getBytes(UTF_8)); + assertNotNull(c.getObject()); + assertEquals(id, c.getObject().getId()); + assertSame(rw.lookupAny(id, typeCode), c.getObject()); + } } @Test @@ -134,18 +135,18 @@ public class RevTagParseTest extends RepositoryTestCase { body.append("\n"); - final RevWalk rw = new RevWalk(db); final RevTag c; c = new RevTag(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67")); assertNull(c.getObject()); assertNull(c.getTagName()); - c.parseCanonical(rw, body.toString().getBytes(UTF_8)); - assertNotNull(c.getObject()); - assertEquals(treeId, c.getObject().getId()); - assertSame(rw.lookupTree(treeId), c.getObject()); - + try (RevWalk rw = new RevWalk(db)) { + c.parseCanonical(rw, body.toString().getBytes(UTF_8)); + assertNotNull(c.getObject()); + assertEquals(treeId, c.getObject().getId()); + assertSame(rw.lookupTree(treeId), c.getObject()); + } assertNotNull(c.getTagName()); assertEquals(name, c.getTagName()); assertEquals("", c.getFullMessage()); @@ -182,17 +183,18 @@ public class RevTagParseTest extends RepositoryTestCase { body.append("\n"); body.append(message); - final RevWalk rw = new RevWalk(db); final RevTag c; c = new RevTag(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67")); assertNull(c.getObject()); assertNull(c.getTagName()); - c.parseCanonical(rw, body.toString().getBytes(UTF_8)); - assertNotNull(c.getObject()); - assertEquals(treeId, c.getObject().getId()); - assertSame(rw.lookupTree(treeId), c.getObject()); + try (RevWalk rw = new RevWalk(db)) { + c.parseCanonical(rw, body.toString().getBytes(UTF_8)); + assertNotNull(c.getObject()); + assertEquals(treeId, c.getObject().getId()); + assertSame(rw.lookupTree(treeId), c.getObject()); + } assertNotNull(c.getTagName()); assertEquals(name, c.getTagName()); @@ -213,7 +215,9 @@ public class RevTagParseTest extends RepositoryTestCase { final RevTag c; c = new RevTag(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67")); - c.parseCanonical(new RevWalk(db), b.toString().getBytes(UTF_8)); + try (RevWalk rw = new RevWalk(db)) { + c.parseCanonical(rw, b.toString().getBytes(UTF_8)); + } return c; } @@ -234,7 +238,9 @@ public class RevTagParseTest extends RepositoryTestCase { b.write("\u304d\u308c\u3044\n".getBytes(UTF_8)); final RevTag c; c = new RevTag(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67")); - c.parseCanonical(new RevWalk(db), b.toByteArray()); + try (RevWalk rw = new RevWalk(db)) { + c.parseCanonical(rw, b.toByteArray()); + } assertEquals("F\u00f6r fattare", c.getTaggerIdent().getName()); assertEquals("Sm\u00f6rg\u00e5sbord", c.getShortMessage()); @@ -257,7 +263,9 @@ public class RevTagParseTest extends RepositoryTestCase { b.write("\u304d\u308c\u3044\n".getBytes(UTF_8)); final RevTag c; c = new RevTag(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67")); - c.parseCanonical(new RevWalk(db), b.toByteArray()); + try (RevWalk rw = new RevWalk(db)) { + c.parseCanonical(rw, b.toByteArray()); + } assertEquals("F\u00f6r fattare", c.getTaggerIdent().getName()); assertEquals("Sm\u00f6rg\u00e5sbord", c.getShortMessage()); @@ -287,7 +295,9 @@ public class RevTagParseTest extends RepositoryTestCase { b.write("Hi\n".getBytes("EUC-JP")); final RevTag c; c = new RevTag(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67")); - c.parseCanonical(new RevWalk(db), b.toByteArray()); + try (RevWalk rw = new RevWalk(db)) { + c.parseCanonical(rw, b.toByteArray()); + } assertEquals("F\u00f6r fattare", c.getTaggerIdent().getName()); assertEquals("\u304d\u308c\u3044", c.getShortMessage()); @@ -320,7 +330,9 @@ public class RevTagParseTest extends RepositoryTestCase { b.write("Hi\n".getBytes(UTF_8)); final RevTag c; c = new RevTag(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67")); - c.parseCanonical(new RevWalk(db), b.toByteArray()); + try (RevWalk rw = new RevWalk(db)) { + c.parseCanonical(rw, b.toByteArray()); + } assertEquals("F\u00f6r fattare", c.getTaggerIdent().getName()); assertEquals("\u304d\u308c\u3044", c.getShortMessage()); @@ -355,7 +367,9 @@ public class RevTagParseTest extends RepositoryTestCase { b.write("Hi\n".getBytes(UTF_8)); final RevTag c; c = new RevTag(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67")); - c.parseCanonical(new RevWalk(db), b.toByteArray()); + try (RevWalk rw = new RevWalk(db)) { + c.parseCanonical(rw, b.toByteArray()); + } assertEquals("F\u00f6r fattare", c.getTaggerIdent().getName()); assertEquals("\u304d\u308c\u3044", c.getShortMessage()); @@ -374,7 +388,9 @@ public class RevTagParseTest extends RepositoryTestCase { b.write("message\n".getBytes(UTF_8)); RevTag t = new RevTag(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67")); - t.parseCanonical(new RevWalk(db), b.toByteArray()); + try (RevWalk rw = new RevWalk(db)) { + t.parseCanonical(rw, b.toByteArray()); + } assertEquals("t", t.getTaggerIdent().getName()); assertEquals("message", t.getShortMessage()); @@ -393,7 +409,9 @@ public class RevTagParseTest extends RepositoryTestCase { b.write("message\n".getBytes(UTF_8)); RevTag t = new RevTag(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67")); - t.parseCanonical(new RevWalk(db), b.toByteArray()); + try (RevWalk rw = new RevWalk(db)) { + t.parseCanonical(rw, b.toByteArray()); + } assertEquals("t", t.getTaggerIdent().getName()); assertEquals("message", t.getShortMessage()); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/TreeRevFilterTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/TreeRevFilterTest.java index 9548992a2b..a345459b3b 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/TreeRevFilterTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/TreeRevFilterTest.java @@ -46,25 +46,15 @@ package org.eclipse.jgit.revwalk; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; -import java.util.Collections; - import org.eclipse.jgit.revwalk.filter.OrRevFilter; import org.eclipse.jgit.revwalk.filter.RevFilter; import org.eclipse.jgit.revwalk.filter.SkipRevFilter; -import org.eclipse.jgit.treewalk.filter.AndTreeFilter; -import org.eclipse.jgit.treewalk.filter.PathFilterGroup; import org.eclipse.jgit.treewalk.filter.TreeFilter; import org.junit.Test; public class TreeRevFilterTest extends RevWalkTestCase { - private RevFilter treeRevFilter(String path) { - return new TreeRevFilter(rw, treeFilter(path)); - } - - private static TreeFilter treeFilter(String path) { - return AndTreeFilter.create( - PathFilterGroup.createFromStrings(Collections.singleton(path)), - TreeFilter.ANY_DIFF); + private RevFilter treeRevFilter() { + return new TreeRevFilter(rw, TreeFilter.ANY_DIFF); } @Test @@ -73,7 +63,7 @@ public class TreeRevFilterTest extends RevWalkTestCase { RevCommit a = commit(tree(file("d/f", blob("a")))); RevCommit b = commit(tree(file("d/f", blob("a"))), a); RevCommit c = commit(tree(file("d/f", blob("b"))), b); - rw.setRevFilter(treeRevFilter("d/f")); + rw.setRevFilter(treeRevFilter()); markStart(c); assertCommit(c, rw.next()); @@ -91,7 +81,7 @@ public class TreeRevFilterTest extends RevWalkTestCase { RevCommit b = commit(tree(file("d/f", blob("a"))), a); RevCommit c = commit(tree(file("d/f", blob("b"))), b); RevCommit d = commit(tree(file("d/f", blob("b"))), c); - rw.setRevFilter(treeRevFilter("d/f")); + rw.setRevFilter(treeRevFilter()); markStart(d); // d was skipped @@ -111,7 +101,7 @@ public class TreeRevFilterTest extends RevWalkTestCase { RevCommit b = commit(tree(file("d/f", blob("a"))), a); RevCommit c = commit(tree(file("d/f", blob("b"))), b); RevCommit d = commit(tree(file("d/f", blob("b"))), c); - rw.setRevFilter(treeRevFilter("d")); + rw.setRevFilter(treeRevFilter()); markStart(d); // d was skipped @@ -136,7 +126,7 @@ public class TreeRevFilterTest extends RevWalkTestCase { RevCommit g = commit(tree(file("d/f", blob("b"))), f); RevCommit h = commit(tree(file("d/f", blob("b"))), g); RevCommit i = commit(tree(file("d/f", blob("c"))), h); - rw.setRevFilter(treeRevFilter("d/f")); + rw.setRevFilter(treeRevFilter()); markStart(i); assertCommit(i, rw.next()); @@ -156,7 +146,7 @@ public class TreeRevFilterTest extends RevWalkTestCase { @Test public void testPathFilterOrOtherFilter() throws Exception { - RevFilter pathFilter = treeRevFilter("d/f"); + RevFilter pathFilter = treeRevFilter(); RevFilter skipFilter = SkipRevFilter.create(1); RevFilter orFilter = OrRevFilter.create(skipFilter, pathFilter); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/submodule/SubmoduleAddTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/submodule/SubmoduleAddTest.java index 1ff64a2e28..80e9e6b14b 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/submodule/SubmoduleAddTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/submodule/SubmoduleAddTest.java @@ -135,20 +135,20 @@ public class SubmoduleAddTest extends RepositoryTestCase { subCommit = repo.resolve(Constants.HEAD); } - SubmoduleWalk generator = SubmoduleWalk.forIndex(db); - generator.loadModulesConfig(); - assertTrue(generator.next()); - assertEquals(path, generator.getModuleName()); - assertEquals(path, generator.getPath()); - assertEquals(commit, generator.getObjectId()); - assertEquals(uri, generator.getModulesUrl()); - assertEquals(path, generator.getModulesPath()); - assertEquals(uri, generator.getConfigUrl()); - try (Repository subModRepo = generator.getRepository()) { - assertNotNull(subModRepo); - assertEquals(subCommit, commit); + try (SubmoduleWalk generator = SubmoduleWalk.forIndex(db)) { + generator.loadModulesConfig(); + assertTrue(generator.next()); + assertEquals(path, generator.getModuleName()); + assertEquals(path, generator.getPath()); + assertEquals(commit, generator.getObjectId()); + assertEquals(uri, generator.getModulesUrl()); + assertEquals(path, generator.getModulesPath()); + assertEquals(uri, generator.getConfigUrl()); + try (Repository subModRepo = generator.getRepository()) { + assertNotNull(subModRepo); + assertEquals(subCommit, commit); + } } - Status status = Git.wrap(db).status().call(); assertTrue(status.getAdded().contains(Constants.DOT_GIT_MODULES)); assertTrue(status.getAdded().contains(path)); @@ -175,20 +175,20 @@ public class SubmoduleAddTest extends RepositoryTestCase { subCommit = repo.resolve(Constants.HEAD); } - SubmoduleWalk generator = SubmoduleWalk.forIndex(db); - generator.loadModulesConfig(); - assertTrue(generator.next()); - assertEquals(name, generator.getModuleName()); - assertEquals(path, generator.getPath()); - assertEquals(commit, generator.getObjectId()); - assertEquals(uri, generator.getModulesUrl()); - assertEquals(path, generator.getModulesPath()); - assertEquals(uri, generator.getConfigUrl()); - try (Repository subModRepo = generator.getRepository()) { - assertNotNull(subModRepo); - assertEquals(subCommit, commit); + try (SubmoduleWalk generator = SubmoduleWalk.forIndex(db)) { + generator.loadModulesConfig(); + assertTrue(generator.next()); + assertEquals(name, generator.getModuleName()); + assertEquals(path, generator.getPath()); + assertEquals(commit, generator.getObjectId()); + assertEquals(uri, generator.getModulesUrl()); + assertEquals(path, generator.getModulesPath()); + assertEquals(uri, generator.getConfigUrl()); + try (Repository subModRepo = generator.getRepository()) { + assertNotNull(subModRepo); + assertEquals(subCommit, commit); + } } - Status status = Git.wrap(db).status().call(); assertTrue(status.getAdded().contains(Constants.DOT_GIT_MODULES)); assertTrue(status.getAdded().contains(path)); @@ -269,24 +269,25 @@ public class SubmoduleAddTest extends RepositoryTestCase { assertNotNull(repo); addRepoToClose(repo); - SubmoduleWalk generator = SubmoduleWalk.forIndex(db); - assertTrue(generator.next()); - assertEquals(path, generator.getPath()); - assertEquals(commit, generator.getObjectId()); - assertEquals(uri, generator.getModulesUrl()); - assertEquals(path, generator.getModulesPath()); - String fullUri = db.getDirectory().getAbsolutePath(); - if (File.separatorChar == '\\') { - fullUri = fullUri.replace('\\', '/'); - } - assertEquals(fullUri, generator.getConfigUrl()); - try (Repository subModRepo = generator.getRepository()) { - assertNotNull(subModRepo); - assertEquals(fullUri, - subModRepo.getConfig().getString( - ConfigConstants.CONFIG_REMOTE_SECTION, - Constants.DEFAULT_REMOTE_NAME, - ConfigConstants.CONFIG_KEY_URL)); + try (SubmoduleWalk generator = SubmoduleWalk.forIndex(db)) { + assertTrue(generator.next()); + assertEquals(path, generator.getPath()); + assertEquals(commit, generator.getObjectId()); + assertEquals(uri, generator.getModulesUrl()); + assertEquals(path, generator.getModulesPath()); + String fullUri = db.getDirectory().getAbsolutePath(); + if (File.separatorChar == '\\') { + fullUri = fullUri.replace('\\', '/'); + } + assertEquals(fullUri, generator.getConfigUrl()); + try (Repository subModRepo = generator.getRepository()) { + assertNotNull(subModRepo); + assertEquals(fullUri, + subModRepo.getConfig().getString( + ConfigConstants.CONFIG_REMOTE_SECTION, + Constants.DEFAULT_REMOTE_NAME, + ConfigConstants.CONFIG_KEY_URL)); + } } assertEquals(commit, repo.resolve(Constants.HEAD)); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/submodule/SubmoduleDeinitTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/submodule/SubmoduleDeinitTest.java index 815ce9b350..bb0085106d 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/submodule/SubmoduleDeinitTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/submodule/SubmoduleDeinitTest.java @@ -107,7 +107,6 @@ public class SubmoduleDeinitTest extends RepositoryTestCase { assertEquals(1, updated.size()); File submoduleDir = assertSubmoduleIsInitialized(); - SubmoduleWalk generator; write(new File(submoduleDir, "untracked"), "untracked"); @@ -115,8 +114,9 @@ public class SubmoduleDeinitTest extends RepositoryTestCase { assertEquals(path, result.getPath()); assertEquals(SubmoduleDeinitCommand.SubmoduleDeinitStatus.DIRTY, result.getStatus()); - generator = SubmoduleWalk.forIndex(db); - assertTrue(generator.next()); + try (SubmoduleWalk generator = SubmoduleWalk.forIndex(db)) { + assertTrue(generator.next()); + } assertTrue(submoduleDir.isDirectory()); assertNotEquals(0, submoduleDir.list().length); } @@ -132,33 +132,36 @@ public class SubmoduleDeinitTest extends RepositoryTestCase { assertEquals(1, updated.size()); File submoduleDir = assertSubmoduleIsInitialized(); - SubmoduleWalk generator = SubmoduleWalk.forIndex(db); - generator.next(); - - //want to create a commit inside the repo... - try (Repository submoduleLocalRepo = generator.getRepository()) { - JGitTestUtil.writeTrashFile(submoduleLocalRepo, "file.txt", - "new data"); - Git.wrap(submoduleLocalRepo).commit().setAll(true) - .setMessage("local commit").call(); + try (SubmoduleWalk generator = SubmoduleWalk.forIndex(db)) { + generator.next(); + + // want to create a commit inside the repo... + try (Repository submoduleLocalRepo = generator.getRepository()) { + JGitTestUtil.writeTrashFile(submoduleLocalRepo, "file.txt", + "new data"); + Git.wrap(submoduleLocalRepo).commit().setAll(true) + .setMessage("local commit").call(); + } } SubmoduleDeinitResult result = runDeinit(new SubmoduleDeinitCommand(db).addPath("sub")); assertEquals(path, result.getPath()); assertEquals(SubmoduleDeinitCommand.SubmoduleDeinitStatus.DIRTY, result.getStatus()); - generator = SubmoduleWalk.forIndex(db); - assertTrue(generator.next()); + try (SubmoduleWalk generator = SubmoduleWalk.forIndex(db)) { + assertTrue(generator.next()); + } assertTrue(submoduleDir.isDirectory()); assertNotEquals(0, submoduleDir.list().length); } private File assertSubmoduleIsInitialized() throws IOException { - SubmoduleWalk generator = SubmoduleWalk.forIndex(db); - assertTrue(generator.next()); - File submoduleDir = new File(db.getWorkTree(), generator.getPath()); - assertTrue(submoduleDir.isDirectory()); - assertNotEquals(0, submoduleDir.list().length); - return submoduleDir; + try (SubmoduleWalk generator = SubmoduleWalk.forIndex(db)) { + assertTrue(generator.next()); + File submoduleDir = new File(db.getWorkTree(), generator.getPath()); + assertTrue(submoduleDir.isDirectory()); + assertNotEquals(0, submoduleDir.list().length); + return submoduleDir; + } } @Test @@ -180,8 +183,9 @@ public class SubmoduleDeinitTest extends RepositoryTestCase { assertEquals(path, result.getPath()); assertEquals(SubmoduleDeinitCommand.SubmoduleDeinitStatus.FORCED, result.getStatus()); - SubmoduleWalk generator = SubmoduleWalk.forIndex(db); - assertTrue(generator.next()); + try (SubmoduleWalk generator = SubmoduleWalk.forIndex(db)) { + assertTrue(generator.next()); + } assertTrue(submoduleDir.isDirectory()); assertEquals(0, submoduleDir.list().length); } @@ -202,8 +206,9 @@ public class SubmoduleDeinitTest extends RepositoryTestCase { assertEquals(path, result.getPath()); assertEquals(SubmoduleDeinitCommand.SubmoduleDeinitStatus.SUCCESS, result.getStatus()); - SubmoduleWalk generator = SubmoduleWalk.forIndex(db); - assertTrue(generator.next()); + try (SubmoduleWalk generator = SubmoduleWalk.forIndex(db)) { + assertTrue(generator.next()); + } assertTrue(submoduleDir.isDirectory()); assertEquals(0, submoduleDir.list().length); } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/submodule/SubmoduleInitTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/submodule/SubmoduleInitTest.java index c7a009c5bf..9fe2fc6fdc 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/submodule/SubmoduleInitTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/submodule/SubmoduleInitTest.java @@ -86,11 +86,11 @@ public class SubmoduleInitTest extends RepositoryTestCase { ConfigInvalidException, GitAPIException { final String path = addSubmoduleToIndex(); - SubmoduleWalk generator = SubmoduleWalk.forIndex(db); - assertTrue(generator.next()); - assertNull(generator.getConfigUrl()); - assertNull(generator.getConfigUpdate()); - + try (SubmoduleWalk generator = SubmoduleWalk.forIndex(db)) { + assertTrue(generator.next()); + assertNull(generator.getConfigUrl()); + assertNull(generator.getConfigUpdate()); + } FileBasedConfig modulesConfig = new FileBasedConfig(new File( db.getWorkTree(), Constants.DOT_GIT_MODULES), db.getFS()); modulesConfig.setString(ConfigConstants.CONFIG_SUBMODULE_SECTION, path, @@ -109,10 +109,11 @@ public class SubmoduleInitTest extends RepositoryTestCase { assertEquals(1, modules.size()); assertEquals(path, modules.iterator().next()); - generator = SubmoduleWalk.forIndex(db); - assertTrue(generator.next()); - assertEquals(url, generator.getConfigUrl()); - assertEquals(update, generator.getConfigUpdate()); + try (SubmoduleWalk generator = SubmoduleWalk.forIndex(db)) { + assertTrue(generator.next()); + assertEquals(url, generator.getConfigUrl()); + assertEquals(update, generator.getConfigUpdate()); + } } @Test @@ -126,11 +127,11 @@ public class SubmoduleInitTest extends RepositoryTestCase { base); config.save(); - SubmoduleWalk generator = SubmoduleWalk.forIndex(db); - assertTrue(generator.next()); - assertNull(generator.getConfigUrl()); - assertNull(generator.getConfigUpdate()); - + try (SubmoduleWalk generator = SubmoduleWalk.forIndex(db)) { + assertTrue(generator.next()); + assertNull(generator.getConfigUrl()); + assertNull(generator.getConfigUpdate()); + } FileBasedConfig modulesConfig = new FileBasedConfig(new File( db.getWorkTree(), Constants.DOT_GIT_MODULES), db.getFS()); modulesConfig.setString(ConfigConstants.CONFIG_SUBMODULE_SECTION, path, @@ -149,10 +150,12 @@ public class SubmoduleInitTest extends RepositoryTestCase { assertEquals(1, modules.size()); assertEquals(path, modules.iterator().next()); - generator = SubmoduleWalk.forIndex(db); - assertTrue(generator.next()); - assertEquals("git://server/repo.git/sub.git", generator.getConfigUrl()); - assertEquals(update, generator.getConfigUpdate()); + try (SubmoduleWalk generator = SubmoduleWalk.forIndex(db)) { + assertTrue(generator.next()); + assertEquals("git://server/repo.git/sub.git", + generator.getConfigUrl()); + assertEquals(update, generator.getConfigUpdate()); + } } @Test @@ -167,11 +170,11 @@ public class SubmoduleInitTest extends RepositoryTestCase { base); config.save(); - SubmoduleWalk generator = SubmoduleWalk.forIndex(db); - assertTrue(generator.next()); - assertNull(generator.getConfigUrl()); - assertNull(generator.getConfigUpdate()); - + try (SubmoduleWalk generator = SubmoduleWalk.forIndex(db)) { + assertTrue(generator.next()); + assertNull(generator.getConfigUrl()); + assertNull(generator.getConfigUpdate()); + } FileBasedConfig modulesConfig = new FileBasedConfig(new File( db.getWorkTree(), Constants.DOT_GIT_MODULES), db.getFS()); modulesConfig.setString(ConfigConstants.CONFIG_SUBMODULE_SECTION, path, @@ -190,10 +193,11 @@ public class SubmoduleInitTest extends RepositoryTestCase { assertEquals(1, modules.size()); assertEquals(path, modules.iterator().next()); - generator = SubmoduleWalk.forIndex(db); - assertTrue(generator.next()); - assertEquals("git://server/sub.git", generator.getConfigUrl()); - assertEquals(update, generator.getConfigUpdate()); + try (SubmoduleWalk generator = SubmoduleWalk.forIndex(db)) { + assertTrue(generator.next()); + assertEquals("git://server/sub.git", generator.getConfigUrl()); + assertEquals(update, generator.getConfigUpdate()); + } } @Test @@ -208,11 +212,11 @@ public class SubmoduleInitTest extends RepositoryTestCase { base); config.save(); - SubmoduleWalk generator = SubmoduleWalk.forIndex(db); - assertTrue(generator.next()); - assertNull(generator.getConfigUrl()); - assertNull(generator.getConfigUpdate()); - + try (SubmoduleWalk generator = SubmoduleWalk.forIndex(db)) { + assertTrue(generator.next()); + assertNull(generator.getConfigUrl()); + assertNull(generator.getConfigUpdate()); + } FileBasedConfig modulesConfig = new FileBasedConfig(new File( db.getWorkTree(), Constants.DOT_GIT_MODULES), db.getFS()); modulesConfig.setString(ConfigConstants.CONFIG_SUBMODULE_SECTION, path, @@ -231,10 +235,11 @@ public class SubmoduleInitTest extends RepositoryTestCase { assertEquals(1, modules.size()); assertEquals(path, modules.iterator().next()); - generator = SubmoduleWalk.forIndex(db); - assertTrue(generator.next()); - assertEquals("git://server2/sub.git", generator.getConfigUrl()); - assertEquals(update, generator.getConfigUpdate()); + try (SubmoduleWalk generator = SubmoduleWalk.forIndex(db)) { + assertTrue(generator.next()); + assertEquals("git://server2/sub.git", generator.getConfigUrl()); + assertEquals(update, generator.getConfigUpdate()); + } } @Test @@ -250,11 +255,11 @@ public class SubmoduleInitTest extends RepositoryTestCase { Constants.DEFAULT_REMOTE_NAME, ConfigConstants.CONFIG_KEY_URL); config.save(); - SubmoduleWalk generator = SubmoduleWalk.forIndex(db); - assertTrue(generator.next()); - assertNull(generator.getConfigUrl()); - assertNull(generator.getConfigUpdate()); - + try (SubmoduleWalk generator = SubmoduleWalk.forIndex(db)) { + assertTrue(generator.next()); + assertNull(generator.getConfigUrl()); + assertNull(generator.getConfigUpdate()); + } FileBasedConfig modulesConfig = new FileBasedConfig(new File( db.getWorkTree(), Constants.DOT_GIT_MODULES), db.getFS()); modulesConfig.setString(ConfigConstants.CONFIG_SUBMODULE_SECTION, path, @@ -273,10 +278,11 @@ public class SubmoduleInitTest extends RepositoryTestCase { assertEquals(1, modules.size()); assertEquals(path, modules.iterator().next()); - generator = SubmoduleWalk.forIndex(db); - assertTrue(generator.next()); - assertEquals(base + "/sub.git", generator.getConfigUrl()); - assertEquals(update, generator.getConfigUpdate()); + try (SubmoduleWalk generator = SubmoduleWalk.forIndex(db)) { + assertTrue(generator.next()); + assertEquals(base + "/sub.git", generator.getConfigUrl()); + assertEquals(update, generator.getConfigUpdate()); + } } @Test @@ -291,11 +297,11 @@ public class SubmoduleInitTest extends RepositoryTestCase { base); config.save(); - SubmoduleWalk generator = SubmoduleWalk.forIndex(db); - assertTrue(generator.next()); - assertNull(generator.getConfigUrl()); - assertNull(generator.getConfigUpdate()); - + try (SubmoduleWalk generator = SubmoduleWalk.forIndex(db)) { + assertTrue(generator.next()); + assertNull(generator.getConfigUrl()); + assertNull(generator.getConfigUpdate()); + } FileBasedConfig modulesConfig = new FileBasedConfig(new File( db.getWorkTree(), Constants.DOT_GIT_MODULES), db.getFS()); modulesConfig.setString(ConfigConstants.CONFIG_SUBMODULE_SECTION, path, diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/submodule/SubmoduleSyncTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/submodule/SubmoduleSyncTest.java index 6f3b52f7bb..1053e31bc9 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/submodule/SubmoduleSyncTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/submodule/SubmoduleSyncTest.java @@ -119,11 +119,11 @@ public class SubmoduleSyncTest extends RepositoryTestCase { addRepoToClose(subRepo); assertNotNull(subRepo); - SubmoduleWalk generator = SubmoduleWalk.forIndex(db); - assertTrue(generator.next()); - assertNull(generator.getConfigUrl()); - assertEquals(url, generator.getModulesUrl()); - + try (SubmoduleWalk generator = SubmoduleWalk.forIndex(db)) { + assertTrue(generator.next()); + assertNull(generator.getConfigUrl()); + assertEquals(url, generator.getModulesUrl()); + } SubmoduleSyncCommand command = new SubmoduleSyncCommand(db); Map<String, String> synced = command.call(); assertNotNull(synced); @@ -132,16 +132,17 @@ public class SubmoduleSyncTest extends RepositoryTestCase { assertEquals(path, module.getKey()); assertEquals(url, module.getValue()); - generator = SubmoduleWalk.forIndex(db); - assertTrue(generator.next()); - assertEquals(url, generator.getConfigUrl()); - try (Repository subModRepository = generator.getRepository()) { - StoredConfig submoduleConfig = subModRepository.getConfig(); - assertEquals(url, - submoduleConfig.getString( - ConfigConstants.CONFIG_REMOTE_SECTION, - Constants.DEFAULT_REMOTE_NAME, - ConfigConstants.CONFIG_KEY_URL)); + try (SubmoduleWalk generator = SubmoduleWalk.forIndex(db)) { + assertTrue(generator.next()); + assertEquals(url, generator.getConfigUrl()); + try (Repository subModRepository = generator.getRepository()) { + StoredConfig submoduleConfig = subModRepository.getConfig(); + assertEquals(url, + submoduleConfig.getString( + ConfigConstants.CONFIG_REMOTE_SECTION, + Constants.DEFAULT_REMOTE_NAME, + ConfigConstants.CONFIG_KEY_URL)); + } } } @@ -190,11 +191,11 @@ public class SubmoduleSyncTest extends RepositoryTestCase { assertNotNull(subRepo); addRepoToClose(subRepo); - SubmoduleWalk generator = SubmoduleWalk.forIndex(db); - assertTrue(generator.next()); - assertNull(generator.getConfigUrl()); - assertEquals(current, generator.getModulesUrl()); - + try (SubmoduleWalk generator = SubmoduleWalk.forIndex(db)) { + assertTrue(generator.next()); + assertNull(generator.getConfigUrl()); + assertEquals(current, generator.getModulesUrl()); + } modulesConfig.setString(ConfigConstants.CONFIG_SUBMODULE_SECTION, path, ConfigConstants.CONFIG_KEY_URL, "../sub.git"); modulesConfig.save(); @@ -207,16 +208,17 @@ public class SubmoduleSyncTest extends RepositoryTestCase { assertEquals(path, module.getKey()); assertEquals("git://server/sub.git", module.getValue()); - generator = SubmoduleWalk.forIndex(db); - assertTrue(generator.next()); - assertEquals("git://server/sub.git", generator.getConfigUrl()); - try (Repository subModRepository1 = generator.getRepository()) { - StoredConfig submoduleConfig = subModRepository1.getConfig(); - assertEquals("git://server/sub.git", - submoduleConfig.getString( - ConfigConstants.CONFIG_REMOTE_SECTION, - Constants.DEFAULT_REMOTE_NAME, - ConfigConstants.CONFIG_KEY_URL)); + try (SubmoduleWalk generator = SubmoduleWalk.forIndex(db)) { + assertTrue(generator.next()); + assertEquals("git://server/sub.git", generator.getConfigUrl()); + try (Repository subModRepository1 = generator.getRepository()) { + StoredConfig submoduleConfig = subModRepository1.getConfig(); + assertEquals("git://server/sub.git", + submoduleConfig.getString( + ConfigConstants.CONFIG_REMOTE_SECTION, + Constants.DEFAULT_REMOTE_NAME, + ConfigConstants.CONFIG_KEY_URL)); + } } } } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/submodule/SubmoduleUpdateTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/submodule/SubmoduleUpdateTest.java index bbce413ef3..6f358b47fd 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/submodule/SubmoduleUpdateTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/submodule/SubmoduleUpdateTest.java @@ -119,11 +119,12 @@ public class SubmoduleUpdateTest extends RepositoryTestCase { assertEquals(1, updated.size()); assertEquals(path, updated.iterator().next()); - SubmoduleWalk generator = SubmoduleWalk.forIndex(db); - assertTrue(generator.next()); - try (Repository subRepo = generator.getRepository()) { - assertNotNull(subRepo); - assertEquals(commit, subRepo.resolve(Constants.HEAD)); + try (SubmoduleWalk generator = SubmoduleWalk.forIndex(db)) { + assertTrue(generator.next()); + try (Repository subRepo = generator.getRepository()) { + assertNotNull(subRepo); + assertEquals(commit, subRepo.resolve(Constants.HEAD)); + } } } @@ -181,10 +182,11 @@ public class SubmoduleUpdateTest extends RepositoryTestCase { }); editor.commit(); - Repository subRepo = Git.init().setBare(false) + try (Repository subRepo = Git.init().setBare(false) .setDirectory(new File(db.getWorkTree(), path)).call() - .getRepository(); - assertNotNull(subRepo); + .getRepository()) { + assertNotNull(subRepo); + } SubmoduleUpdateCommand command = new SubmoduleUpdateCommand(db); Collection<String> updated = command.call(); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/submodule/SubmoduleWalkTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/submodule/SubmoduleWalkTest.java index ea1ace364e..0b6047f881 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/submodule/SubmoduleWalkTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/submodule/SubmoduleWalkTest.java @@ -98,10 +98,11 @@ public class SubmoduleWalkTest extends RepositoryTestCase { @Test public void repositoryWithNoSubmodules() throws IOException { - SubmoduleWalk gen = SubmoduleWalk.forIndex(db); - assertFalse(gen.next()); - assertNull(gen.getPath()); - assertEquals(ObjectId.zeroId(), gen.getObjectId()); + try (SubmoduleWalk gen = SubmoduleWalk.forIndex(db)) { + assertFalse(gen.next()); + assertNull(gen.getPath()); + assertEquals(ObjectId.zeroId(), gen.getObjectId()); + } } @Test @@ -129,20 +130,21 @@ public class SubmoduleWalkTest extends RepositoryTestCase { }); editor.commit(); - SubmoduleWalk gen = SubmoduleWalk.forIndex(db); - assertTrue(gen.next()); - assertEquals(path, gen.getPath()); - assertEquals(id, gen.getObjectId()); - assertEquals(new File(db.getWorkTree(), path), gen.getDirectory()); - assertNull(gen.getConfigUpdate()); - assertNull(gen.getConfigUrl()); - assertNull(gen.getModulesPath()); - assertNull(gen.getModulesUpdate()); - assertNull(gen.getModulesUrl()); - assertNull(gen.getRepository()); + try (SubmoduleWalk gen = SubmoduleWalk.forIndex(db)) { + assertTrue(gen.next()); + assertEquals(path, gen.getPath()); + assertEquals(id, gen.getObjectId()); + assertEquals(new File(db.getWorkTree(), path), gen.getDirectory()); + assertNull(gen.getConfigUpdate()); + assertNull(gen.getConfigUrl()); + assertNull(gen.getModulesPath()); + assertNull(gen.getModulesUpdate()); + assertNull(gen.getModulesUrl()); + assertNull(gen.getRepository()); + assertFalse(gen.next()); + } Status status = Git.wrap(db).status().call(); - assertTrue(!status.isClean()); - assertFalse(gen.next()); + assertFalse(status.isClean()); } @Test @@ -178,24 +180,25 @@ public class SubmoduleWalkTest extends RepositoryTestCase { }); editor.commit(); - SubmoduleWalk gen = SubmoduleWalk.forIndex(db); - assertTrue(gen.next()); - assertEquals(path, gen.getPath()); - assertEquals(id, gen.getObjectId()); - assertEquals(new File(db.getWorkTree(), path), gen.getDirectory()); - assertNull(gen.getConfigUpdate()); - assertNull(gen.getConfigUrl()); - assertNull(gen.getModulesPath()); - assertNull(gen.getModulesUpdate()); - assertNull(gen.getModulesUrl()); - try (Repository subRepo = gen.getRepository()) { - assertNotNull(subRepo); - assertEquals(modulesGitDir.getAbsolutePath(), - subRepo.getDirectory().getAbsolutePath()); - assertEquals(new File(db.getWorkTree(), path).getAbsolutePath(), - subRepo.getWorkTree().getAbsolutePath()); + try (SubmoduleWalk gen = SubmoduleWalk.forIndex(db)) { + assertTrue(gen.next()); + assertEquals(path, gen.getPath()); + assertEquals(id, gen.getObjectId()); + assertEquals(new File(db.getWorkTree(), path), gen.getDirectory()); + assertNull(gen.getConfigUpdate()); + assertNull(gen.getConfigUrl()); + assertNull(gen.getModulesPath()); + assertNull(gen.getModulesUpdate()); + assertNull(gen.getModulesUrl()); + try (Repository subRepo = gen.getRepository()) { + assertNotNull(subRepo); + assertEquals(modulesGitDir.getAbsolutePath(), + subRepo.getDirectory().getAbsolutePath()); + assertEquals(new File(db.getWorkTree(), path).getAbsolutePath(), + subRepo.getWorkTree().getAbsolutePath()); + } + assertFalse(gen.next()); } - assertFalse(gen.next()); } @Test @@ -232,23 +235,24 @@ public class SubmoduleWalkTest extends RepositoryTestCase { }); editor.commit(); - SubmoduleWalk gen = SubmoduleWalk.forIndex(db); - assertTrue(gen.next()); - assertEquals(path, gen.getPath()); - assertEquals(id, gen.getObjectId()); - assertEquals(new File(db.getWorkTree(), path), gen.getDirectory()); - assertNull(gen.getConfigUpdate()); - assertNull(gen.getConfigUrl()); - assertNull(gen.getModulesPath()); - assertNull(gen.getModulesUpdate()); - assertNull(gen.getModulesUrl()); - try (Repository subRepo = gen.getRepository()) { - assertNotNull(subRepo); - assertEqualsFile(modulesGitDir, subRepo.getDirectory()); - assertEqualsFile(new File(db.getWorkTree(), path), - subRepo.getWorkTree()); - subRepo.close(); - assertFalse(gen.next()); + try (SubmoduleWalk gen = SubmoduleWalk.forIndex(db)) { + assertTrue(gen.next()); + assertEquals(path, gen.getPath()); + assertEquals(id, gen.getObjectId()); + assertEquals(new File(db.getWorkTree(), path), gen.getDirectory()); + assertNull(gen.getConfigUpdate()); + assertNull(gen.getConfigUrl()); + assertNull(gen.getModulesPath()); + assertNull(gen.getModulesUpdate()); + assertNull(gen.getModulesUrl()); + try (Repository subRepo = gen.getRepository()) { + assertNotNull(subRepo); + assertEqualsFile(modulesGitDir, subRepo.getDirectory()); + assertEqualsFile(new File(db.getWorkTree(), path), + subRepo.getWorkTree()); + subRepo.close(); + assertFalse(gen.next()); + } } } @@ -270,18 +274,19 @@ public class SubmoduleWalkTest extends RepositoryTestCase { }); editor.commit(); - SubmoduleWalk gen = SubmoduleWalk.forIndex(db); - assertTrue(gen.next()); - assertEquals(path, gen.getPath()); - assertEquals(id, gen.getObjectId()); - assertEquals(new File(db.getWorkTree(), path), gen.getDirectory()); - assertNull(gen.getConfigUpdate()); - assertNull(gen.getConfigUrl()); - assertNull(gen.getModulesPath()); - assertNull(gen.getModulesUpdate()); - assertNull(gen.getModulesUrl()); - assertNull(gen.getRepository()); - assertFalse(gen.next()); + try (SubmoduleWalk gen = SubmoduleWalk.forIndex(db)) { + assertTrue(gen.next()); + assertEquals(path, gen.getPath()); + assertEquals(id, gen.getObjectId()); + assertEquals(new File(db.getWorkTree(), path), gen.getDirectory()); + assertNull(gen.getConfigUpdate()); + assertNull(gen.getConfigUrl()); + assertNull(gen.getModulesPath()); + assertNull(gen.getModulesUpdate()); + assertNull(gen.getModulesUrl()); + assertNull(gen.getRepository()); + assertFalse(gen.next()); + } } @Test @@ -312,12 +317,13 @@ public class SubmoduleWalkTest extends RepositoryTestCase { }); editor.commit(); - SubmoduleWalk gen = SubmoduleWalk.forIndex(db); - gen.setFilter(PathFilter.create(path1)); - assertTrue(gen.next()); - assertEquals(path1, gen.getPath()); - assertEquals(id1, gen.getObjectId()); - assertFalse(gen.next()); + try (SubmoduleWalk gen = SubmoduleWalk.forIndex(db)) { + gen.setFilter(PathFilter.create(path1)); + assertTrue(gen.next()); + assertEquals(path1, gen.getPath()); + assertEquals(id1, gen.getObjectId()); + assertFalse(gen.next()); + } } @Test @@ -358,18 +364,19 @@ public class SubmoduleWalkTest extends RepositoryTestCase { }); editor.commit(); - SubmoduleWalk gen = SubmoduleWalk.forIndex(db); - assertTrue(gen.next()); - assertEquals(path, gen.getPath()); - assertEquals(subId, gen.getObjectId()); - assertEquals(new File(db.getWorkTree(), path), gen.getDirectory()); - assertNull(gen.getConfigUpdate()); - assertNull(gen.getConfigUrl()); - assertEquals("sub", gen.getModulesPath()); - assertNull(gen.getModulesUpdate()); - assertEquals("git://example.com/sub", gen.getModulesUrl()); - assertNull(gen.getRepository()); - assertFalse(gen.next()); + try (SubmoduleWalk gen = SubmoduleWalk.forIndex(db)) { + assertTrue(gen.next()); + assertEquals(path, gen.getPath()); + assertEquals(subId, gen.getObjectId()); + assertEquals(new File(db.getWorkTree(), path), gen.getDirectory()); + assertNull(gen.getConfigUpdate()); + assertNull(gen.getConfigUrl()); + assertEquals("sub", gen.getModulesPath()); + assertNull(gen.getModulesUpdate()); + assertEquals("git://example.com/sub", gen.getModulesUrl()); + assertNull(gen.getRepository()); + assertFalse(gen.next()); + } } @Test @@ -397,17 +404,19 @@ public class SubmoduleWalkTest extends RepositoryTestCase { }) .create()); - SubmoduleWalk gen = SubmoduleWalk.forPath(db, commit.getTree(), "sub"); - assertEquals(path, gen.getPath()); - assertEquals(subId, gen.getObjectId()); - assertEquals(new File(db.getWorkTree(), path), gen.getDirectory()); - assertNull(gen.getConfigUpdate()); - assertNull(gen.getConfigUrl()); - assertEquals("sub", gen.getModulesPath()); - assertNull(gen.getModulesUpdate()); - assertEquals("git://example.com/sub", gen.getModulesUrl()); - assertNull(gen.getRepository()); - assertFalse(gen.next()); + try (SubmoduleWalk gen = SubmoduleWalk.forPath(db, commit.getTree(), + "sub")) { + assertEquals(path, gen.getPath()); + assertEquals(subId, gen.getObjectId()); + assertEquals(new File(db.getWorkTree(), path), gen.getDirectory()); + assertNull(gen.getConfigUpdate()); + assertNull(gen.getConfigUrl()); + assertEquals("sub", gen.getModulesPath()); + assertNull(gen.getModulesUpdate()); + assertEquals("git://example.com/sub", gen.getModulesUrl()); + assertNull(gen.getRepository()); + assertFalse(gen.next()); + } } @Test @@ -437,17 +446,18 @@ public class SubmoduleWalkTest extends RepositoryTestCase { final CanonicalTreeParser p = new CanonicalTreeParser(); p.reset(testDb.getRevWalk().getObjectReader(), commit.getTree()); - SubmoduleWalk gen = SubmoduleWalk.forPath(db, p, "sub"); - assertEquals(path, gen.getPath()); - assertEquals(subId, gen.getObjectId()); - assertEquals(new File(db.getWorkTree(), path), gen.getDirectory()); - assertNull(gen.getConfigUpdate()); - assertNull(gen.getConfigUrl()); - assertEquals("sub", gen.getModulesPath()); - assertNull(gen.getModulesUpdate()); - assertEquals("git://example.com/sub", gen.getModulesUrl()); - assertNull(gen.getRepository()); - assertFalse(gen.next()); + try (SubmoduleWalk gen = SubmoduleWalk.forPath(db, p, "sub")) { + assertEquals(path, gen.getPath()); + assertEquals(subId, gen.getObjectId()); + assertEquals(new File(db.getWorkTree(), path), gen.getDirectory()); + assertNull(gen.getConfigUpdate()); + assertNull(gen.getConfigUrl()); + assertEquals("sub", gen.getModulesPath()); + assertNull(gen.getModulesUpdate()); + assertEquals("git://example.com/sub", gen.getModulesUrl()); + assertNull(gen.getRepository()); + assertFalse(gen.next()); + } } @Test @@ -477,16 +487,17 @@ public class SubmoduleWalkTest extends RepositoryTestCase { final CanonicalTreeParser p = new CanonicalTreeParser(); p.reset(testDb.getRevWalk().getObjectReader(), commit.getTree()); - SubmoduleWalk gen = SubmoduleWalk.forPath(db, p, "sub"); - assertEquals(path, gen.getPath()); - assertEquals(subId, gen.getObjectId()); - assertEquals(new File(db.getWorkTree(), path), gen.getDirectory()); - assertNull(gen.getConfigUpdate()); - assertNull(gen.getConfigUrl()); - assertEquals("sub", gen.getModulesPath()); - assertNull(gen.getModulesUpdate()); - assertEquals("git://example.com/sub", gen.getModulesUrl()); - assertNull(gen.getRepository()); - assertFalse(gen.next()); + try (SubmoduleWalk gen = SubmoduleWalk.forPath(db, p, "sub")) { + assertEquals(path, gen.getPath()); + assertEquals(subId, gen.getObjectId()); + assertEquals(new File(db.getWorkTree(), path), gen.getDirectory()); + assertNull(gen.getConfigUpdate()); + assertNull(gen.getConfigUrl()); + assertEquals("sub", gen.getModulesPath()); + assertNull(gen.getModulesUpdate()); + assertEquals("git://example.com/sub", gen.getModulesUrl()); + assertNull(gen.getRepository()); + assertFalse(gen.next()); + } } } 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 c1e078d10d..d6c7a6199d 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 @@ -55,10 +55,9 @@ import org.eclipse.jgit.errors.TransportException; 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.lib.Constants; +import org.eclipse.jgit.junit.TestRepository; import org.eclipse.jgit.lib.NullProgressMonitor; import org.eclipse.jgit.lib.ObjectId; -import org.eclipse.jgit.lib.ObjectInserter; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.transport.resolver.ReceivePackFactory; import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException; @@ -73,8 +72,8 @@ public class AtomicPushTest { private Object ctx = new Object(); private InMemoryRepository server; private InMemoryRepository client; - private ObjectId obj1; - private ObjectId obj2; + private ObjectId commit1; + private ObjectId commit2; @Before public void setUp() throws Exception { @@ -92,10 +91,11 @@ public class AtomicPushTest { }); uri = testProtocol.register(ctx, server); - try (ObjectInserter ins = client.newObjectInserter()) { - obj1 = ins.insert(Constants.OBJ_BLOB, Constants.encode("test")); - obj2 = ins.insert(Constants.OBJ_BLOB, Constants.encode("file")); - ins.flush(); + try (TestRepository<?> clientRepo = new TestRepository<>(client)) { + commit1 = clientRepo.commit().noFiles().message("test commit 1") + .create(); + commit2 = clientRepo.commit().noFiles().message("test commit 2") + .create(); } } @@ -149,13 +149,13 @@ public class AtomicPushTest { List<RemoteRefUpdate> cmds = new ArrayList<>(); cmds.add(new RemoteRefUpdate( null, null, - obj1, "refs/heads/one", + commit1, "refs/heads/one", true /* force update */, null /* no local tracking ref */, ObjectId.zeroId())); cmds.add(new RemoteRefUpdate( null, null, - obj2, "refs/heads/two", + commit2, "refs/heads/two", true /* force update */, null /* no local tracking ref */, ObjectId.zeroId())); @@ -176,16 +176,16 @@ public class AtomicPushTest { List<RemoteRefUpdate> cmds = new ArrayList<>(); cmds.add(new RemoteRefUpdate( null, null, - obj1, "refs/heads/one", + commit1, "refs/heads/one", true /* force update */, null /* no local tracking ref */, ObjectId.zeroId())); cmds.add(new RemoteRefUpdate( null, null, - obj2, "refs/heads/two", + commit2, "refs/heads/two", true /* force update */, null /* no local tracking ref */, - obj1)); + commit1)); return cmds; } } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/HttpAuthTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/HttpAuthTest.java index ea15ebe7de..947ca97615 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/HttpAuthTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/HttpAuthTest.java @@ -133,16 +133,15 @@ public class HttpAuthTest { @Override public String getHeaderField(String name) { - if (!headerFields.containsKey(name)) + if (!headerFields.containsKey(name)) { return null; - else { - int n = headerFields.get(name).size(); + } + int n = headerFields.get(name).size(); - if (n > 0) - return headerFields.get(name).get(n - 1); - else - return null; + if (n > 0) { + return headerFields.get(name).get(n - 1); } + return null; } @Override diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PushCertificateParserTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PushCertificateParserTest.java index 4bf26b6288..5db4563ba6 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PushCertificateParserTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PushCertificateParserTest.java @@ -145,7 +145,7 @@ public class PushCertificateParserTest { ObjectId newId = ObjectId.fromString("deadbeefdeadbeefdeadbeefdeadbeefdeadbeef"); String line = oldId.name() + " " + newId.name() + " refs/heads/master"; - ReceiveCommand cmd = BaseReceivePack.parseCommand(line); + ReceiveCommand cmd = ReceivePack.parseCommand(line); parser.addCommand(cmd); parser.addCommand(line); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PushOptionsTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PushOptionsTest.java index fd1c3bf8b8..18946e0d50 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PushOptionsTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PushOptionsTest.java @@ -62,10 +62,9 @@ import org.eclipse.jgit.api.errors.TransportException; import org.eclipse.jgit.internal.storage.dfs.DfsRepositoryDescription; import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository; import org.eclipse.jgit.junit.RepositoryTestCase; -import org.eclipse.jgit.lib.Constants; +import org.eclipse.jgit.junit.TestRepository; import org.eclipse.jgit.lib.NullProgressMonitor; import org.eclipse.jgit.lib.ObjectId; -import org.eclipse.jgit.lib.ObjectInserter; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.lib.StoredConfig; import org.eclipse.jgit.revwalk.RevCommit; @@ -79,8 +78,8 @@ public class PushOptionsTest extends RepositoryTestCase { private Object ctx = new Object(); private InMemoryRepository server; private InMemoryRepository client; - private ObjectId obj1; - private ObjectId obj2; + private ObjectId commit1; + private ObjectId commit2; private ReceivePack receivePack; @Override @@ -101,10 +100,11 @@ public class PushOptionsTest extends RepositoryTestCase { uri = testProtocol.register(ctx, server); - try (ObjectInserter ins = client.newObjectInserter()) { - obj1 = ins.insert(Constants.OBJ_BLOB, Constants.encode("test")); - obj2 = ins.insert(Constants.OBJ_BLOB, Constants.encode("file")); - ins.flush(); + try (TestRepository<?> clientRepo = new TestRepository<>(client)) { + commit1 = clientRepo.commit().noFiles().message("test commit 1") + .create(); + commit2 = clientRepo.commit().noFiles().message("test commit 2") + .create(); } } @@ -121,12 +121,12 @@ public class PushOptionsTest extends RepositoryTestCase { private List<RemoteRefUpdate> commands(boolean atomicSafe) throws IOException { List<RemoteRefUpdate> cmds = new ArrayList<>(); - cmds.add(new RemoteRefUpdate(null, null, obj1, "refs/heads/one", + cmds.add(new RemoteRefUpdate(null, null, commit1, "refs/heads/one", true /* force update */, null /* no local tracking ref */, ObjectId.zeroId())); - cmds.add(new RemoteRefUpdate(null, null, obj2, "refs/heads/two", + cmds.add(new RemoteRefUpdate(null, null, commit2, "refs/heads/two", true /* force update */, null /* no local tracking ref */, - atomicSafe ? ObjectId.zeroId() : obj1)); + atomicSafe ? ObjectId.zeroId() : commit1)); return cmds; } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/ReachableCommitRequestValidatorTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/ReachableCommitRequestValidatorTest.java new file mode 100644 index 0000000000..20b490b263 --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/ReachableCommitRequestValidatorTest.java @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2019, Google LLC. + * 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.transport; + +import org.eclipse.jgit.transport.UploadPack.RequestValidator; + +/** + * Client may ask for any commit reachable from a reference advertised by + * the server. + */ +public class ReachableCommitRequestValidatorTest extends RequestValidatorTestCase { + + @Override + protected RequestValidator createValidator() { + return new UploadPack.ReachableCommitRequestValidator(); + } + + @Override + protected boolean isReachableCommitValid() { + return true; + } + + @Override + protected boolean isUnreachableCommitValid() { + return false; + } + + @Override + protected boolean isReachableBlobValid_withBitmaps() { + return true; + } + + @Override + protected boolean isReachableBlobValid_withoutBitmaps() { + return false; + } + + @Override + protected boolean isUnreachableBlobValid() { + return false; + } + + @Override + protected boolean isAdvertisedTipValid() { + return true; + } + + @Override + protected boolean isUnadvertisedTipCommitValid() { + return false; + } +} diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/ReachableCommitTipRequestValidatorTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/ReachableCommitTipRequestValidatorTest.java new file mode 100644 index 0000000000..5e5391dac7 --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/ReachableCommitTipRequestValidatorTest.java @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2019, Google LLC. + * 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.transport; + +import org.eclipse.jgit.transport.UploadPack.RequestValidator; + +/** + * Client may ask for any commit reachable from any reference, even if that + * reference wasn't advertised. + */ +public class ReachableCommitTipRequestValidatorTest + extends RequestValidatorTestCase { + + @Override + protected RequestValidator createValidator() { + return new UploadPack.ReachableCommitTipRequestValidator(); + } + + @Override + protected boolean isReachableCommitValid() { + return true; + } + + @Override + protected boolean isUnreachableCommitValid() { + return false; + } + + @Override + protected boolean isAdvertisedTipValid() { + return true; + } + + @Override + protected boolean isReachableBlobValid_withBitmaps() { + return true; + } + + @Override + protected boolean isReachableBlobValid_withoutBitmaps() { + return false; + } + + @Override + protected boolean isUnreachableBlobValid() { + return false; + } + + @Override + protected boolean isUnadvertisedTipCommitValid() { + return true; + } + +} 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 5d208eea73..89ac2fe96d 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 @@ -174,7 +174,7 @@ public class ReceivePackAdvertiseRefsHookTest extends LocalDiskRepositoryTestCas ReceivePack rp = super.createReceivePack(dst); rp.setAdvertiseRefsHook(new AdvertiseRefsHook() { @Override - public void advertiseRefs(BaseReceivePack rp2) + public void advertiseRefs(ReceivePack rp2) throws ServiceMayNotContinueException { rp.setAdvertisedRefs(rp.getRepository().getAllRefs(), null); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/BaseReceivePackTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/ReceivePackTest.java index 7578c6e3eb..156746d79f 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/BaseReceivePackTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/ReceivePackTest.java @@ -49,14 +49,14 @@ import org.eclipse.jgit.errors.PackProtocolException; import org.eclipse.jgit.lib.ObjectId; import org.junit.Test; -/** Tests for base receive-pack utilities. */ -public class BaseReceivePackTest { +/** Tests for receive-pack utilities. */ +public class ReceivePackTest { @Test public void parseCommand() throws Exception { String o = "0000000000000000000000000000000000000000"; String n = "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef"; String r = "refs/heads/master"; - ReceiveCommand cmd = BaseReceivePack.parseCommand(o + " " + n + " " + r); + ReceiveCommand cmd = ReceivePack.parseCommand(o + " " + n + " " + r); assertEquals(ObjectId.zeroId(), cmd.getOldId()); assertEquals("deadbeefdeadbeefdeadbeefdeadbeefdeadbeef", cmd.getNewId().name()); @@ -76,7 +76,7 @@ public class BaseReceivePackTest { private void assertParseCommandFails(String input) { try { - BaseReceivePack.parseCommand(input); + ReceivePack.parseCommand(input); fail(); } catch (PackProtocolException e) { // Expected. diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/RequestValidatorTestCase.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/RequestValidatorTestCase.java new file mode 100644 index 0000000000..c1e7bcfcbe --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/RequestValidatorTestCase.java @@ -0,0 +1,319 @@ +/* + * Copyright (C) 2019, Google LLC. + * 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.transport; + +import java.io.IOException; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.jgit.errors.PackProtocolException; +import org.eclipse.jgit.errors.TransportException; +import org.eclipse.jgit.internal.storage.dfs.DfsGarbageCollector; +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.Ref; +import org.eclipse.jgit.lib.Repository; +import org.eclipse.jgit.revwalk.RevBlob; +import org.eclipse.jgit.revwalk.RevCommit; +import org.eclipse.jgit.transport.UploadPack.RequestValidator; +import org.hamcrest.Matchers; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +public abstract class RequestValidatorTestCase { + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + private RevCommit reachableCommit; + + private RevCommit tipAdvertisedCommit; + + private RevCommit tipUnadvertisedCommit; + + private RevCommit unreachableCommit; + + private RevBlob reachableBlob; + + private RevBlob unreachableBlob; + + private InMemoryRepository repo; + + protected abstract RequestValidator createValidator(); + + @Before + public void setUp() throws Exception { + repo = new InMemoryRepository(new DfsRepositoryDescription()); + try (TestRepository<InMemoryRepository> git = new TestRepository<>( + repo)) { + reachableBlob = git.blob("foo"); + reachableCommit = git + .commit(git.tree(git.file("foo", reachableBlob))); + tipAdvertisedCommit = git.commit(reachableCommit); + git.update("advertised", tipAdvertisedCommit); + + tipUnadvertisedCommit = git.commit(reachableCommit); + git.update("unadvertised", tipUnadvertisedCommit); + + unreachableBlob = git.blob("unreachableFoo"); + unreachableCommit = git + .commit(git.tree(git.file("foo", unreachableBlob))); + } + } + + /** + * @return true if a commit reachable from a visible tip (but not directly + * the tip) is valid + */ + protected abstract boolean isReachableCommitValid(); + + /** @return true if a commit not reachable from any tip is valid */ + protected abstract boolean isUnreachableCommitValid(); + + /** + * @return true if the commit directly pointed by an advertised ref is valid + */ + protected abstract boolean isAdvertisedTipValid(); + + /** + * @return true if the object directly pointed by a non-advertised ref is + * valid + */ + protected abstract boolean isUnadvertisedTipCommitValid(); + + // UploadPack doesn't allow to ask for blobs when there is no + // bitmap. Test both cases separately. + /** + * @return true if a reachable blob is valid (and the repo has bitmaps) + */ + protected abstract boolean isReachableBlobValid_withBitmaps(); + + /** + * @return true if a reachable blob is valid (and the repo does NOT have + * bitmaps) + */ + protected abstract boolean isReachableBlobValid_withoutBitmaps(); + + /** + * @return true if a blob unreachable from any tip is valid + */ + protected abstract boolean isUnreachableBlobValid(); + + @Test + public void validateReachableCommitWithBitmaps() + throws PackProtocolException, IOException { + if (!isReachableCommitValid()) { + thrown.expect(TransportException.class); + thrown.expectMessage(Matchers + .containsString( + "want " + reachableCommit.name() + " not valid")); + + } + createValidator().checkWants(getUploadPack(getRepoWithBitmaps()), + Arrays.asList(reachableCommit)); + } + + @Test + public void validateReachableCommitWithoutBitmaps() + throws PackProtocolException, IOException { + if (!isReachableCommitValid()) { + thrown.expect(TransportException.class); + thrown.expectMessage(Matchers.containsString( + "want " + reachableCommit.name() + " not valid")); + + } + createValidator().checkWants(getUploadPack(getRepoWithoutBitmaps()), + Arrays.asList(reachableCommit)); + } + + @Test + public void validateAdvertisedTipWithBitmaps() + throws PackProtocolException, IOException { + if (!isAdvertisedTipValid()) { + thrown.expect(TransportException.class); + thrown.expectMessage(Matchers.containsString( + "want " + tipAdvertisedCommit.name() + " not valid")); + + } + createValidator().checkWants(getUploadPack(getRepoWithBitmaps()), + Arrays.asList(tipAdvertisedCommit)); + } + + @Test + public void validateAdvertisedTipWithoutBitmaps() + throws PackProtocolException, IOException { + if (!isAdvertisedTipValid()) { + thrown.expect(TransportException.class); + thrown.expectMessage(Matchers.containsString( + "want " + tipAdvertisedCommit.name() + " not valid")); + + } + createValidator().checkWants(getUploadPack(getRepoWithoutBitmaps()), + Arrays.asList(tipAdvertisedCommit)); + } + + @Test + public void validateUnadvertisedTipWithBitmaps() + throws PackProtocolException, IOException { + if (!isUnadvertisedTipCommitValid()) { + thrown.expect(TransportException.class); + thrown.expectMessage(Matchers.containsString( + "want " + tipUnadvertisedCommit.name() + " not valid")); + + } + createValidator().checkWants(getUploadPack(getRepoWithBitmaps()), + Arrays.asList(tipUnadvertisedCommit)); + } + + @Test + public void validateUnadvertisedTipWithoutBitmaps() + throws PackProtocolException, IOException { + if (!isUnadvertisedTipCommitValid()) { + thrown.expect(TransportException.class); + thrown.expectMessage(Matchers.containsString( + "want " + tipUnadvertisedCommit.name() + " not valid")); + + } + createValidator().checkWants(getUploadPack(getRepoWithoutBitmaps()), + Arrays.asList(tipUnadvertisedCommit)); + } + + @Test + public void validateUnreachableCommitWithBitmaps() + throws PackProtocolException, IOException { + if (!isUnreachableCommitValid()) { + thrown.expect(TransportException.class); + thrown.expectMessage(Matchers.containsString( + "want " + unreachableCommit.name() + " not valid")); + + } + createValidator().checkWants(getUploadPack(getRepoWithBitmaps()), + Arrays.asList(unreachableCommit)); + } + + @Test + public void validateUnreachableCommitWithoutBitmaps() + throws PackProtocolException, IOException { + if (!isUnreachableCommitValid()) { + thrown.expect(TransportException.class); + thrown.expectMessage(Matchers.containsString( + "want " + unreachableCommit.name() + " not valid")); + + } + createValidator().checkWants(getUploadPack(getRepoWithoutBitmaps()), + Arrays.asList(unreachableCommit)); + } + + @Test + public void validateReachableBlobWithBitmaps() + throws PackProtocolException, IOException { + if (!isReachableBlobValid_withBitmaps()) { + thrown.expect(TransportException.class); + thrown.expectMessage(Matchers.containsString( + "want " + reachableBlob.name() + " not valid")); + } + createValidator().checkWants(getUploadPack(getRepoWithBitmaps()), + Arrays.asList(reachableBlob)); + } + + @Test + public void validateReachableBlobWithoutBitmaps() + throws PackProtocolException, IOException { + if (!isReachableBlobValid_withoutBitmaps()) { + thrown.expect(TransportException.class); + thrown.expectMessage(Matchers.containsString( + "want " + reachableBlob.name() + " not valid")); + } + createValidator().checkWants(getUploadPack(getRepoWithoutBitmaps()), + Arrays.asList(reachableBlob)); + } + + @Test + public void validateUnreachableBlobWithBitmaps() + throws PackProtocolException, IOException { + if (!isUnreachableBlobValid()) { + thrown.expect(TransportException.class); + thrown.expectMessage(Matchers.containsString( + "want " + unreachableBlob.name() + " not valid")); + } + createValidator().checkWants(getUploadPack(getRepoWithBitmaps()), + Arrays.asList(unreachableBlob)); + } + + @Test + public void validateUnreachableBlobWithoutBitmaps() + throws PackProtocolException, IOException { + if (!isUnreachableBlobValid()) { + thrown.expect(TransportException.class); + thrown.expectMessage(Matchers.containsString( + "want " + unreachableBlob.name() + " not valid")); + } + createValidator().checkWants(getUploadPack(getRepoWithoutBitmaps()), + Arrays.asList(unreachableBlob)); + } + + private UploadPack getUploadPack(Repository repository) throws IOException { + UploadPack uploadPack = new UploadPack(repository); + + Ref advertisedRef = repo.getRefDatabase().findRef("advertised"); + Map<String, Ref> advertisedRefs = new HashMap<>(); + advertisedRefs.put(advertisedRef.getName(), advertisedRef); + + uploadPack.setAdvertisedRefs(advertisedRefs); + return uploadPack; + } + + private Repository getRepoWithBitmaps() throws IOException { + new DfsGarbageCollector(repo).pack(null); + repo.scanForRepoChanges(); + return repo; + } + + private Repository getRepoWithoutBitmaps() { + return repo; + } +} diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/TipRequestValidatorTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/TipRequestValidatorTest.java new file mode 100644 index 0000000000..565d0e6e95 --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/TipRequestValidatorTest.java @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2019, Google LLC. + * 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.transport; + +import org.eclipse.jgit.transport.UploadPack.RequestValidator; + +/** + * Client may ask for objects that are the tip of any reference, even if not + * advertised. + */ +public class TipRequestValidatorTest extends RequestValidatorTestCase { + + @Override + protected RequestValidator createValidator() { + return new UploadPack.TipRequestValidator(); + } + + @Override + protected boolean isReachableCommitValid() { + return false; + } + + @Override + protected boolean isUnreachableCommitValid() { + return false; + } + + @Override + protected boolean isReachableBlobValid_withBitmaps() { + return false; + } + + @Override + protected boolean isReachableBlobValid_withoutBitmaps() { + return false; + } + + @Override + protected boolean isUnreachableBlobValid() { + return false; + } + + @Override + protected boolean isAdvertisedTipValid() { + return true; + } + + @Override + protected boolean isUnadvertisedTipCommitValid() { + return true; + } + +} diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/UploadPackReachabilityTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/UploadPackReachabilityTest.java new file mode 100644 index 0000000000..7122082d81 --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/UploadPackReachabilityTest.java @@ -0,0 +1,316 @@ +/* + * Copyright (C) 2019, Google LLC. + * 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.transport; + +import static org.eclipse.jgit.lib.MoreAsserts.assertThrows; +import static org.hamcrest.Matchers.containsString; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; + +import java.util.Collections; + +import org.eclipse.jgit.errors.TransportException; +import org.eclipse.jgit.internal.storage.dfs.DfsGarbageCollector; +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.NullProgressMonitor; +import org.eclipse.jgit.lib.Repository; +import org.eclipse.jgit.revwalk.RevBlob; +import org.eclipse.jgit.revwalk.RevCommit; +import org.eclipse.jgit.transport.UploadPack.RequestPolicy; +import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException; +import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException; +import org.eclipse.jgit.transport.resolver.UploadPackFactory; +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +/** + * Test combinations of: + * <ul> + * <li>Fetch a blob or a commit</li> + * <li>Fetched object is reachable or not</li> + * <li>With and without bitmaps</li> + * </ul> + */ +public class UploadPackReachabilityTest { + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + private URIish uri; + + private TestProtocol<Object> testProtocol; + + private Object ctx = new Object(); + + private InMemoryRepository server; + + private InMemoryRepository client; + + private TestRepository<InMemoryRepository> remote; + + @Before + public void setUp() throws Exception { + server = newRepo("server"); + client = newRepo("client"); + + remote = new TestRepository<>(server); + } + + @After + public void tearDown() { + Transport.unregister(testProtocol); + } + + @Test + public void testFetchUnreachableBlobWithBitmap() throws Exception { + RevBlob blob = remote.blob("foo"); + remote.commit(remote.tree(remote.file("foo", blob))); + generateBitmaps(server); + + testProtocol = generateReachableCommitUploadPackProtocol(); + uri = testProtocol.register(ctx, server); + + assertFalse(client.getObjectDatabase().has(blob.toObjectId())); + + try (Transport tn = testProtocol.open(uri, client, "server")) { + TransportException e = assertThrows(TransportException.class, + () -> tn.fetch(NullProgressMonitor.INSTANCE, Collections + .singletonList(new RefSpec(blob.name())))); + assertThat(e.getMessage(), + containsString("want " + blob.name() + " not valid")); + } + } + + @Test + public void testFetchReachableBlobWithoutBitmap() throws Exception { + RevBlob blob = remote.blob("foo"); + RevCommit commit = remote.commit(remote.tree(remote.file("foo", blob))); + remote.update("master", commit); + + testProtocol = generateReachableCommitUploadPackProtocol(); + uri = testProtocol.register(ctx, server); + + assertFalse(client.getObjectDatabase().has(blob.toObjectId())); + + try (Transport tn = testProtocol.open(uri, client, "server")) { + TransportException e = assertThrows(TransportException.class, + () -> tn.fetch(NullProgressMonitor.INSTANCE, Collections + .singletonList(new RefSpec(blob.name())))); + assertThat(e.getMessage(), + containsString( + "want " + blob.name() + " not valid")); + } + } + + @Test + public void testFetchReachableBlobWithoutBitmapButFilterAllowed() throws Exception { + InMemoryRepository server2 = newRepo("server2"); + try (TestRepository<InMemoryRepository> remote2 = new TestRepository<>( + server2)) { + RevBlob blob = remote2.blob("foo"); + RevCommit commit = remote2.commit(remote2.tree(remote2.file("foo", blob))); + remote2.update("master", commit); + + server2.getConfig().setBoolean("uploadpack", null, "allowfilter", + true); + + testProtocol = new TestProtocol<>((Object req, Repository db) -> { + UploadPack up = new UploadPack(db); + up.setRequestPolicy(RequestPolicy.REACHABLE_COMMIT); + return up; + }, null); + uri = testProtocol.register(ctx, server2); + + assertFalse(client.getObjectDatabase().has(blob.toObjectId())); + + try (Transport tn = testProtocol.open(uri, client, "server2")) { + tn.fetch(NullProgressMonitor.INSTANCE, + Collections.singletonList(new RefSpec(blob.name()))); + assertTrue(client.getObjectDatabase().has(blob.toObjectId())); + } + } + } + + @Test + public void testFetchUnreachableBlobWithoutBitmap() throws Exception { + RevBlob blob = remote.blob("foo"); + remote.commit(remote.tree(remote.file("foo", blob))); + + testProtocol = generateReachableCommitUploadPackProtocol(); + uri = testProtocol.register(ctx, server); + + assertFalse(client.getObjectDatabase().has(blob.toObjectId())); + + try (Transport tn = testProtocol.open(uri, client, "server")) { + TransportException e = assertThrows(TransportException.class, () -> + tn.fetch(NullProgressMonitor.INSTANCE, + Collections.singletonList(new RefSpec(blob.name())))); + assertThat(e.getMessage(), + containsString("want " + blob.name() + " not valid")); + } + } + + @Test + public void testFetchReachableBlobWithBitmap() throws Exception { + RevBlob blob = remote.blob("foo"); + RevCommit commit = remote.commit(remote.tree(remote.file("foo", blob))); + remote.update("master", commit); + generateBitmaps(server); + + testProtocol = generateReachableCommitUploadPackProtocol(); + uri = testProtocol.register(ctx, server); + + assertFalse(client.getObjectDatabase().has(blob.toObjectId())); + + try (Transport tn = testProtocol.open(uri, client, "server")) { + tn.fetch(NullProgressMonitor.INSTANCE, + Collections.singletonList(new RefSpec(blob.name()))); + assertTrue(client.getObjectDatabase().has(blob.toObjectId())); + } + } + + @Test + public void testFetchReachableCommitWithBitmap() throws Exception { + RevCommit commit = remote + .commit(remote.tree(remote.file("foo", remote.blob("foo")))); + remote.update("master", commit); + generateBitmaps(server); + + testProtocol = generateReachableCommitUploadPackProtocol(); + uri = testProtocol.register(ctx, server); + + assertFalse(client.getObjectDatabase().has(commit.toObjectId())); + + try (Transport tn = testProtocol.open(uri, client, "server")) { + tn.fetch(NullProgressMonitor.INSTANCE, + Collections.singletonList(new RefSpec(commit.name()))); + assertTrue(client.getObjectDatabase().has(commit.toObjectId())); + } + } + + @Test + public void testFetchReachableCommitWithoutBitmap() throws Exception { + RevCommit commit = remote + .commit(remote.tree(remote.file("foo", remote.blob("foo")))); + remote.update("master", commit); + generateBitmaps(server); + + testProtocol = generateReachableCommitUploadPackProtocol(); + uri = testProtocol.register(ctx, server); + + assertFalse(client.getObjectDatabase().has(commit.toObjectId())); + + try (Transport tn = testProtocol.open(uri, client, "server")) { + tn.fetch(NullProgressMonitor.INSTANCE, + Collections.singletonList(new RefSpec(commit.name()))); + assertTrue(client.getObjectDatabase().has(commit.toObjectId())); + } + } + + @Test + public void testFetchUnreachableCommitWithBitmap() throws Exception { + RevCommit commit = remote + .commit(remote.tree(remote.file("foo", remote.blob("foo")))); + generateBitmaps(server); + + testProtocol = generateReachableCommitUploadPackProtocol(); + uri = testProtocol.register(ctx, server); + + assertFalse(client.getObjectDatabase().has(commit.toObjectId())); + + try (Transport tn = testProtocol.open(uri, client, "server")) { + TransportException e = assertThrows(TransportException.class, + () -> tn.fetch(NullProgressMonitor.INSTANCE, + Collections.singletonList(new RefSpec(commit.name())))); + assertThat(e.getMessage(), + containsString("want " + commit.name() + " not valid")); + } + } + + @Test + public void testFetchUnreachableCommitWithoutBitmap() throws Exception { + RevCommit commit = remote + .commit(remote.tree(remote.file("foo", remote.blob("foo")))); + + testProtocol = generateReachableCommitUploadPackProtocol(); + uri = testProtocol.register(ctx, server); + + assertFalse(client.getObjectDatabase().has(commit.toObjectId())); + + try (Transport tn = testProtocol.open(uri, client, "server")) { + TransportException e = assertThrows(TransportException.class, + () -> tn.fetch(NullProgressMonitor.INSTANCE, Collections + .singletonList(new RefSpec(commit.name())))); + assertThat(e.getMessage(), + containsString("want " + commit.name() + " not valid")); + } + } + + private static InMemoryRepository newRepo(String name) { + return new InMemoryRepository(new DfsRepositoryDescription(name)); + } + + private void generateBitmaps(InMemoryRepository repo) throws Exception { + new DfsGarbageCollector(repo).pack(null); + repo.scanForRepoChanges(); + } + + private static TestProtocol<Object> generateReachableCommitUploadPackProtocol() { + return new TestProtocol<>(new UploadPackFactory<Object>() { + @Override + public UploadPack create(Object req, Repository db) + throws ServiceNotEnabledException, + ServiceNotAuthorizedException { + UploadPack up = new UploadPack(db); + up.setRequestPolicy(RequestPolicy.REACHABLE_COMMIT); + return up; + } + }, null); + } +} diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/UploadPackRefSortingForReachabilityTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/UploadPackRefSortingForReachabilityTest.java new file mode 100644 index 0000000000..0875a33287 --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/UploadPackRefSortingForReachabilityTest.java @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2019, Google LLC. + * 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.transport; + +import static org.hamcrest.Matchers.contains; +import static org.junit.Assert.assertThat; + +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import org.eclipse.jgit.lib.ObjectId; +import org.eclipse.jgit.lib.ObjectIdRef.Unpeeled; +import org.eclipse.jgit.lib.Ref; +import org.eclipse.jgit.lib.Ref.Storage; +import org.junit.Test; + +public class UploadPackRefSortingForReachabilityTest { + + @Test + public void sortReferences() { + List<Ref> refs = Stream.of("refs/changes/12/12", "refs/changes/12/1", + "refs/heads/master", "refs/heads/something", + "refs/changes/55/1", "refs/tags/v1.1") + .map(s -> new Unpeeled(Storage.LOOSE, s, ObjectId.zeroId())) + .collect(Collectors.toList()); + Stream<Ref> sorted = UploadPack.importantRefsFirst(refs); + List<String> collected = sorted.map(Ref::getName) + .collect(Collectors.toList()); + assertThat(collected, + contains("refs/heads/master", "refs/heads/something", + "refs/tags/v1.1", "refs/changes/12/12", + "refs/changes/12/1", "refs/changes/55/1")); + } +} diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/UploadPackTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/UploadPackTest.java index 528a63f9c0..108e5edb78 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/UploadPackTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/UploadPackTest.java @@ -98,14 +98,6 @@ public class UploadPackTest { repo.scanForRepoChanges(); } - private static TestProtocol<Object> generateReachableCommitUploadPackProtocol() { - return new TestProtocol<>((Object req, Repository db) -> { - UploadPack up = new UploadPack(db); - up.setRequestPolicy(RequestPolicy.REACHABLE_COMMIT); - return up; - }, null); - } - @Test public void testFetchParentOfShallowCommit() throws Exception { RevCommit commit0 = remote.commit().message("0").create(); @@ -134,95 +126,6 @@ public class UploadPackTest { } @Test - public void testFetchUnreachableBlobWithBitmap() throws Exception { - RevBlob blob = remote.blob("foo"); - remote.commit(remote.tree(remote.file("foo", blob))); - generateBitmaps(server); - - testProtocol = generateReachableCommitUploadPackProtocol(); - uri = testProtocol.register(ctx, server); - - assertFalse(client.getObjectDatabase().has(blob.toObjectId())); - - try (Transport tn = testProtocol.open(uri, client, "server")) { - TransportException e = assertThrows(TransportException.class, - () -> tn.fetch(NullProgressMonitor.INSTANCE, Collections - .singletonList(new RefSpec(blob.name())))); - assertThat(e.getMessage(), - containsString("want " + blob.name() + " not valid")); - } - } - - @Test - public void testFetchReachableBlobWithBitmap() throws Exception { - RevBlob blob = remote.blob("foo"); - RevCommit commit = remote.commit(remote.tree(remote.file("foo", blob))); - remote.update("master", commit); - generateBitmaps(server); - - testProtocol = generateReachableCommitUploadPackProtocol(); - uri = testProtocol.register(ctx, server); - - assertFalse(client.getObjectDatabase().has(blob.toObjectId())); - - try (Transport tn = testProtocol.open(uri, client, "server")) { - tn.fetch(NullProgressMonitor.INSTANCE, - Collections.singletonList(new RefSpec(blob.name()))); - assertTrue(client.getObjectDatabase().has(blob.toObjectId())); - } - } - - @Test - public void testFetchReachableBlobWithoutBitmap() throws Exception { - RevBlob blob = remote.blob("foo"); - RevCommit commit = remote.commit(remote.tree(remote.file("foo", blob))); - remote.update("master", commit); - - testProtocol = generateReachableCommitUploadPackProtocol(); - uri = testProtocol.register(ctx, server); - - assertFalse(client.getObjectDatabase().has(blob.toObjectId())); - - try (Transport tn = testProtocol.open(uri, client, "server")) { - TransportException e = assertThrows(TransportException.class, - () -> tn.fetch(NullProgressMonitor.INSTANCE, Collections - .singletonList(new RefSpec(blob.name())))); - assertThat(e.getMessage(), - containsString( - "want " + blob.name() + " not valid")); - } - } - - @Test - public void testFetchReachableBlobWithoutBitmapButFilterAllowed() throws Exception { - InMemoryRepository server2 = newRepo("server2"); - try (TestRepository<InMemoryRepository> remote2 = new TestRepository<>( - server2)) { - RevBlob blob = remote2.blob("foo"); - RevCommit commit = remote2.commit(remote2.tree(remote2.file("foo", blob))); - remote2.update("master", commit); - - server2.getConfig().setBoolean("uploadpack", null, "allowfilter", - true); - - testProtocol = new TestProtocol<>((Object req, Repository db) -> { - UploadPack up = new UploadPack(db); - up.setRequestPolicy(RequestPolicy.REACHABLE_COMMIT); - return up; - }, null); - uri = testProtocol.register(ctx, server2); - - assertFalse(client.getObjectDatabase().has(blob.toObjectId())); - - try (Transport tn = testProtocol.open(uri, client, "server2")) { - tn.fetch(NullProgressMonitor.INSTANCE, - Collections.singletonList(new RefSpec(blob.name()))); - assertTrue(client.getObjectDatabase().has(blob.toObjectId())); - } - } - } - - @Test public void testFetchWithBlobNoneFilter() throws Exception { InMemoryRepository server2 = newRepo("server2"); try (TestRepository<InMemoryRepository> remote2 = new TestRepository<>( @@ -559,7 +462,9 @@ public class UploadPackTest { assertThat(lines, containsInAnyOrder("ls-refs", "fetch", "server-option")); } - private void checkUnadvertisedIfUnallowed(String fetchCapability) throws Exception { + private void checkUnadvertisedIfUnallowed(String configSection, + String configName, String fetchCapability) throws Exception { + server.getConfig().setBoolean(configSection, null, configName, false); ByteArrayInputStream recvStream = uploadPackV2Setup(null, PacketLineIn.end()); PacketLineIn pckIn = new PacketLineIn(recvStream); @@ -570,9 +475,9 @@ public class UploadPackTest { String line; while (!PacketLineIn.isEnd((line = pckIn.readString()))) { if (line.startsWith("fetch=")) { - assertThat( - Arrays.asList(line.substring(6).split(" ")), - hasItems("shallow")); + List<String> fetchItems = Arrays.asList(line.substring(6).split(" ")); + assertThat(fetchItems, hasItems("shallow")); + assertFalse(fetchItems.contains(fetchCapability)); lines.add("fetch"); } else { lines.add(line); @@ -584,7 +489,7 @@ public class UploadPackTest { @Test public void testV2CapabilitiesAllowFilter() throws Exception { checkAdvertisedIfAllowed("uploadpack", "allowfilter", "filter"); - checkUnadvertisedIfUnallowed("filter"); + checkUnadvertisedIfUnallowed("uploadpack", "allowfilter", "filter"); } @Test @@ -594,13 +499,18 @@ public class UploadPackTest { @Test public void testV2CapabilitiesRefInWantNotAdvertisedIfUnallowed() throws Exception { - checkUnadvertisedIfUnallowed("ref-in-want"); + checkUnadvertisedIfUnallowed("uploadpack", "allowrefinwant", + "ref-in-want"); } @Test - public void testV2CapabilitiesAllowSidebandAll() throws Exception { - checkAdvertisedIfAllowed("uploadpack", "allowsidebandall", "sideband-all"); - checkUnadvertisedIfUnallowed("sideband-all"); + public void testV2CapabilitiesAdvertiseSidebandAll() throws Exception { + server.getConfig().setBoolean("uploadpack", null, "allowsidebandall", + true); + checkAdvertisedIfAllowed("uploadpack", "advertisesidebandall", + "sideband-all"); + checkUnadvertisedIfUnallowed("uploadpack", "advertisesidebandall", + "sideband-all"); } @Test @@ -2112,12 +2022,12 @@ public class UploadPackTest { ByteArrayInputStream recvStream = uploadPackV2( "command=fetch\n", - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "sideband-all\n", "want " + fooChild.toObjectId().getName() + "\n", "want " + barChild.toObjectId().getName() + "\n", "have " + fooParent.toObjectId().getName() + "\n", - PacketLineIn.END); + PacketLineIn.end()); PacketLineIn pckIn = new PacketLineIn(recvStream); assertThat(pckIn.readString(), is("\001acknowledgments")); @@ -2133,11 +2043,11 @@ public class UploadPackTest { server.getConfig().setBoolean("uploadpack", null, "allowsidebandall", true); ByteArrayInputStream recvStream = uploadPackV2("command=fetch\n", - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "want " + commit.getName() + "\n", "sideband-all\n", "done\n", - PacketLineIn.END); + PacketLineIn.end()); PacketLineIn pckIn = new PacketLineIn(recvStream); String s; @@ -2174,18 +2084,18 @@ public class UploadPackTest { assertThat(protocolsSupported, hasItems("https")); if (!protocolsSupported.contains("https")) return null; - return new PackInfo("myhash", "myuri"); + return new PackInfo("myhash", "myuri", 100); } }); }, "command=fetch\n", - PacketLineIn.DELIM, + PacketLineIn.delimiter(), "want " + commit2.getName() + "\n", "sideband-all\n", "packfile-uris https\n", "done\n", - PacketLineIn.END); + PacketLineIn.end()); PacketLineIn pckIn = new PacketLineIn(recvStream); String s; diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/WalkEncryptionTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/WalkEncryptionTest.java index 4750d15b3d..d1d7a1d81d 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/WalkEncryptionTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/WalkEncryptionTest.java @@ -239,9 +239,8 @@ public class WalkEncryptionTest { loadEnvVar(ENV_SECRET_KEY, SECRET_KEY, props); loadEnvVar(ENV_BUCKET_NAME, TEST_BUCKET, props); return props; - } else { - return null; } + return null; } static Properties fromEnvFile() throws Exception { @@ -250,12 +249,10 @@ public class WalkEncryptionTest { props.load(new FileInputStream(ENV_CONFIG_FILE)); if (checkTestProps(props)) { return props; - } else { - throw new Error("Environment config file is incomplete."); } - } else { - return null; + throw new Error("Environment config file is incomplete."); } + return null; } static Properties fromSysProps() { @@ -266,9 +263,8 @@ public class WalkEncryptionTest { loadSysProp(SYS_SECRET_KEY, SECRET_KEY, props); loadSysProp(SYS_BUCKET_NAME, TEST_BUCKET, props); return props; - } else { - return null; } + return null; } static Properties fromSysFile() throws Exception { @@ -277,12 +273,10 @@ public class WalkEncryptionTest { props.load(new FileInputStream(SYS_CONFIG_FILE)); if (checkTestProps(props)) { return props; - } else { - throw new Error("System props config file is incomplete."); } - } else { - return null; + throw new Error("System props config file is incomplete."); } + return null; } static Properties fromConfigFile(String path) throws Exception { @@ -292,12 +286,10 @@ public class WalkEncryptionTest { props.load(new FileInputStream(file)); if (checkTestProps(props)) { return props; - } else { - throw new Error("Props config file is incomplete: " + path); } - } else { - return null; + throw new Error("Props config file is incomplete: " + path); } + return null; } /** diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/EmptyTreeIteratorTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/EmptyTreeIteratorTest.java index 58aa608ff5..4deb188784 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/EmptyTreeIteratorTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/EmptyTreeIteratorTest.java @@ -65,12 +65,13 @@ public class EmptyTreeIteratorTest extends RepositoryTestCase { @Test public void testCreateSubtreeIterator() throws Exception { final EmptyTreeIterator etp = new EmptyTreeIterator(); - final ObjectReader reader = db.newObjectReader(); - final AbstractTreeIterator sub = etp.createSubtreeIterator(reader); - assertNotNull(sub); - assertTrue(sub.first()); - assertTrue(sub.eof()); - assertTrue(sub instanceof EmptyTreeIterator); + try (ObjectReader reader = db.newObjectReader()) { + final AbstractTreeIterator sub = etp.createSubtreeIterator(reader); + assertNotNull(sub); + assertTrue(sub.first()); + assertTrue(sub.eof()); + assertTrue(sub instanceof EmptyTreeIterator); + } } @Test @@ -121,8 +122,9 @@ public class EmptyTreeIteratorTest extends RepositoryTestCase { called[0] = true; } }; - final ObjectReader reader = db.newObjectReader(); - parent.createSubtreeIterator(reader).stopWalk(); + try (ObjectReader reader = db.newObjectReader()) { + parent.createSubtreeIterator(reader).stopWalk(); + } assertTrue(called[0]); } } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/FileTreeIteratorTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/FileTreeIteratorTest.java index a3ce4ae94f..ffa6e5d252 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/FileTreeIteratorTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/FileTreeIteratorTest.java @@ -217,29 +217,29 @@ public class FileTreeIteratorTest extends RepositoryTestCase { assertFalse(top.eof()); assertEquals(FileMode.TREE.getBits(), top.mode); - final ObjectReader reader = db.newObjectReader(); - final AbstractTreeIterator sub = top.createSubtreeIterator(reader); - assertTrue(sub instanceof FileTreeIterator); - final FileTreeIterator subfti = (FileTreeIterator) sub; - assertTrue(sub.first()); - assertFalse(sub.eof()); - assertEquals(paths[2], nameOf(sub)); - assertEquals(paths[2].length(), subfti.getEntryLength()); - assertEquals(mtime[2], subfti.getEntryLastModifiedInstant()); - - sub.next(1); - assertTrue(sub.eof()); - - top.next(1); - assertFalse(top.first()); - assertFalse(top.eof()); - assertEquals(FileMode.REGULAR_FILE.getBits(), top.mode); - assertEquals(paths[3], nameOf(top)); - assertEquals(paths[3].length(), top.getEntryLength()); - assertEquals(mtime[3], top.getEntryLastModifiedInstant()); - - top.next(1); - assertTrue(top.eof()); + try (ObjectReader reader = db.newObjectReader()) { + final AbstractTreeIterator sub = top.createSubtreeIterator(reader); + assertTrue(sub instanceof FileTreeIterator); + final FileTreeIterator subfti = (FileTreeIterator) sub; + assertTrue(sub.first()); + assertFalse(sub.eof()); + assertEquals(paths[2], nameOf(sub)); + assertEquals(paths[2].length(), subfti.getEntryLength()); + assertEquals(mtime[2], subfti.getEntryLastModifiedInstant()); + + sub.next(1); + assertTrue(sub.eof()); + top.next(1); + assertFalse(top.first()); + assertFalse(top.eof()); + assertEquals(FileMode.REGULAR_FILE.getBits(), top.mode); + assertEquals(paths[3], nameOf(top)); + assertEquals(paths[3].length(), top.getEntryLength()); + assertEquals(mtime[3], top.getEntryLastModifiedInstant()); + + top.next(1); + assertTrue(top.eof()); + } } @Test @@ -272,22 +272,23 @@ public class FileTreeIteratorTest extends RepositoryTestCase { git.add().addFilepattern("file").call(); } DirCacheEntry dce = db.readDirCache().getEntry("file"); - TreeWalk tw = new TreeWalk(db); - FileTreeIterator fti = new FileTreeIterator(trash, db.getFS(), db - .getConfig().get(WorkingTreeOptions.KEY)); - tw.addTree(fti); - DirCacheIterator dci = new DirCacheIterator(db.readDirCache()); - tw.addTree(dci); - fti.setDirCacheIterator(tw, 1); - while (tw.next() && !tw.getPathString().equals("file")) { - // - } - assertEquals(MetadataDiff.EQUAL, fti.compareMetadata(dce)); - ObjectId fromRaw = ObjectId.fromRaw(fti.idBuffer(), fti.idOffset()); - assertEquals("6b584e8ece562ebffc15d38808cd6b98fc3d97ea", - fromRaw.getName()); - try (ObjectReader objectReader = db.newObjectReader()) { - assertFalse(fti.isModified(dce, false, objectReader)); + try (TreeWalk tw = new TreeWalk(db)) { + FileTreeIterator fti = new FileTreeIterator(trash, db.getFS(), + db.getConfig().get(WorkingTreeOptions.KEY)); + tw.addTree(fti); + DirCacheIterator dci = new DirCacheIterator(db.readDirCache()); + tw.addTree(dci); + fti.setDirCacheIterator(tw, 1); + while (tw.next() && !tw.getPathString().equals("file")) { + // + } + assertEquals(MetadataDiff.EQUAL, fti.compareMetadata(dce)); + ObjectId fromRaw = ObjectId.fromRaw(fti.idBuffer(), fti.idOffset()); + assertEquals("6b584e8ece562ebffc15d38808cd6b98fc3d97ea", + fromRaw.getName()); + try (ObjectReader objectReader = db.newObjectReader()) { + assertFalse(fti.isModified(dce, false, objectReader)); + } } } @@ -624,9 +625,8 @@ public class FileTreeIteratorTest extends RepositoryTestCase { @Test public void testCustomFileModeStrategy() throws Exception { - Repository nestedRepo = createNestedRepo(); - - try (Git git = new Git(nestedRepo)) { + try (Repository nestedRepo = createNestedRepo(); + Git git = new Git(nestedRepo)) { // validate that our custom strategy is honored WorkingTreeIterator customIterator = new FileTreeIterator( nestedRepo, NO_GITLINKS_STRATEGY); @@ -641,9 +641,8 @@ public class FileTreeIteratorTest extends RepositoryTestCase { @Test public void testCustomFileModeStrategyFromParentIterator() throws Exception { - Repository nestedRepo = createNestedRepo(); - - try (Git git = new Git(nestedRepo)) { + try (Repository nestedRepo = createNestedRepo(); + Git git = new Git(nestedRepo)) { FileTreeIterator customIterator = new FileTreeIterator(nestedRepo, NO_GITLINKS_STRATEGY); File r = new File(nestedRepo.getWorkTree(), "sub"); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/NameConflictTreeWalkTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/NameConflictTreeWalkTest.java index 54c217276d..e6a5322374 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/NameConflictTreeWalkTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/NameConflictTreeWalkTest.java @@ -84,16 +84,17 @@ public class NameConflictTreeWalkTest extends RepositoryTestCase { assertEquals(1, tree1.getEntryCount()); } - final TreeWalk tw = new TreeWalk(db); - tw.addTree(new DirCacheIterator(tree0)); - tw.addTree(new DirCacheIterator(tree1)); - - assertModes("a", REGULAR_FILE, MISSING, tw); - assertModes("a.b", EXECUTABLE_FILE, MISSING, tw); - assertModes("a", MISSING, TREE, tw); - tw.enterSubtree(); - assertModes("a/b", MISSING, REGULAR_FILE, tw); - assertModes("a0b", SYMLINK, MISSING, tw); + try (TreeWalk tw = new TreeWalk(db)) { + tw.addTree(new DirCacheIterator(tree0)); + tw.addTree(new DirCacheIterator(tree1)); + + assertModes("a", REGULAR_FILE, MISSING, tw); + assertModes("a.b", EXECUTABLE_FILE, MISSING, tw); + assertModes("a", MISSING, TREE, tw); + tw.enterSubtree(); + assertModes("a/b", MISSING, REGULAR_FILE, tw); + assertModes("a0b", SYMLINK, MISSING, tw); + } } @Test @@ -115,20 +116,21 @@ public class NameConflictTreeWalkTest extends RepositoryTestCase { assertEquals(1, tree1.getEntryCount()); } - final NameConflictTreeWalk tw = new NameConflictTreeWalk(db); - tw.addTree(new DirCacheIterator(tree0)); - tw.addTree(new DirCacheIterator(tree1)); - - assertModes("a", REGULAR_FILE, TREE, tw); - assertTrue(tw.isDirectoryFileConflict()); - assertTrue(tw.isSubtree()); - tw.enterSubtree(); - assertModes("a/b", MISSING, REGULAR_FILE, tw); - assertTrue(tw.isDirectoryFileConflict()); - assertModes("a.b", EXECUTABLE_FILE, MISSING, tw); - assertFalse(tw.isDirectoryFileConflict()); - assertModes("a0b", SYMLINK, MISSING, tw); - assertFalse(tw.isDirectoryFileConflict()); + try (NameConflictTreeWalk tw = new NameConflictTreeWalk(db)) { + tw.addTree(new DirCacheIterator(tree0)); + tw.addTree(new DirCacheIterator(tree1)); + + assertModes("a", REGULAR_FILE, TREE, tw); + assertTrue(tw.isDirectoryFileConflict()); + assertTrue(tw.isSubtree()); + tw.enterSubtree(); + assertModes("a/b", MISSING, REGULAR_FILE, tw); + assertTrue(tw.isDirectoryFileConflict()); + assertModes("a.b", EXECUTABLE_FILE, MISSING, tw); + assertFalse(tw.isDirectoryFileConflict()); + assertModes("a0b", SYMLINK, MISSING, tw); + assertFalse(tw.isDirectoryFileConflict()); + } } @Test @@ -151,20 +153,21 @@ public class NameConflictTreeWalkTest extends RepositoryTestCase { assertEquals(2, tree1.getEntryCount()); } - final NameConflictTreeWalk tw = new NameConflictTreeWalk(db); - tw.addTree(new DirCacheIterator(tree0)); - tw.addTree(new DirCacheIterator(tree1)); - - assertModes("a", REGULAR_FILE, TREE, tw); - assertTrue(tw.isSubtree()); - assertTrue(tw.isDirectoryFileConflict()); - tw.enterSubtree(); - assertModes("a/b", MISSING, REGULAR_FILE, tw); - assertTrue(tw.isDirectoryFileConflict()); - assertModes("a.b", EXECUTABLE_FILE, EXECUTABLE_FILE, tw); - assertFalse(tw.isDirectoryFileConflict()); - assertModes("a0b", SYMLINK, MISSING, tw); - assertFalse(tw.isDirectoryFileConflict()); + try (NameConflictTreeWalk tw = new NameConflictTreeWalk(db)) { + tw.addTree(new DirCacheIterator(tree0)); + tw.addTree(new DirCacheIterator(tree1)); + + assertModes("a", REGULAR_FILE, TREE, tw); + assertTrue(tw.isSubtree()); + assertTrue(tw.isDirectoryFileConflict()); + tw.enterSubtree(); + assertModes("a/b", MISSING, REGULAR_FILE, tw); + assertTrue(tw.isDirectoryFileConflict()); + assertModes("a.b", EXECUTABLE_FILE, EXECUTABLE_FILE, tw); + assertFalse(tw.isDirectoryFileConflict()); + assertModes("a0b", SYMLINK, MISSING, tw); + assertFalse(tw.isDirectoryFileConflict()); + } } @Test @@ -187,20 +190,21 @@ public class NameConflictTreeWalkTest extends RepositoryTestCase { assertEquals(3, tree1.getEntryCount()); } - final NameConflictTreeWalk tw = new NameConflictTreeWalk(db); - tw.addTree(new DirCacheIterator(tree0)); - tw.addTree(new DirCacheIterator(tree1)); - - assertModes("a", REGULAR_FILE, TREE, tw); - assertTrue(tw.isSubtree()); - assertTrue(tw.isDirectoryFileConflict()); - tw.enterSubtree(); - assertModes("a/b", MISSING, REGULAR_FILE, tw); - assertTrue(tw.isDirectoryFileConflict()); - assertModes("a.b", MISSING, EXECUTABLE_FILE, tw); - assertFalse(tw.isDirectoryFileConflict()); - assertModes("a0b", SYMLINK, SYMLINK, tw); - assertFalse(tw.isDirectoryFileConflict()); + try (NameConflictTreeWalk tw = new NameConflictTreeWalk(db)) { + tw.addTree(new DirCacheIterator(tree0)); + tw.addTree(new DirCacheIterator(tree1)); + + assertModes("a", REGULAR_FILE, TREE, tw); + assertTrue(tw.isSubtree()); + assertTrue(tw.isDirectoryFileConflict()); + tw.enterSubtree(); + assertModes("a/b", MISSING, REGULAR_FILE, tw); + assertTrue(tw.isDirectoryFileConflict()); + assertModes("a.b", MISSING, EXECUTABLE_FILE, tw); + assertFalse(tw.isDirectoryFileConflict()); + assertModes("a0b", SYMLINK, SYMLINK, tw); + assertFalse(tw.isDirectoryFileConflict()); + } } @Test @@ -224,26 +228,27 @@ public class NameConflictTreeWalkTest extends RepositoryTestCase { assertEquals(4, tree1.getEntryCount()); } - final NameConflictTreeWalk tw = new NameConflictTreeWalk(db); - tw.addTree(new DirCacheIterator(tree0)); - tw.addTree(new DirCacheIterator(tree1)); - - assertModes("0", REGULAR_FILE, REGULAR_FILE, tw); - assertFalse(tw.isDirectoryFileConflict()); - assertModes("a", REGULAR_FILE, TREE, tw); - assertTrue(tw.isSubtree()); - assertTrue(tw.isDirectoryFileConflict()); - tw.enterSubtree(); - assertModes("a/b", MISSING, REGULAR_FILE, tw); - assertTrue(tw.isDirectoryFileConflict()); - assertModes("a/c", MISSING, TREE, tw); - assertTrue(tw.isDirectoryFileConflict()); - tw.enterSubtree(); - assertModes("a/c/e", MISSING, REGULAR_FILE, tw); - assertTrue(tw.isDirectoryFileConflict()); - - assertModes("a.b", MISSING, REGULAR_FILE, tw); - assertFalse(tw.isDirectoryFileConflict()); + try (NameConflictTreeWalk tw = new NameConflictTreeWalk(db)) { + tw.addTree(new DirCacheIterator(tree0)); + tw.addTree(new DirCacheIterator(tree1)); + + assertModes("0", REGULAR_FILE, REGULAR_FILE, tw); + assertFalse(tw.isDirectoryFileConflict()); + assertModes("a", REGULAR_FILE, TREE, tw); + assertTrue(tw.isSubtree()); + assertTrue(tw.isDirectoryFileConflict()); + tw.enterSubtree(); + assertModes("a/b", MISSING, REGULAR_FILE, tw); + assertTrue(tw.isDirectoryFileConflict()); + assertModes("a/c", MISSING, TREE, tw); + assertTrue(tw.isDirectoryFileConflict()); + tw.enterSubtree(); + assertModes("a/c/e", MISSING, REGULAR_FILE, tw); + assertTrue(tw.isDirectoryFileConflict()); + + assertModes("a.b", MISSING, REGULAR_FILE, tw); + assertFalse(tw.isDirectoryFileConflict()); + } } private static void assertModes(final String path, final FileMode mode0, diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/filter/IndexDiffFilterTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/filter/IndexDiffFilterTest.java index 2f797e361a..964ffcaa83 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/filter/IndexDiffFilterTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/filter/IndexDiffFilterTest.java @@ -101,13 +101,14 @@ public class IndexDiffFilterTest extends RepositoryTestCase { RevCommit commit = writeFileInFolderAndCommit(); deleteAll(); writeFileWithFolderName(); - TreeWalk treeWalk = createTreeWalk(commit); - assertTrue(treeWalk.next()); - assertEquals("folder", treeWalk.getPathString()); - assertTrue(treeWalk.next()); - assertEquals("folder/file", treeWalk.getPathString()); - assertFalse(treeWalk.next()); + try (TreeWalk treeWalk = createTreeWalk(commit)) { + assertTrue(treeWalk.next()); + assertEquals("folder", treeWalk.getPathString()); + assertTrue(treeWalk.next()); + assertEquals("folder/file", treeWalk.getPathString()); + assertFalse(treeWalk.next()); + } } @Test @@ -115,24 +116,26 @@ public class IndexDiffFilterTest extends RepositoryTestCase { RevCommit commit = writeFileInFolderAndCommit(); deleteAll(); writeFileWithFolderName(); - TreeWalk treeWalk = createNonRecursiveTreeWalk(commit); - - assertTrue(treeWalk.next()); - assertEquals("folder", treeWalk.getPathString()); - assertTrue(treeWalk.next()); - assertEquals("folder", treeWalk.getPathString()); - assertTrue(treeWalk.isSubtree()); - treeWalk.enterSubtree(); - assertTrue(treeWalk.next()); - assertEquals("folder/file", treeWalk.getPathString()); - assertFalse(treeWalk.next()); + + try (TreeWalk treeWalk = createNonRecursiveTreeWalk(commit)) { + assertTrue(treeWalk.next()); + assertEquals("folder", treeWalk.getPathString()); + assertTrue(treeWalk.next()); + assertEquals("folder", treeWalk.getPathString()); + assertTrue(treeWalk.isSubtree()); + treeWalk.enterSubtree(); + assertTrue(treeWalk.next()); + assertEquals("folder/file", treeWalk.getPathString()); + assertFalse(treeWalk.next()); + } } @Test public void testFileCommitted() throws Exception { RevCommit commit = writeFileAndCommit(); - TreeWalk treeWalk = createTreeWalk(commit); - assertFalse(treeWalk.next()); + try (TreeWalk treeWalk = createTreeWalk(commit)) { + assertFalse(treeWalk.next()); + } } @Test @@ -153,89 +156,100 @@ public class IndexDiffFilterTest extends RepositoryTestCase { "<<<<<<< HEAD\nside\n=======\nmaster\n>>>>>>> master\n"); writeTrashFile(FILE, "master"); - TreeWalk treeWalk = createTreeWalk(side); - int count = 0; - while (treeWalk.next()) - count++; - assertEquals(2, count); + try (TreeWalk treeWalk = createTreeWalk(side)) { + int count = 0; + while (treeWalk.next()) + count++; + assertEquals(2, count); + } } @Test public void testFileInFolderCommitted() throws Exception { RevCommit commit = writeFileInFolderAndCommit(); - TreeWalk treeWalk = createTreeWalk(commit); - assertFalse(treeWalk.next()); + try (TreeWalk treeWalk = createTreeWalk(commit)) { + assertFalse(treeWalk.next()); + } } @Test public void testEmptyFolderCommitted() throws Exception { RevCommit commit = createEmptyFolderAndCommit(); - TreeWalk treeWalk = createTreeWalk(commit); - assertFalse(treeWalk.next()); + try (TreeWalk treeWalk = createTreeWalk(commit)) { + assertFalse(treeWalk.next()); + } } @Test public void testFileCommittedChangedNotModified() throws Exception { RevCommit commit = writeFileAndCommit(); writeFile(); - TreeWalk treeWalk = createTreeWalk(commit); - assertFalse(treeWalk.next()); + try (TreeWalk treeWalk = createTreeWalk(commit)) { + assertFalse(treeWalk.next()); + } } @Test public void testFileInFolderCommittedChangedNotModified() throws Exception { RevCommit commit = writeFileInFolderAndCommit(); writeFileInFolder(); - TreeWalk treeWalk = createTreeWalk(commit); - assertFalse(treeWalk.next()); + try (TreeWalk treeWalk = createTreeWalk(commit)) { + assertFalse(treeWalk.next()); + } } @Test public void testFileCommittedModified() throws Exception { RevCommit commit = writeFileAndCommit(); writeFileModified(); - TreeWalk treeWalk = createTreeWalk(commit); - assertPaths(treeWalk, FILE); + try (TreeWalk treeWalk = createTreeWalk(commit)) { + assertPaths(treeWalk, FILE); + } } @Test public void testFileInFolderCommittedModified() throws Exception { RevCommit commit = writeFileInFolderAndCommit(); writeFileInFolderModified(); - TreeWalk treeWalk = createTreeWalk(commit); - assertPaths(treeWalk, FILE_IN_FOLDER); + try (TreeWalk treeWalk = createTreeWalk(commit)) { + assertPaths(treeWalk, FILE_IN_FOLDER); + } } @Test public void testFileCommittedDeleted() throws Exception { RevCommit commit = writeFileAndCommit(); deleteFile(); - TreeWalk treeWalk = createTreeWalk(commit); - assertPaths(treeWalk, FILE); + try (TreeWalk treeWalk = createTreeWalk(commit)) { + assertPaths(treeWalk, FILE); + } } @Test public void testFileInFolderCommittedDeleted() throws Exception { RevCommit commit = writeFileInFolderAndCommit(); deleteFileInFolder(); - TreeWalk treeWalk = createTreeWalk(commit); - assertPaths(treeWalk, FILE_IN_FOLDER); + try (TreeWalk treeWalk = createTreeWalk(commit)) { + assertPaths(treeWalk, FILE_IN_FOLDER); + } } @Test public void testFileInFolderCommittedAllDeleted() throws Exception { RevCommit commit = writeFileInFolderAndCommit(); deleteAll(); - TreeWalk treeWalk = createTreeWalk(commit); - assertPaths(treeWalk, FILE_IN_FOLDER); + try (TreeWalk treeWalk = createTreeWalk(commit)) { + assertPaths(treeWalk, FILE_IN_FOLDER); + } } @Test public void testEmptyFolderCommittedDeleted() throws Exception { RevCommit commit = createEmptyFolderAndCommit(); deleteFolder(); - TreeWalk treeWalk = createTreeWalk(commit); - assertFalse(treeWalk.next()); + try (TreeWalk treeWalk = createTreeWalk(commit)) { + assertFalse(treeWalk.next()); + } } @Test @@ -243,8 +257,9 @@ public class IndexDiffFilterTest extends RepositoryTestCase { throws Exception { RevCommit commit = writeFileAndCommit(); writeFileModifiedAndCommit(); - TreeWalk treeWalk = createTreeWalk(commit); - assertPaths(treeWalk, FILE); + try (TreeWalk treeWalk = createTreeWalk(commit)) { + assertPaths(treeWalk, FILE); + } } @Test @@ -252,8 +267,9 @@ public class IndexDiffFilterTest extends RepositoryTestCase { throws Exception { RevCommit commit = writeFileInFolderAndCommit(); writeFileInFolderModifiedAndCommit(); - TreeWalk treeWalk = createTreeWalk(commit); - assertPaths(treeWalk, FILE_IN_FOLDER); + try (TreeWalk treeWalk = createTreeWalk(commit)) { + assertPaths(treeWalk, FILE_IN_FOLDER); + } } @Test @@ -261,8 +277,9 @@ public class IndexDiffFilterTest extends RepositoryTestCase { throws Exception { RevCommit commit = writeFileAndCommit(); deleteFileAndCommit(); - TreeWalk treeWalk = createTreeWalk(commit); - assertPaths(treeWalk, FILE); + try (TreeWalk treeWalk = createTreeWalk(commit)) { + assertPaths(treeWalk, FILE); + } } @Test @@ -270,8 +287,9 @@ public class IndexDiffFilterTest extends RepositoryTestCase { throws Exception { RevCommit commit = writeFileInFolderAndCommit(); deleteFileInFolderAndCommit(); - TreeWalk treeWalk = createTreeWalk(commit); - assertPaths(treeWalk, FILE_IN_FOLDER); + try (TreeWalk treeWalk = createTreeWalk(commit)) { + assertPaths(treeWalk, FILE_IN_FOLDER); + } } @Test @@ -279,8 +297,9 @@ public class IndexDiffFilterTest extends RepositoryTestCase { throws Exception { RevCommit commit = writeFileInFolderAndCommit(); deleteAllAndCommit(); - TreeWalk treeWalk = createTreeWalk(commit); - assertPaths(treeWalk, FILE_IN_FOLDER); + try (TreeWalk treeWalk = createTreeWalk(commit)) { + assertPaths(treeWalk, FILE_IN_FOLDER); + } } @Test @@ -288,96 +307,108 @@ public class IndexDiffFilterTest extends RepositoryTestCase { throws Exception { RevCommit commit = createEmptyFolderAndCommit(); deleteFolderAndCommit(); - TreeWalk treeWalk = createTreeWalk(commit); - assertFalse(treeWalk.next()); + try (TreeWalk treeWalk = createTreeWalk(commit)) { + assertFalse(treeWalk.next()); + } } @Test public void testFileUntracked() throws Exception { RevCommit commit = writeFileAndCommit(); writeFileUntracked(); - TreeWalk treeWalk = createTreeWalk(commit); - assertPaths(treeWalk, UNTRACKED_FILE); + try (TreeWalk treeWalk = createTreeWalk(commit)) { + assertPaths(treeWalk, UNTRACKED_FILE); + } } @Test public void testFileInFolderUntracked() throws Exception { RevCommit commit = writeFileInFolderAndCommit(); writeFileInFolderUntracked(); - TreeWalk treeWalk = createTreeWalk(commit); - assertPaths(treeWalk, UNTRACKED_FILE_IN_FOLDER); + try (TreeWalk treeWalk = createTreeWalk(commit)) { + assertPaths(treeWalk, UNTRACKED_FILE_IN_FOLDER); + } } @Test public void testEmptyFolderUntracked() throws Exception { RevCommit commit = createEmptyFolderAndCommit(); createEmptyFolderUntracked(); - TreeWalk treeWalk = createTreeWalk(commit); - assertFalse(treeWalk.next()); + try (TreeWalk treeWalk = createTreeWalk(commit)) { + assertFalse(treeWalk.next()); + } } @Test public void testFileIgnored() throws Exception { RevCommit commit = writeFileAndCommit(); writeFileIgnored(); - TreeWalk treeWalk = createTreeWalk(commit); - assertFalse(treeWalk.next()); + try (TreeWalk treeWalk = createTreeWalk(commit)) { + assertFalse(treeWalk.next()); + } } @Test public void testFileInFolderIgnored() throws Exception { RevCommit commit = writeFileInFolderAndCommit(); writeFileInFolderIgnored(); - TreeWalk treeWalk = createTreeWalk(commit); - assertFalse(treeWalk.next()); + try (TreeWalk treeWalk = createTreeWalk(commit)) { + assertFalse(treeWalk.next()); + } } @Test public void testFileInFolderAllIgnored() throws Exception { RevCommit commit = writeFileInFolderAndCommit(); writeFileInFolderAllIgnored(); - TreeWalk treeWalk = createTreeWalk(commit); - assertFalse(treeWalk.next()); + try (TreeWalk treeWalk = createTreeWalk(commit)) { + assertFalse(treeWalk.next()); + } } @Test public void testEmptyFolderIgnored() throws Exception { RevCommit commit = createEmptyFolderAndCommit(); createEmptyFolderIgnored(); - TreeWalk treeWalk = createTreeWalk(commit); - assertFalse(treeWalk.next()); + try (TreeWalk treeWalk = createTreeWalk(commit)) { + assertFalse(treeWalk.next()); + } } @Test public void testFileIgnoredNotHonored() throws Exception { RevCommit commit = writeFileAndCommit(); writeFileIgnored(); - TreeWalk treeWalk = createTreeWalkDishonorIgnores(commit); - assertPaths(treeWalk, IGNORED_FILE, GITIGNORE); + try (TreeWalk treeWalk = createTreeWalkDishonorIgnores(commit)) { + assertPaths(treeWalk, IGNORED_FILE, GITIGNORE); + } } @Test public void testFileCommittedModifiedIgnored() throws Exception { RevCommit commit = writeFileAndCommit(); writeFileModifiedIgnored(); - TreeWalk treeWalk = createTreeWalk(commit); - assertPaths(treeWalk, FILE); + try (TreeWalk treeWalk = createTreeWalk(commit)) { + assertPaths(treeWalk, FILE); + } } @Test public void testFileInFolderCommittedModifiedIgnored() throws Exception { RevCommit commit = writeFileInFolderAndCommit(); writeFileInFolderModifiedIgnored(); - TreeWalk treeWalk = createTreeWalk(commit); - assertPaths(treeWalk, FILE_IN_FOLDER); + try (TreeWalk treeWalk = createTreeWalk(commit)) { + assertPaths(treeWalk, FILE_IN_FOLDER); + } } @Test public void testFileInFolderCommittedModifiedAllIgnored() throws Exception { RevCommit commit = writeFileInFolderAndCommit(); writeFileInFolderModifiedAllIgnored(); - TreeWalk treeWalk = createTreeWalk(commit); - assertPaths(treeWalk, FILE_IN_FOLDER); + try (TreeWalk treeWalk = createTreeWalk(commit)) { + assertPaths(treeWalk, FILE_IN_FOLDER); + } } @Test @@ -386,8 +417,9 @@ public class IndexDiffFilterTest extends RepositoryTestCase { RevCommit commit = writeFileAndCommit(); deleteFileAndCommit(); rewriteFileIgnored(); - TreeWalk treeWalk = createTreeWalk(commit); - assertPaths(treeWalk, FILE); + try (TreeWalk treeWalk = createTreeWalk(commit)) { + assertPaths(treeWalk, FILE); + } } @Test @@ -396,8 +428,9 @@ public class IndexDiffFilterTest extends RepositoryTestCase { RevCommit commit = writeFileInFolderAndCommit(); deleteFileInFolderAndCommit(); rewriteFileInFolderIgnored(); - TreeWalk treeWalk = createTreeWalk(commit); - assertPaths(treeWalk, FILE_IN_FOLDER); + try (TreeWalk treeWalk = createTreeWalk(commit)) { + assertPaths(treeWalk, FILE_IN_FOLDER); + } } @Test @@ -406,8 +439,9 @@ public class IndexDiffFilterTest extends RepositoryTestCase { RevCommit commit = writeFileInFolderAndCommit(); deleteAllAndCommit(); rewriteFileInFolderAllIgnored(); - TreeWalk treeWalk = createTreeWalk(commit); - assertPaths(treeWalk, FILE_IN_FOLDER); + try (TreeWalk treeWalk = createTreeWalk(commit)) { + assertPaths(treeWalk, FILE_IN_FOLDER); + } } @Test @@ -416,15 +450,17 @@ public class IndexDiffFilterTest extends RepositoryTestCase { RevCommit commit = createEmptyFolderAndCommit(); deleteFolderAndCommit(); recreateEmptyFolderIgnored(); - TreeWalk treeWalk = createTreeWalk(commit); - assertFalse(treeWalk.next()); + try (TreeWalk treeWalk = createTreeWalk(commit)) { + assertFalse(treeWalk.next()); + } } @Test public void testFileInFolderCommittedNonRecursive() throws Exception { RevCommit commit = writeFileInFolderAndCommit(); - TreeWalk treeWalk = createNonRecursiveTreeWalk(commit); - assertPaths(treeWalk, FOLDER); + try (TreeWalk treeWalk = createNonRecursiveTreeWalk(commit)) { + assertPaths(treeWalk, FOLDER); + } } @Test @@ -432,8 +468,9 @@ public class IndexDiffFilterTest extends RepositoryTestCase { RevCommit commit = writeFileInFolderAndCommit(); deleteAll(); writeFileWithFolderName(); - TreeWalk treeWalk = createTreeWalk(commit); - assertPaths(treeWalk, FOLDER, FILE_IN_FOLDER); + try (TreeWalk treeWalk = createTreeWalk(commit)) { + assertPaths(treeWalk, FOLDER, FILE_IN_FOLDER); + } } @Test @@ -442,8 +479,9 @@ public class IndexDiffFilterTest extends RepositoryTestCase { RevCommit commit = writeFileInFolderAndCommit(); deleteAll(); writeFileWithFolderNameAndCommit(); - TreeWalk treeWalk = createTreeWalk(commit); - assertPaths(treeWalk, FOLDER, FILE_IN_FOLDER); + try (TreeWalk treeWalk = createTreeWalk(commit)) { + assertPaths(treeWalk, FOLDER, FILE_IN_FOLDER); + } } private void writeFile() throws Exception { diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/FSTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/FSTest.java index 89a2fc44c7..c9a339352b 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/FSTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/FSTest.java @@ -254,7 +254,9 @@ public class FSTest { formatter.format(t1.toInstant()), Long.valueOf(resolutionNs)), t2.compareTo(t1) > 0); } finally { - Files.delete(f); + if (f != null) { + Files.delete(f); + } } } } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/HookTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/HookTest.java index e5fcbf9d7c..70a2dbbfe8 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/HookTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/HookTest.java @@ -58,6 +58,8 @@ import org.eclipse.jgit.hooks.PostCommitHook; import org.eclipse.jgit.hooks.PreCommitHook; import org.eclipse.jgit.junit.JGitTestUtil; import org.eclipse.jgit.junit.RepositoryTestCase; +import org.eclipse.jgit.lib.ConfigConstants; +import org.eclipse.jgit.lib.StoredConfig; import org.eclipse.jgit.revwalk.RevCommit; import org.junit.Assume; import org.junit.Test; @@ -221,6 +223,75 @@ public class HookTest extends RepositoryTestCase { } @Test + public void testRunHookHooksPathRelative() throws Exception { + assumeSupportedPlatform(); + + writeHookFile(PreCommitHook.NAME, + "#!/bin/sh\necho \"Wrong hook $1 $2\"\nread INPUT\necho $INPUT\n" + + "echo $GIT_DIR\necho $GIT_WORK_TREE\necho 1>&2 \"stderr\""); + writeHookFile("../../" + PreCommitHook.NAME, + "#!/bin/sh\necho \"test $1 $2\"\nread INPUT\necho $INPUT\n" + + "echo $GIT_DIR\necho $GIT_WORK_TREE\necho 1>&2 \"stderr\""); + StoredConfig cfg = db.getConfig(); + cfg.load(); + cfg.setString(ConfigConstants.CONFIG_CORE_SECTION, null, + ConfigConstants.CONFIG_KEY_HOOKS_PATH, "."); + cfg.save(); + try (ByteArrayOutputStream out = new ByteArrayOutputStream(); + ByteArrayOutputStream err = new ByteArrayOutputStream()) { + ProcessResult res = FS.DETECTED.runHookIfPresent(db, + PreCommitHook.NAME, new String[] { "arg1", "arg2" }, + new PrintStream(out), new PrintStream(err), "stdin"); + + assertEquals("unexpected hook output", + "test arg1 arg2\nstdin\n" + + db.getDirectory().getAbsolutePath() + '\n' + + db.getWorkTree().getAbsolutePath() + '\n', + out.toString("UTF-8")); + assertEquals("unexpected output on stderr stream", "stderr\n", + err.toString("UTF-8")); + assertEquals("unexpected exit code", 0, res.getExitCode()); + assertEquals("unexpected process status", ProcessResult.Status.OK, + res.getStatus()); + } + } + + @Test + public void testRunHookHooksPathAbsolute() throws Exception { + assumeSupportedPlatform(); + + writeHookFile(PreCommitHook.NAME, + "#!/bin/sh\necho \"Wrong hook $1 $2\"\nread INPUT\necho $INPUT\n" + + "echo $GIT_DIR\necho $GIT_WORK_TREE\necho 1>&2 \"stderr\""); + writeHookFile("../../" + PreCommitHook.NAME, + "#!/bin/sh\necho \"test $1 $2\"\nread INPUT\necho $INPUT\n" + + "echo $GIT_DIR\necho $GIT_WORK_TREE\necho 1>&2 \"stderr\""); + StoredConfig cfg = db.getConfig(); + cfg.load(); + cfg.setString(ConfigConstants.CONFIG_CORE_SECTION, null, + ConfigConstants.CONFIG_KEY_HOOKS_PATH, + db.getWorkTree().getAbsolutePath()); + cfg.save(); + try (ByteArrayOutputStream out = new ByteArrayOutputStream(); + ByteArrayOutputStream err = new ByteArrayOutputStream()) { + ProcessResult res = FS.DETECTED.runHookIfPresent(db, + PreCommitHook.NAME, new String[] { "arg1", "arg2" }, + new PrintStream(out), new PrintStream(err), "stdin"); + + assertEquals("unexpected hook output", + "test arg1 arg2\nstdin\n" + + db.getDirectory().getAbsolutePath() + '\n' + + db.getWorkTree().getAbsolutePath() + '\n', + out.toString("UTF-8")); + assertEquals("unexpected output on stderr stream", "stderr\n", + err.toString("UTF-8")); + assertEquals("unexpected exit code", 0, res.getExitCode()); + assertEquals("unexpected process status", ProcessResult.Status.OK, + res.getStatus()); + } + } + + @Test public void testFailedPreCommitHookBlockCommit() throws Exception { assumeSupportedPlatform(); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/HttpSupportTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/HttpSupportTest.java new file mode 100644 index 0000000000..cbe4eb2eb0 --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/HttpSupportTest.java @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2019, Thomas Wolf <thomas.wolf@paranor.ch> and others + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0 which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +package org.eclipse.jgit.util; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.net.Proxy; +import java.net.ProxySelector; +import java.net.SocketAddress; +import java.net.URI; +import java.net.URL; +import java.util.Collections; +import java.util.List; + +import org.junit.Test; + +public class HttpSupportTest { + + private static class TestProxySelector extends ProxySelector { + + private static final Proxy DUMMY = new Proxy(Proxy.Type.HTTP, + InetSocketAddress.createUnresolved("localhost", 0)); + + @Override + public List<Proxy> select(URI uri) { + if ("http".equals(uri.getScheme()) + && "somehost".equals(uri.getHost())) { + return Collections.singletonList(DUMMY); + } + return Collections.singletonList(Proxy.NO_PROXY); + } + + @Override + public void connectFailed(URI uri, SocketAddress sa, IOException ioe) { + // Empty + } + } + + @Test + public void testMalformedUri() throws Exception { + // Valid URL, but backslash is not allowed in a URI in the userinfo part + // per RFC 3986: https://tools.ietf.org/html/rfc3986#section-3.2.1 . + // Test that conversion to URI to call the ProxySelector does not throw + // an exception. + Proxy proxy = HttpSupport.proxyFor(new TestProxySelector(), new URL( + "http://infor\\c.jones@somehost/somewhere/someproject.git")); + assertNotNull(proxy); + assertEquals(Proxy.Type.HTTP, proxy.type()); + } + + @Test + public void testCorrectUri() throws Exception { + // Backslash escaped as %5C is correct. + Proxy proxy = HttpSupport.proxyFor(new TestProxySelector(), new URL( + "http://infor%5Cc.jones@somehost/somewhere/someproject.git")); + assertNotNull(proxy); + assertEquals(Proxy.Type.HTTP, proxy.type()); + } +} diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/QuotedStringGitPathStyleTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/QuotedStringGitPathStyleTest.java index 9a0c96e171..c09b136ca6 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/QuotedStringGitPathStyleTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/QuotedStringGitPathStyleTest.java @@ -45,6 +45,7 @@ package org.eclipse.jgit.util; import static java.nio.charset.StandardCharsets.ISO_8859_1; import static org.eclipse.jgit.util.QuotedString.GIT_PATH; +import static org.eclipse.jgit.util.QuotedString.GIT_PATH_MINIMAL; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotSame; @@ -67,6 +68,12 @@ public class QuotedStringGitPathStyleTest { assertEquals(exp, r); } + private static void assertDequoteMinimal(String exp, String in) { + final byte[] b = ('"' + in + '"').getBytes(ISO_8859_1); + final String r = GIT_PATH_MINIMAL.dequote(b, 0, b.length); + assertEquals(exp, r); + } + @Test public void testQuote_Empty() { assertEquals("\"\"", GIT_PATH.quote("")); @@ -206,4 +213,75 @@ public class QuotedStringGitPathStyleTest { assertSame("abc@2x.png", GIT_PATH.quote("abc@2x.png")); assertDequote("abc@2x.png", "abc\\1002x.png"); } + + @Test + public void testNoQuote() { + assertSame("\u00c5ngstr\u00f6m", + GIT_PATH_MINIMAL.quote("\u00c5ngstr\u00f6m")); + } + + @Test + public void testQuoteMinimal() { + assertEquals("\"\u00c5n\\\\str\u00f6m\"", + GIT_PATH_MINIMAL.quote("\u00c5n\\str\u00f6m")); + } + + @Test + public void testDequoteMinimal() { + assertEquals("\u00c5n\\str\u00f6m", GIT_PATH_MINIMAL + .dequote(GIT_PATH_MINIMAL.quote("\u00c5n\\str\u00f6m"))); + + } + + @Test + public void testRoundtripMinimal() { + assertEquals("\u00c5ngstr\u00f6m", GIT_PATH_MINIMAL + .dequote(GIT_PATH_MINIMAL.quote("\u00c5ngstr\u00f6m"))); + + } + + @Test + public void testQuoteMinimalDequoteNormal() { + assertEquals("\u00c5n\\str\u00f6m", GIT_PATH + .dequote(GIT_PATH_MINIMAL.quote("\u00c5n\\str\u00f6m"))); + + } + + @Test + public void testQuoteNormalDequoteMinimal() { + assertEquals("\u00c5n\\str\u00f6m", GIT_PATH_MINIMAL + .dequote(GIT_PATH.quote("\u00c5n\\str\u00f6m"))); + + } + + @Test + public void testRoundtripMinimalDequoteNormal() { + assertEquals("\u00c5ngstr\u00f6m", + GIT_PATH.dequote(GIT_PATH_MINIMAL.quote("\u00c5ngstr\u00f6m"))); + + } + + @Test + public void testRoundtripNormalDequoteMinimal() { + assertEquals("\u00c5ngstr\u00f6m", + GIT_PATH_MINIMAL.dequote(GIT_PATH.quote("\u00c5ngstr\u00f6m"))); + + } + + @Test + public void testDequote_UTF8_Minimal() { + assertDequoteMinimal("\u00c5ngstr\u00f6m", + "\\303\\205ngstr\\303\\266m"); + } + + @Test + public void testDequote_RawUTF8_Minimal() { + assertDequoteMinimal("\u00c5ngstr\u00f6m", "\303\205ngstr\303\266m"); + } + + @Test + public void testDequote_RawLatin1_Minimal() { + assertDequoteMinimal("\u00c5ngstr\u00f6m", "\305ngstr\366m"); + } + } |