diff --git a/org.eclipse.jgit.http.apache/src/org/eclipse/jgit/transport/http/apache/HttpClientConnection.java b/org.eclipse.jgit.http.apache/src/org/eclipse/jgit/transport/http/apache/HttpClientConnection.java index b776119e2..d42d6f29e 100644 --- a/org.eclipse.jgit.http.apache/src/org/eclipse/jgit/transport/http/apache/HttpClientConnection.java +++ b/org.eclipse.jgit.http.apache/src/org/eclipse/jgit/transport/http/apache/HttpClientConnection.java @@ -309,19 +309,19 @@ public class HttpClientConnection implements HttpConnection { public void setFixedLengthStreamingMode(int contentLength) { if (entity != null) throw new IllegalArgumentException(); - entity = new TemporaryBufferEntity(new LocalFile()); + entity = new TemporaryBufferEntity(new LocalFile(null)); entity.setContentLength(contentLength); } public OutputStream getOutputStream() throws IOException { if (entity == null) - entity = new TemporaryBufferEntity(new LocalFile()); + entity = new TemporaryBufferEntity(new LocalFile(null)); return entity.getBuffer(); } public void setChunkedStreamingMode(int chunklen) { if (entity == null) - entity = new TemporaryBufferEntity(new LocalFile()); + entity = new TemporaryBufferEntity(new LocalFile(null)); entity.setChunked(true); } diff --git a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/SmartClientSmartServerTest.java b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/SmartClientSmartServerTest.java index bb612b1a6..4e75a5632 100644 --- a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/SmartClientSmartServerTest.java +++ b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/SmartClientSmartServerTest.java @@ -84,6 +84,7 @@ import org.eclipse.jgit.junit.TestRepository; import org.eclipse.jgit.junit.TestRng; import org.eclipse.jgit.junit.http.AccessEvent; import org.eclipse.jgit.junit.http.HttpTestCase; +import org.eclipse.jgit.lib.ConfigConstants; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.NullProgressMonitor; import org.eclipse.jgit.lib.ObjectId; @@ -143,6 +144,10 @@ public class SmartClientSmartServerTest extends HttpTestCase { final TestRepository src = createTestRepository(); final String srcName = src.getRepository().getDirectory().getName(); + src.getRepository() + .getConfig() + .setBoolean(ConfigConstants.CONFIG_CORE_SECTION, null, + ConfigConstants.CONFIG_KEY_LOGALLREFUPDATES, true); ServletContextHandler app = server.addContext("/git"); GitServlet gs = new GitServlet(); diff --git a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/LocalDiskRepositoryTestCase.java b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/LocalDiskRepositoryTestCase.java index 053751f8a..b98db7d18 100644 --- a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/LocalDiskRepositoryTestCase.java +++ b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/LocalDiskRepositoryTestCase.java @@ -265,7 +265,7 @@ public abstract class LocalDiskRepositoryTestCase { File gitdir = createUniqueTestGitDir(bare); FileRepository db = new FileRepository(gitdir); assertFalse(gitdir.exists()); - db.create(); + db.create(bare); toClose.add(db); return db; } diff --git a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/MockSystemReader.java b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/MockSystemReader.java index deca34106..3d21f9f8a 100644 --- a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/MockSystemReader.java +++ b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/MockSystemReader.java @@ -90,6 +90,7 @@ public class MockSystemReader extends SystemReader { init(Constants.GIT_AUTHOR_EMAIL_KEY); init(Constants.GIT_COMMITTER_NAME_KEY); init(Constants.GIT_COMMITTER_EMAIL_KEY); + setProperty(Constants.OS_USER_DIR, "."); userGitConfig = new MockConfig(null, null); systemGitConfig = new MockConfig(null, null); setCurrentPlatform(); diff --git a/org.eclipse.jgit.test/exttst/org/eclipse/jgit/patch/EGitPatchHistoryTest.java b/org.eclipse.jgit.test/exttst/org/eclipse/jgit/patch/EGitPatchHistoryTest.java index dc5821b5c..76930f2b8 100644 --- a/org.eclipse.jgit.test/exttst/org/eclipse/jgit/patch/EGitPatchHistoryTest.java +++ b/org.eclipse.jgit.test/exttst/org/eclipse/jgit/patch/EGitPatchHistoryTest.java @@ -216,7 +216,7 @@ public class EGitPatchHistoryTest { buf.destroy(); } commitId = line.substring("commit ".length()); - buf = new TemporaryBuffer.LocalFile(); + buf = new TemporaryBuffer.LocalFile(null); } else if (buf != null) { buf.write(line.getBytes("ISO-8859-1")); buf.write('\n'); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CheckoutCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CheckoutCommandTest.java index f13fb2026..f7a50dffc 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CheckoutCommandTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CheckoutCommandTest.java @@ -43,8 +43,8 @@ */ package org.eclipse.jgit.api; -import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; @@ -78,6 +78,7 @@ import org.eclipse.jgit.lib.RefUpdate; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.lib.StoredConfig; import org.eclipse.jgit.revwalk.RevCommit; +import org.eclipse.jgit.storage.file.FileBasedConfig; import org.eclipse.jgit.transport.RefSpec; import org.eclipse.jgit.transport.RemoteConfig; import org.eclipse.jgit.transport.URIish; @@ -508,4 +509,49 @@ public class CheckoutCommandTest extends RepositoryTestCase { } } + // TODO: write a faster test which depends less on characteristics of + // underlying filesystem/OS. + @Test + public void testCheckoutAutoCrlfTrue() throws Exception { + int nrOfAutoCrlfTestFiles = 200; + + FileBasedConfig c = db.getConfig(); + c.setString("core", null, "autocrlf", "true"); + c.save(); + + AddCommand add = git.add(); + for (int i = 100; i < 100 + nrOfAutoCrlfTestFiles; i++) { + writeTrashFile("Test_" + i + ".txt", "Hello " + i + + " world\nX\nYU\nJK\n"); + add.addFilepattern("Test_" + i + ".txt"); + } + fsTick(null); + add.call(); + RevCommit c1 = git.commit().setMessage("add some lines").call(); + + add = git.add(); + for (int i = 100; i < 100 + nrOfAutoCrlfTestFiles; i++) { + writeTrashFile("Test_" + i + ".txt", "Hello " + i + + " world\nX\nY\n"); + add.addFilepattern("Test_" + i + ".txt"); + } + fsTick(null); + add.call(); + git.commit().setMessage("add more").call(); + + git.checkout().setName(c1.getName()).call(); + + boolean foundUnsmudged = false; + DirCache dc = db.readDirCache(); + for (int i = 100; i < 100 + nrOfAutoCrlfTestFiles; i++) { + DirCacheEntry entry = dc.getEntry( + "Test_" + i + ".txt"); + if (!entry.isSmudged()) { + foundUnsmudged = true; + assertEquals("unexpected file length in git index", 28, + entry.getLength()); + } + } + org.junit.Assume.assumeTrue(foundUnsmudged); + } } 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 56c120176..ece1b324b 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 @@ -45,6 +45,7 @@ package org.eclipse.jgit.api; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; @@ -58,6 +59,7 @@ import java.util.Map; import org.eclipse.jgit.api.ListBranchCommand.ListMode; import org.eclipse.jgit.api.errors.GitAPIException; import org.eclipse.jgit.api.errors.JGitInternalException; +import org.eclipse.jgit.errors.NoWorkTreeException; import org.eclipse.jgit.junit.RepositoryTestCase; import org.eclipse.jgit.junit.TestRepository; import org.eclipse.jgit.lib.ConfigConstants; @@ -135,6 +137,54 @@ public class CloneCommandTest extends RepositoryTestCase { fetchRefSpec(git2.getRepository())); } + @Test + public void testCloneRepositoryExplicitGitDir() throws IOException, + JGitInternalException, GitAPIException { + File directory = createTempDirectory("testCloneRepository"); + CloneCommand command = Git.cloneRepository(); + command.setDirectory(directory); + command.setGitDir(new File(directory, ".git")); + command.setURI(fileUri()); + Git git2 = command.call(); + assertEquals(directory, git2.getRepository().getWorkTree()); + assertEquals(new File(directory, ".git"), git2.getRepository() + .getDirectory()); + } + + @Test + public void testCloneRepositoryExplicitGitDirNonStd() throws IOException, + JGitInternalException, GitAPIException { + File directory = createTempDirectory("testCloneRepository"); + File gDir = createTempDirectory("testCloneRepository.git"); + CloneCommand command = Git.cloneRepository(); + command.setDirectory(directory); + command.setGitDir(gDir); + command.setURI(fileUri()); + Git git2 = command.call(); + assertEquals(directory, git2.getRepository().getWorkTree()); + assertEquals(gDir, git2.getRepository() + .getDirectory()); + assertTrue(new File(directory, ".git").isFile()); + assertFalse(new File(gDir, ".git").exists()); + } + + @Test + public void testCloneRepositoryExplicitGitDirBare() throws IOException, + JGitInternalException, GitAPIException { + File gDir = createTempDirectory("testCloneRepository.git"); + CloneCommand command = Git.cloneRepository(); + command.setBare(true); + command.setGitDir(gDir); + command.setURI(fileUri()); + Git git2 = command.call(); + try { + assertNull(null, git2.getRepository().getWorkTree()); + fail("Expected NoWorkTreeException"); + } catch (NoWorkTreeException e) { + assertEquals(gDir, git2.getRepository().getDirectory()); + } + } + @Test public void testBareCloneRepository() throws IOException, JGitInternalException, GitAPIException, URISyntaxException { @@ -360,6 +410,18 @@ public class CloneCommandTest extends RepositoryTestCase { assertEquals(SubmoduleStatusType.INITIALIZED, pathStatus.getType()); assertEquals(commit, pathStatus.getHeadId()); assertEquals(commit, pathStatus.getIndexId()); + + SubmoduleWalk walk = SubmoduleWalk.forIndex(git2.getRepository()); + assertTrue(walk.next()); + Repository clonedSub1 = walk.getRepository(); + addRepoToClose(clonedSub1); + 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()); + walk.release(); } @Test @@ -441,10 +503,16 @@ public class CloneCommandTest extends RepositoryTestCase { SubmoduleWalk walk = SubmoduleWalk.forIndex(git2.getRepository()); assertTrue(walk.next()); Repository clonedSub1 = walk.getRepository(); - addRepoToClose(clonedSub1); 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(); + clonedSub1.close(); pathStatus = statuses.get(path); assertNotNull(pathStatus); assertEquals(SubmoduleStatusType.INITIALIZED, pathStatus.getType()); 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 0b523f4f3..1f7140287 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 @@ -205,8 +205,8 @@ public class CommitCommandTest extends RepositoryTestCase { assertEquals(path, generator.getModulesPath()); assertEquals(uri, generator.getConfigUrl()); Repository subModRepo = generator.getRepository(); - addRepoToClose(subModRepo); assertNotNull(subModRepo); + subModRepo.close(); assertEquals(commit, repo.resolve(Constants.HEAD)); RevCommit submoduleCommit = git.commit().setMessage("submodule add") @@ -253,8 +253,8 @@ public class CommitCommandTest extends RepositoryTestCase { assertEquals(path, generator.getModulesPath()); assertEquals(uri, generator.getConfigUrl()); Repository subModRepo = generator.getRepository(); - addRepoToClose(subModRepo); assertNotNull(subModRepo); + subModRepo.close(); assertEquals(commit2, repo.resolve(Constants.HEAD)); RevCommit submoduleAddCommit = git.commit().setMessage("submodule add") diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/InitCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/InitCommandTest.java index 3296717c0..e85022376 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/InitCommandTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/InitCommandTest.java @@ -43,6 +43,7 @@ package org.eclipse.jgit.api; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import java.io.File; @@ -50,8 +51,12 @@ import java.io.IOException; import org.eclipse.jgit.api.errors.GitAPIException; import org.eclipse.jgit.api.errors.JGitInternalException; +import org.eclipse.jgit.errors.NoWorkTreeException; +import org.eclipse.jgit.junit.MockSystemReader; import org.eclipse.jgit.junit.RepositoryTestCase; +import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.Repository; +import org.eclipse.jgit.util.SystemReader; import org.junit.Before; import org.junit.Test; @@ -101,4 +106,109 @@ public class InitCommandTest extends RepositoryTestCase { assertNotNull(repository); assertTrue(repository.isBare()); } + + // non-bare repos where gitDir and directory is set. Same as + // "git init --separate-git-dir /tmp/a /tmp/b" + @Test + public void testInitWithExplicitGitDir() throws IOException, + JGitInternalException, GitAPIException { + File wt = createTempDirectory("testInitRepositoryWT"); + File gitDir = createTempDirectory("testInitRepositoryGIT"); + InitCommand command = new InitCommand(); + command.setDirectory(wt); + command.setGitDir(gitDir); + Repository repository = command.call().getRepository(); + addRepoToClose(repository); + assertNotNull(repository); + assertEqualsFile(wt, repository.getWorkTree()); + assertEqualsFile(gitDir, repository.getDirectory()); + } + + // non-bare repos where only gitDir is set. Same as + // "git init --separate-git-dir /tmp/a" + @Test + public void testInitWithOnlyExplicitGitDir() throws IOException, + JGitInternalException, GitAPIException { + MockSystemReader reader = (MockSystemReader) SystemReader.getInstance(); + reader.setProperty(Constants.OS_USER_DIR, getTemporaryDirectory() + .getAbsolutePath()); + File gitDir = createTempDirectory("testInitRepository/.git"); + InitCommand command = new InitCommand(); + command.setGitDir(gitDir); + Repository repository = command.call().getRepository(); + addRepoToClose(repository); + assertNotNull(repository); + assertEqualsFile(gitDir, repository.getDirectory()); + assertEqualsFile(new File(reader.getProperty("user.dir")), + repository.getWorkTree()); + } + + // Bare repos where gitDir and directory is set will only work if gitDir and + // directory is pointing to same dir. Same as + // "git init --bare --separate-git-dir /tmp/a /tmp/b" + // (works in native git but I guess that's more a bug) + @Test(expected = IllegalStateException.class) + public void testInitBare_DirAndGitDirMustBeEqual() throws IOException, + JGitInternalException, GitAPIException { + File gitDir = createTempDirectory("testInitRepository.git"); + InitCommand command = new InitCommand(); + command.setBare(true); + command.setDirectory(gitDir); + command.setGitDir(new File(gitDir, "..")); + command.call(); + } + + // If neither directory nor gitDir is set in a non-bare repo make sure + // worktree and gitDir are set correctly. Standard case. Same as + // "git init" + @Test + public void testInitWithDefaultsNonBare() throws JGitInternalException, + GitAPIException, IOException { + MockSystemReader reader = (MockSystemReader) SystemReader.getInstance(); + reader.setProperty(Constants.OS_USER_DIR, getTemporaryDirectory() + .getAbsolutePath()); + InitCommand command = new InitCommand(); + command.setBare(false); + Repository repository = command.call().getRepository(); + addRepoToClose(repository); + assertNotNull(repository); + assertEqualsFile(new File(reader.getProperty("user.dir"), ".git"), + repository.getDirectory()); + assertEqualsFile(new File(reader.getProperty("user.dir")), + repository.getWorkTree()); + } + + // If neither directory nor gitDir is set in a bare repo make sure + // worktree and gitDir are set correctly. Standard case. Same as + // "git init --bare" + @Test(expected = NoWorkTreeException.class) + public void testInitWithDefaultsBare() throws JGitInternalException, + GitAPIException, IOException { + MockSystemReader reader = (MockSystemReader) SystemReader.getInstance(); + reader.setProperty(Constants.OS_USER_DIR, getTemporaryDirectory() + .getAbsolutePath()); + InitCommand command = new InitCommand(); + command.setBare(true); + Repository repository = command.call().getRepository(); + addRepoToClose(repository); + assertNotNull(repository); + assertEqualsFile(new File(reader.getProperty("user.dir")), + repository.getDirectory()); + assertNull(repository.getWorkTree()); + } + + // In a non-bare repo when directory and gitDir is set then they shouldn't + // point to the same dir. Same as + // "git init --separate-git-dir /tmp/a /tmp/a" + // (works in native git but I guess that's more a bug) + @Test(expected = IllegalStateException.class) + public void testInitNonBare_GitdirAndDirShouldntBeSame() + throws JGitInternalException, GitAPIException, IOException { + File gitDir = createTempDirectory("testInitRepository.git"); + InitCommand command = new InitCommand(); + command.setBare(false); + command.setGitDir(gitDir); + command.setDirectory(gitDir); + command.call().getRepository(); + } } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PathCheckoutCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PathCheckoutCommandTest.java index dbda85285..eb092ad6c 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PathCheckoutCommandTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PathCheckoutCommandTest.java @@ -43,6 +43,7 @@ package org.eclipse.jgit.api; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; import java.io.File; import java.io.IOException; @@ -276,6 +277,39 @@ public class PathCheckoutCommandTest extends RepositoryTestCase { assertStageOneToThree(FILE1); } + @Test + public void testCheckoutOursWhenNoBase() throws Exception { + String file = "added.txt"; + + git.checkout().setCreateBranch(true).setName("side") + .setStartPoint(initialCommit).call(); + writeTrashFile(file, "Added on side"); + git.add().addFilepattern(file).call(); + RevCommit side = git.commit().setMessage("Commit on side").call(); + + git.checkout().setName("master").call(); + writeTrashFile(file, "Added on master"); + git.add().addFilepattern(file).call(); + git.commit().setMessage("Commit on master").call(); + + git.merge().include(side).call(); + assertEquals(RepositoryState.MERGING, db.getRepositoryState()); + + DirCache cache = DirCache.read(db.getIndexFile(), db.getFS()); + assertEquals("Expected add/add file to not have base stage", + DirCacheEntry.STAGE_2, cache.getEntry(file).getStage()); + + assertTrue(read(file).startsWith("<<<<<<< HEAD")); + + git.checkout().setStage(Stage.OURS).addPath(file).call(); + + assertEquals("Added on master", read(file)); + + cache = DirCache.read(db.getIndexFile(), db.getFS()); + assertEquals("Expected conflict stages to still exist after checkout", + DirCacheEntry.STAGE_2, cache.getEntry(file).getStage()); + } + @Test(expected = IllegalStateException.class) public void testStageNotPossibleWithBranch() throws Exception { git.checkout().setStage(Stage.OURS).setStartPoint("master").call(); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheBasicTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheBasicTest.java index 6ac718ec5..0c1baab2b 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheBasicTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheBasicTest.java @@ -47,12 +47,19 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; import java.io.File; +import java.text.MessageFormat; +import org.eclipse.jgit.errors.CorruptObjectException; +import org.eclipse.jgit.internal.JGitText; +import org.eclipse.jgit.junit.MockSystemReader; import org.eclipse.jgit.junit.RepositoryTestCase; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.FileMode; +import org.eclipse.jgit.lib.ObjectInserter; +import org.eclipse.jgit.util.SystemReader; import org.junit.Test; public class DirCacheBasicTest extends RepositoryTestCase { @@ -190,7 +197,7 @@ public class DirCacheBasicTest extends RepositoryTestCase { public void testBuildThenClear() throws Exception { final DirCache dc = db.readDirCache(); - final String[] paths = { "a.", "a.b", "a/b", "a0b" }; + final String[] paths = { "a-", "a.b", "a/b", "a0b" }; final DirCacheEntry[] ents = new DirCacheEntry[paths.length]; for (int i = 0; i < paths.length; i++) { ents[i] = new DirCacheEntry(paths[i]); @@ -234,4 +241,41 @@ public class DirCacheBasicTest extends RepositoryTestCase { final byte[] path = Constants.encode("a"); assertEquals(-1, dc.findEntry(path, path.length)); } + + @Test + public void testRejectInvalidWindowsPaths() throws Exception { + SystemReader.setInstance(new MockSystemReader() { + { + setUnix(); + } + }); + + String path = "src/con.txt"; + DirCache dc = db.lockDirCache(); + DirCacheBuilder b = dc.builder(); + DirCacheEntry e = new DirCacheEntry(path); + e.setFileMode(FileMode.REGULAR_FILE); + e.setObjectId(new ObjectInserter.Formatter().idFor( + Constants.OBJ_BLOB, + Constants.encode(path))); + b.add(e); + b.commit(); + db.readDirCache(); + + SystemReader.setInstance(new MockSystemReader() { + { + setWindows(); + } + }); + + try { + db.readDirCache(); + fail("should have rejected " + path); + } catch (CorruptObjectException err) { + assertEquals(MessageFormat.format(JGitText.get().invalidPath, path), + err.getMessage()); + assertNotNull(err.getCause()); + assertEquals("invalid name 'CON'", err.getCause().getMessage()); + } + } } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheBuilderIteratorTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheBuilderIteratorTest.java index 254431f74..8561fdf35 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheBuilderIteratorTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheBuilderIteratorTest.java @@ -63,7 +63,7 @@ public class DirCacheBuilderIteratorTest extends RepositoryTestCase { final DirCache dc = db.readDirCache(); final FileMode mode = FileMode.REGULAR_FILE; - final String[] paths = { "a.", "a/b", "a/c", "a/d", "a0b" }; + final String[] paths = { "a-", "a/b", "a/c", "a/d", "a0b" }; final DirCacheEntry[] ents = new DirCacheEntry[paths.length]; for (int i = 0; i < paths.length; i++) { ents[i] = new DirCacheEntry(paths[i]); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheBuilderTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheBuilderTest.java index a502db3ac..5408f761d 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheBuilderTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheBuilderTest.java @@ -290,7 +290,7 @@ public class DirCacheBuilderTest extends RepositoryTestCase { public void testAdd_InGitSortOrder() throws Exception { final DirCache dc = db.readDirCache(); - final String[] paths = { "a.", "a.b", "a/b", "a0b" }; + final String[] paths = { "a-", "a.b", "a/b", "a0b" }; final DirCacheEntry[] ents = new DirCacheEntry[paths.length]; for (int i = 0; i < paths.length; i++) { ents[i] = new DirCacheEntry(paths[i]); @@ -315,7 +315,7 @@ public class DirCacheBuilderTest extends RepositoryTestCase { public void testAdd_ReverseGitSortOrder() throws Exception { final DirCache dc = db.readDirCache(); - final String[] paths = { "a.", "a.b", "a/b", "a0b" }; + final String[] paths = { "a-", "a.b", "a/b", "a0b" }; final DirCacheEntry[] ents = new DirCacheEntry[paths.length]; for (int i = 0; i < paths.length; i++) { ents[i] = new DirCacheEntry(paths[i]); @@ -340,7 +340,7 @@ public class DirCacheBuilderTest extends RepositoryTestCase { public void testBuilderClear() throws Exception { final DirCache dc = db.readDirCache(); - final String[] paths = { "a.", "a.b", "a/b", "a0b" }; + final String[] paths = { "a-", "a.b", "a/b", "a0b" }; final DirCacheEntry[] ents = new DirCacheEntry[paths.length]; for (int i = 0; i < paths.length; i++) { ents[i] = new DirCacheEntry(paths[i]); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheCGitCompatabilityTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheCGitCompatabilityTest.java index 53d672d7f..7f58a1cbe 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheCGitCompatabilityTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheCGitCompatabilityTest.java @@ -213,7 +213,7 @@ public class DirCacheCGitCompatabilityTest extends LocalDiskRepositoryTestCase { assertV3TreeEntry(9, "newfile.txt", false, true, dc); final ByteArrayOutputStream bos = new ByteArrayOutputStream(); - dc.writeTo(bos); + dc.writeTo(null, bos); final byte[] indexBytes = bos.toByteArray(); final byte[] expectedBytes = IO.readFully(file); assertArrayEquals(expectedBytes, indexBytes); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheEntryTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheEntryTest.java index 225ce2a90..e159ed939 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheEntryTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheEntryTest.java @@ -49,7 +49,6 @@ import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; -import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.FileMode; import org.eclipse.jgit.lib.ObjectId; import org.junit.Test; @@ -71,7 +70,12 @@ public class DirCacheEntryTest { } private static boolean isValidPath(final String path) { - return DirCacheEntry.isValidPath(Constants.encode(path)); + try { + DirCacheCheckout.checkValidPath(path); + return true; + } catch (InvalidPathException e) { + return false; + } } @Test diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheFindTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheFindTest.java index 0b43b2311..3b8c6ee7b 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheFindTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheFindTest.java @@ -56,7 +56,7 @@ public class DirCacheFindTest extends RepositoryTestCase { public void testEntriesWithin() throws Exception { final DirCache dc = db.readDirCache(); - final String[] paths = { "a.", "a/b", "a/c", "a/d", "a0b" }; + final String[] paths = { "a-", "a/b", "a/c", "a/d", "a0b" }; final DirCacheEntry[] ents = new DirCacheEntry[paths.length]; for (int i = 0; i < paths.length; i++) { ents[i] = new DirCacheEntry(paths[i]); @@ -96,13 +96,13 @@ public class DirCacheFindTest extends RepositoryTestCase { assertSame(ents[i], aContents[i]); } - assertNotNull(dc.getEntriesWithin("a.")); - assertEquals(0, dc.getEntriesWithin("a.").length); + assertNotNull(dc.getEntriesWithin("a-")); + assertEquals(0, dc.getEntriesWithin("a-").length); assertNotNull(dc.getEntriesWithin("a0b")); - assertEquals(0, dc.getEntriesWithin("a0b.").length); + assertEquals(0, dc.getEntriesWithin("a0b-").length); assertNotNull(dc.getEntriesWithin("zoo")); - assertEquals(0, dc.getEntriesWithin("zoo.").length); + assertEquals(0, dc.getEntriesWithin("zoo-").length); } } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheIteratorTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheIteratorTest.java index 8d29a7318..af1c8a356 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheIteratorTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheIteratorTest.java @@ -85,7 +85,7 @@ public class DirCacheIteratorTest extends RepositoryTestCase { public void testNoSubtree_NoTreeWalk() throws Exception { final DirCache dc = DirCache.newInCore(); - final String[] paths = { "a.", "a0b" }; + final String[] paths = { "a-", "a0b" }; final DirCacheEntry[] ents = new DirCacheEntry[paths.length]; for (int i = 0; i < paths.length; i++) { ents[i] = new DirCacheEntry(paths[i]); @@ -111,7 +111,7 @@ public class DirCacheIteratorTest extends RepositoryTestCase { public void testNoSubtree_WithTreeWalk() throws Exception { final DirCache dc = DirCache.newInCore(); - final String[] paths = { "a.", "a0b" }; + final String[] paths = { "a-", "a0b" }; final FileMode[] modes = { FileMode.EXECUTABLE_FILE, FileMode.GITLINK }; final DirCacheEntry[] ents = new DirCacheEntry[paths.length]; for (int i = 0; i < paths.length; i++) { @@ -144,7 +144,7 @@ public class DirCacheIteratorTest extends RepositoryTestCase { public void testSingleSubtree_NoRecursion() throws Exception { final DirCache dc = DirCache.newInCore(); - final String[] paths = { "a.", "a/b", "a/c", "a/d", "a0b" }; + final String[] paths = { "a-", "a/b", "a/c", "a/d", "a0b" }; final DirCacheEntry[] ents = new DirCacheEntry[paths.length]; for (int i = 0; i < paths.length; i++) { ents[i] = new DirCacheEntry(paths[i]); @@ -156,7 +156,7 @@ public class DirCacheIteratorTest extends RepositoryTestCase { b.add(ents[i]); b.finish(); - final String[] expPaths = { "a.", "a", "a0b" }; + final String[] expPaths = { "a-", "a", "a0b" }; final FileMode[] expModes = { FileMode.REGULAR_FILE, FileMode.TREE, FileMode.REGULAR_FILE }; final int expPos[] = { 0, -1, 4 }; @@ -189,7 +189,7 @@ public class DirCacheIteratorTest extends RepositoryTestCase { final DirCache dc = DirCache.newInCore(); final FileMode mode = FileMode.REGULAR_FILE; - final String[] paths = { "a.", "a/b", "a/c", "a/d", "a0b" }; + final String[] paths = { "a-", "a/b", "a/c", "a/d", "a0b" }; final DirCacheEntry[] ents = new DirCacheEntry[paths.length]; for (int i = 0; i < paths.length; i++) { ents[i] = new DirCacheEntry(paths[i]); @@ -224,7 +224,7 @@ public class DirCacheIteratorTest extends RepositoryTestCase { final DirCache dc = DirCache.newInCore(); final FileMode mode = FileMode.REGULAR_FILE; - final String[] paths = { "a.", "a/b", "a/c/e", "a/c/f", "a/d", "a0b" }; + final String[] paths = { "a-", "a/b", "a/c/e", "a/c/f", "a/d", "a0b" }; final DirCacheEntry[] ents = new DirCacheEntry[paths.length]; for (int i = 0; i < paths.length; i++) { ents[i] = new DirCacheEntry(paths[i]); @@ -258,7 +258,7 @@ public class DirCacheIteratorTest extends RepositoryTestCase { final DirCache dc = DirCache.newInCore(); final FileMode mode = FileMode.REGULAR_FILE; - final String[] paths = { "a.", "a/b", "a/c/e", "a/c/f", "a/d", "a0b" }; + final String[] paths = { "a-", "a/b", "a/c/e", "a/c/f", "a/d", "a0b" }; final DirCacheEntry[] ents = new DirCacheEntry[paths.length]; for (int i = 0; i < paths.length; i++) { ents[i] = new DirCacheEntry(paths[i]); @@ -272,7 +272,7 @@ public class DirCacheIteratorTest extends RepositoryTestCase { DirCacheIterator dci = new DirCacheIterator(dc); assertFalse(dci.eof()); - assertEquals("a.", dci.getEntryPathString()); + assertEquals("a-", dci.getEntryPathString()); dci.next(1); assertFalse(dci.eof()); assertEquals("a", dci.getEntryPathString()); @@ -285,7 +285,7 @@ public class DirCacheIteratorTest extends RepositoryTestCase { // same entries the second time dci.reset(); assertFalse(dci.eof()); - assertEquals("a.", dci.getEntryPathString()); + assertEquals("a-", dci.getEntryPathString()); dci.next(1); assertFalse(dci.eof()); assertEquals("a", dci.getEntryPathString()); @@ -304,12 +304,12 @@ public class DirCacheIteratorTest extends RepositoryTestCase { assertEquals("a", dci.getEntryPathString()); dci.back(1); assertFalse(dci.eof()); - assertEquals("a.", dci.getEntryPathString()); + assertEquals("a-", dci.getEntryPathString()); assertTrue(dci.first()); // forward assertFalse(dci.eof()); - assertEquals("a.", dci.getEntryPathString()); + assertEquals("a-", dci.getEntryPathString()); dci.next(1); assertFalse(dci.eof()); assertEquals("a", dci.getEntryPathString()); @@ -385,7 +385,7 @@ public class DirCacheIteratorTest extends RepositoryTestCase { final DirCache dc = DirCache.newInCore(); final FileMode mode = FileMode.REGULAR_FILE; - final String[] paths = { "a.", "a/b", "a/c/e", "a/c/f", "a/d", "a0b" }; + final String[] paths = { "a-", "a/b", "a/c/e", "a/c/f", "a/d", "a0b" }; final DirCacheEntry[] ents = new DirCacheEntry[paths.length]; for (int i = 0; i < paths.length; i++) { ents[i] = new DirCacheEntry(paths[i]); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCachePathEditTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCachePathEditTest.java index 28140f330..63ec85861 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCachePathEditTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCachePathEditTest.java @@ -113,21 +113,23 @@ public class DirCachePathEditTest { DirCache dc = DirCache.newInCore(); DirCacheEditor editor = dc.editor(); editor.add(new AddEdit("a/b")); - editor.add(new AddEdit("a.")); + editor.add(new AddEdit("a-")); editor.add(new AddEdit("ab")); editor.finish(); assertEquals(3, dc.getEntryCount()); + // Validate sort order - assertEquals("a.", dc.getEntry(0).getPathString()); + assertEquals("a-", dc.getEntry(0).getPathString()); assertEquals("a/b", dc.getEntry(1).getPathString()); assertEquals("ab", dc.getEntry(2).getPathString()); editor = dc.editor(); + // Sort order should not confuse DeleteTree editor.add(new DirCacheEditor.DeleteTree("a")); editor.finish(); assertEquals(2, dc.getEntryCount()); - assertEquals("a.", dc.getEntry(0).getPathString()); + assertEquals("a-", dc.getEntry(0).getPathString()); assertEquals("ab", dc.getEntry(1).getPathString()); } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheTreeTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheTreeTest.java index 89d7bed8b..f662e2660 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheTreeTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheTreeTest.java @@ -92,7 +92,7 @@ public class DirCacheTreeTest extends RepositoryTestCase { public void testSingleSubtree() throws Exception { final DirCache dc = db.readDirCache(); - final String[] paths = { "a.", "a/b", "a/c", "a/d", "a0b" }; + final String[] paths = { "a-", "a/b", "a/c", "a/d", "a0b" }; final DirCacheEntry[] ents = new DirCacheEntry[paths.length]; for (int i = 0; i < paths.length; i++) { ents[i] = new DirCacheEntry(paths[i]); @@ -130,7 +130,7 @@ public class DirCacheTreeTest extends RepositoryTestCase { public void testTwoLevelSubtree() throws Exception { final DirCache dc = db.readDirCache(); - final String[] paths = { "a.", "a/b", "a/c/e", "a/c/f", "a/d", "a0b" }; + final String[] paths = { "a-", "a/b", "a/c/e", "a/c/f", "a/d", "a0b" }; final DirCacheEntry[] ents = new DirCacheEntry[paths.length]; for (int i = 0; i < paths.length; i++) { ents[i] = new DirCacheEntry(paths[i]); @@ -190,7 +190,7 @@ public class DirCacheTreeTest extends RepositoryTestCase { final String A = String.format("a%2000s", "a"); final String B = String.format("b%2000s", "b"); - final String[] paths = { A + ".", A + "." + B, A + "/" + B, A + "0" + B }; + final String[] paths = { A + "-", A + "-" + B, A + "/" + B, A + "0" + B }; final DirCacheEntry[] ents = new DirCacheEntry[paths.length]; for (int i = 0; i < paths.length; i++) { ents[i] = new DirCacheEntry(paths[i]); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/gitrepo/RepoCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/gitrepo/RepoCommandTest.java index d24d375cb..3d86cfd5b 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/gitrepo/RepoCommandTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/gitrepo/RepoCommandTest.java @@ -90,24 +90,28 @@ public class RepoCommandTest extends RepositoryTestCase { JGitTestUtil.writeTrashFile(defaultDb, "hello.txt", "master world"); git.add().addFilepattern("hello.txt").call(); git.commit().setMessage("Second commit").call(); + addRepoToClose(defaultDb); notDefaultDb = createWorkRepository(); git = new Git(notDefaultDb); JGitTestUtil.writeTrashFile(notDefaultDb, "world.txt", "hello"); git.add().addFilepattern("world.txt").call(); git.commit().setMessage("Initial commit").call(); + addRepoToClose(notDefaultDb); groupADb = createWorkRepository(); git = new Git(groupADb); JGitTestUtil.writeTrashFile(groupADb, "a.txt", "world"); git.add().addFilepattern("a.txt").call(); git.commit().setMessage("Initial commit").call(); + addRepoToClose(groupADb); groupBDb = createWorkRepository(); git = new Git(groupBDb); JGitTestUtil.writeTrashFile(groupBDb, "b.txt", "world"); git.add().addFilepattern("b.txt").call(); git.commit().setMessage("Initial commit").call(); + addRepoToClose(groupBDb); resolveRelativeUris(); } @@ -239,45 +243,47 @@ public class RepoCommandTest extends RepositoryTestCase { public void testBareRepo() throws Exception { Repository remoteDb = createBareRepository(); Repository tempDb = createWorkRepository(); - StringBuilder xmlContent = new StringBuilder(); - xmlContent.append("\n") - .append("") - .append("") - .append("") - .append("") - .append(""); - JGitTestUtil.writeTrashFile( - tempDb, "manifest.xml", xmlContent.toString()); - RepoCommand command = new RepoCommand(remoteDb); - command - .setPath(tempDb.getWorkTree().getAbsolutePath() + "/manifest.xml") - .setURI(rootUri) - .call(); - // Clone it - File directory = createTempDirectory("testBareRepo"); - Repository localDb = Git - .cloneRepository() - .setDirectory(directory) - .setURI(remoteDb.getDirectory().toURI().toString()) - .call() - .getRepository(); - // The .gitmodules file should exist - File gitmodules = new File(localDb.getWorkTree(), ".gitmodules"); - assertTrue("The .gitmodules file should exist", gitmodules.exists()); - // The first line of .gitmodules file should be expected - BufferedReader reader = new BufferedReader(new FileReader(gitmodules)); - String content = reader.readLine(); - reader.close(); - assertEquals( - "The first line of .gitmodules file should be as expected", - "[submodule \"foo\"]", content); - // The gitlink should be the same as remote head sha1 - String gitlink = localDb.resolve(Constants.HEAD + ":foo").name(); - String remote = defaultDb.resolve(Constants.HEAD).name(); - assertEquals("The gitlink should be the same as remote head", - remote, gitlink); + try { + StringBuilder xmlContent = new StringBuilder(); + xmlContent + .append("\n") + .append("") + .append("") + .append("") + .append("").append(""); + JGitTestUtil.writeTrashFile(tempDb, "manifest.xml", + xmlContent.toString()); + RepoCommand command = new RepoCommand(remoteDb); + command.setPath( + tempDb.getWorkTree().getAbsolutePath() + "/manifest.xml") + .setURI(rootUri).call(); + // Clone it + File directory = createTempDirectory("testBareRepo"); + Repository localDb = Git.cloneRepository().setDirectory(directory) + .setURI(remoteDb.getDirectory().toURI().toString()).call() + .getRepository(); + // The .gitmodules file should exist + File gitmodules = new File(localDb.getWorkTree(), ".gitmodules"); + assertTrue("The .gitmodules file should exist", gitmodules.exists()); + // The first line of .gitmodules file should be expected + BufferedReader reader = new BufferedReader(new FileReader( + gitmodules)); + String content = reader.readLine(); + reader.close(); + assertEquals( + "The first line of .gitmodules file should be as expected", + "[submodule \"foo\"]", content); + // The gitlink should be the same as remote head sha1 + String gitlink = localDb.resolve(Constants.HEAD + ":foo").name(); + localDb.close(); + String remote = defaultDb.resolve(Constants.HEAD).name(); + assertEquals("The gitlink should be the same as remote head", + remote, gitlink); + } finally { + tempDb.close(); + remoteDb.close(); + } } @Test @@ -362,213 +368,213 @@ public class RepoCommandTest extends RepositoryTestCase { public void testRevisionBare() throws Exception { Repository remoteDb = createBareRepository(); Repository tempDb = createWorkRepository(); - StringBuilder xmlContent = new StringBuilder(); - xmlContent.append("\n") - .append("") - .append("") - .append("") - .append("") - .append(""); - JGitTestUtil.writeTrashFile( - tempDb, "manifest.xml", xmlContent.toString()); - RepoCommand command = new RepoCommand(remoteDb); - command - .setPath(tempDb.getWorkTree().getAbsolutePath() + "/manifest.xml") - .setURI(rootUri) - .call(); - // Clone it - File directory = createTempDirectory("testRevisionBare"); - Repository localDb = Git - .cloneRepository() - .setDirectory(directory) - .setURI(remoteDb.getDirectory().toURI().toString()) - .call() - .getRepository(); - // The gitlink should be the same as oldCommitId - String gitlink = localDb.resolve(Constants.HEAD + ":foo").name(); - assertEquals("The gitlink is same as remote head", - oldCommitId.name(), gitlink); + try { + StringBuilder xmlContent = new StringBuilder(); + xmlContent.append("\n") + .append("") + .append("") + .append("") + .append("").append(""); + JGitTestUtil.writeTrashFile(tempDb, "manifest.xml", + xmlContent.toString()); + RepoCommand command = new RepoCommand(remoteDb); + command.setPath( + tempDb.getWorkTree().getAbsolutePath() + "/manifest.xml") + .setURI(rootUri).call(); + // Clone it + File directory = createTempDirectory("testRevisionBare"); + Repository localDb = Git.cloneRepository().setDirectory(directory) + .setURI(remoteDb.getDirectory().toURI().toString()).call() + .getRepository(); + // The gitlink should be the same as oldCommitId + String gitlink = localDb.resolve(Constants.HEAD + ":foo").name(); + localDb.close(); + assertEquals("The gitlink is same as remote head", + oldCommitId.name(), gitlink); + } finally { + tempDb.close(); + remoteDb.close(); + } } @Test public void testCopyFileBare() throws Exception { Repository remoteDb = createBareRepository(); Repository tempDb = createWorkRepository(); - StringBuilder xmlContent = new StringBuilder(); - xmlContent.append("\n") - .append("") - .append("") - .append("") - .append("") - .append("") - .append("") - .append(""); - JGitTestUtil.writeTrashFile( - tempDb, "manifest.xml", xmlContent.toString()); - RepoCommand command = new RepoCommand(remoteDb); - command - .setPath(tempDb.getWorkTree().getAbsolutePath() + "/manifest.xml") - .setURI(rootUri) - .call(); - // Clone it - File directory = createTempDirectory("testCopyFileBare"); - Repository localDb = Git - .cloneRepository() - .setDirectory(directory) - .setURI(remoteDb.getDirectory().toURI().toString()) - .call() - .getRepository(); - // The Hello file should exist - File hello = new File(localDb.getWorkTree(), "Hello"); - assertTrue("The Hello file should exist", hello.exists()); - // The content of Hello file should be expected - BufferedReader reader = new BufferedReader(new FileReader(hello)); - String content = reader.readLine(); - reader.close(); - assertEquals("The Hello file should have expected content", - "branch world", content); + try { + StringBuilder xmlContent = new StringBuilder(); + xmlContent + .append("\n") + .append("") + .append("") + .append("") + .append("") + .append("") + .append("").append(""); + JGitTestUtil.writeTrashFile(tempDb, "manifest.xml", + xmlContent.toString()); + RepoCommand command = new RepoCommand(remoteDb); + command.setPath( + tempDb.getWorkTree().getAbsolutePath() + "/manifest.xml") + .setURI(rootUri).call(); + // Clone it + File directory = createTempDirectory("testCopyFileBare"); + Repository localDb = Git.cloneRepository().setDirectory(directory) + .setURI(remoteDb.getDirectory().toURI().toString()).call() + .getRepository(); + // The Hello file should exist + File hello = new File(localDb.getWorkTree(), "Hello"); + localDb.close(); + assertTrue("The Hello file should exist", hello.exists()); + // The content of Hello file should be expected + BufferedReader reader = new BufferedReader(new FileReader(hello)); + String content = reader.readLine(); + reader.close(); + assertEquals("The Hello file should have expected content", + "branch world", content); + } finally { + tempDb.close(); + remoteDb.close(); + } } @Test public void testReplaceManifestBare() throws Exception { Repository remoteDb = createBareRepository(); Repository tempDb = createWorkRepository(); - StringBuilder xmlContent = new StringBuilder(); - xmlContent.append("\n") - .append("") - .append("") - .append("") - .append("") - .append("") - .append("") - .append(""); - JGitTestUtil.writeTrashFile(tempDb, "old.xml", xmlContent.toString()); - RepoCommand command = new RepoCommand(remoteDb); - command.setPath(tempDb.getWorkTree().getAbsolutePath() + "/old.xml") - .setURI(rootUri) - .call(); - xmlContent = new StringBuilder(); - xmlContent.append("\n") - .append("") - .append("") - .append("") - .append("") - .append("") - .append("") - .append(""); - JGitTestUtil.writeTrashFile(tempDb, "new.xml", xmlContent.toString()); - command = new RepoCommand(remoteDb); - command.setPath(tempDb.getWorkTree().getAbsolutePath() + "/new.xml") - .setURI(rootUri) - .call(); - // Clone it - File directory = createTempDirectory("testReplaceManifestBare"); - Repository localDb = Git - .cloneRepository() - .setDirectory(directory) - .setURI(remoteDb.getDirectory().toURI().toString()) - .call() - .getRepository(); - // The Hello file should not exist - File hello = new File(localDb.getWorkTree(), "Hello"); - assertFalse("The Hello file shouldn't exist", hello.exists()); - // The Hello.txt file should exist - File hellotxt = new File(localDb.getWorkTree(), "Hello.txt"); - assertTrue("The Hello.txt file should exist", hellotxt.exists()); - // The .gitmodules file should have 'submodule "bar"' and shouldn't have - // 'submodule "foo"' lines. - File dotmodules = new File(localDb.getWorkTree(), - Constants.DOT_GIT_MODULES); - BufferedReader reader = new BufferedReader(new FileReader(dotmodules)); - boolean foo = false; - boolean bar = false; - while (true) { - String line = reader.readLine(); - if (line == null) - break; - if (line.contains("submodule \"foo\"")) - foo = true; - if (line.contains("submodule \"bar\"")) - bar = true; + try { + StringBuilder xmlContent = new StringBuilder(); + xmlContent + .append("\n") + .append("") + .append("") + .append("") + .append("") + .append("") + .append("").append(""); + JGitTestUtil.writeTrashFile(tempDb, "old.xml", + xmlContent.toString()); + RepoCommand command = new RepoCommand(remoteDb); + command.setPath(tempDb.getWorkTree().getAbsolutePath() + "/old.xml") + .setURI(rootUri).call(); + xmlContent = new StringBuilder(); + xmlContent + .append("\n") + .append("") + .append("") + .append("") + .append("") + .append("") + .append("").append(""); + JGitTestUtil.writeTrashFile(tempDb, "new.xml", + xmlContent.toString()); + command = new RepoCommand(remoteDb); + command.setPath(tempDb.getWorkTree().getAbsolutePath() + "/new.xml") + .setURI(rootUri).call(); + // Clone it + File directory = createTempDirectory("testReplaceManifestBare"); + Repository localDb = Git.cloneRepository().setDirectory(directory) + .setURI(remoteDb.getDirectory().toURI().toString()).call() + .getRepository(); + // The Hello file should not exist + File hello = new File(localDb.getWorkTree(), "Hello"); + assertFalse("The Hello file shouldn't exist", hello.exists()); + // The Hello.txt file should exist + File hellotxt = new File(localDb.getWorkTree(), "Hello.txt"); + assertTrue("The Hello.txt file should exist", hellotxt.exists()); + // The .gitmodules file should have 'submodule "bar"' and shouldn't + // have + // 'submodule "foo"' lines. + File dotmodules = new File(localDb.getWorkTree(), + Constants.DOT_GIT_MODULES); + localDb.close(); + BufferedReader reader = new BufferedReader(new FileReader( + dotmodules)); + boolean foo = false; + boolean bar = false; + while (true) { + String line = reader.readLine(); + if (line == null) + break; + if (line.contains("submodule \"foo\"")) + foo = true; + if (line.contains("submodule \"bar\"")) + bar = true; + } + reader.close(); + assertTrue("The bar submodule should exist", bar); + assertFalse("The foo submodule shouldn't exist", foo); + } finally { + tempDb.close(); + remoteDb.close(); } - reader.close(); - assertTrue("The bar submodule should exist", bar); - assertFalse("The foo submodule shouldn't exist", foo); } @Test public void testRemoveOverlappingBare() throws Exception { Repository remoteDb = createBareRepository(); Repository tempDb = createWorkRepository(); - StringBuilder xmlContent = new StringBuilder(); - xmlContent.append("\n") - .append("") - .append("") - .append("") - .append("") - .append("") - .append("") - .append(""); - JGitTestUtil.writeTrashFile( - tempDb, "manifest.xml", xmlContent.toString()); - RepoCommand command = new RepoCommand(remoteDb); - command - .setPath(tempDb.getWorkTree().getAbsolutePath() + "/manifest.xml") - .setURI(rootUri) - .call(); - // Clone it - File directory = createTempDirectory("testRemoveOverlappingBare"); - Repository localDb = Git - .cloneRepository() - .setDirectory(directory) - .setURI(remoteDb.getDirectory().toURI().toString()) - .call() - .getRepository(); - // The .gitmodules file should have 'submodule "foo"' and shouldn't have - // 'submodule "foo/bar"' lines. - File dotmodules = new File(localDb.getWorkTree(), - Constants.DOT_GIT_MODULES); - BufferedReader reader = new BufferedReader(new FileReader(dotmodules)); - boolean foo = false; - boolean foobar = false; - boolean a = false; - while (true) { - String line = reader.readLine(); - if (line == null) - break; - if (line.contains("submodule \"foo\"")) - foo = true; - if (line.contains("submodule \"foo/bar\"")) - foobar = true; - if (line.contains("submodule \"a\"")) - a = true; + try { + StringBuilder xmlContent = new StringBuilder(); + xmlContent + .append("\n") + .append("") + .append("") + .append("") + .append("") + .append("").append("").append(""); + JGitTestUtil.writeTrashFile(tempDb, "manifest.xml", + xmlContent.toString()); + RepoCommand command = new RepoCommand(remoteDb); + command.setPath( + tempDb.getWorkTree().getAbsolutePath() + "/manifest.xml") + .setURI(rootUri).call(); + // Clone it + File directory = createTempDirectory("testRemoveOverlappingBare"); + Repository localDb = Git.cloneRepository().setDirectory(directory) + .setURI(remoteDb.getDirectory().toURI().toString()).call() + .getRepository(); + // The .gitmodules file should have 'submodule "foo"' and shouldn't + // have + // 'submodule "foo/bar"' lines. + File dotmodules = new File(localDb.getWorkTree(), + Constants.DOT_GIT_MODULES); + localDb.close(); + BufferedReader reader = new BufferedReader(new FileReader( + dotmodules)); + boolean foo = false; + boolean foobar = false; + boolean a = false; + while (true) { + String line = reader.readLine(); + if (line == null) + break; + if (line.contains("submodule \"foo\"")) + foo = true; + if (line.contains("submodule \"foo/bar\"")) + foobar = true; + if (line.contains("submodule \"a\"")) + a = true; + } + reader.close(); + assertTrue("The foo submodule should exist", foo); + assertFalse("The foo/bar submodule shouldn't exist", foobar); + assertTrue("The a submodule should exist", a); + } finally { + tempDb.close(); + remoteDb.close(); } - reader.close(); - assertTrue("The foo submodule should exist", foo); - assertFalse("The foo/bar submodule shouldn't exist", foobar); - assertTrue("The a submodule should exist", a); } @Test 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 d29a75ef7..ca3e0666e 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 @@ -186,10 +186,7 @@ public class DirCacheCheckoutMaliciousPathTest extends RepositoryTestCase { @Test public void testMaliciousGitPathEndSpaceUnixOk() throws Exception { - if (File.separatorChar == '\\') - return; // cannot emulate Unix on Windows for this test - ((MockSystemReader) SystemReader.getInstance()).setUnix(); - testMaliciousPathGoodFirstCheckout(".git ", "konfig"); + testMaliciousPathBadFirstCheckout(".git ", "konfig"); } @Test @@ -212,10 +209,7 @@ public class DirCacheCheckoutMaliciousPathTest extends RepositoryTestCase { @Test public void testMaliciousGitPathEndDotUnixOk() throws Exception { - if (File.separatorChar == '\\') - return; // cannot emulate Unix on Windows for this test - ((MockSystemReader) SystemReader.getInstance()).setUnix(); - testMaliciousPathGoodFirstCheckout(".git.", "konfig"); + testMaliciousPathBadFirstCheckout(".git.", "konfig"); } @Test 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 8003824d4..863d79dde 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 @@ -90,7 +90,9 @@ public class IndexDiffSubmoduleTest extends RepositoryTestCase { .setPath("submodule") .setURI(submoduleStandalone.getDirectory().toURI().toString()) .call(); + submoduleStandalone.close(); submodule_trash = submodule_db.getWorkTree(); + addRepoToClose(submodule_db); writeTrashFile("fileInRoot", "root"); Git rootGit = Git.wrap(db); rootGit.add().addFilepattern("fileInRoot").call(); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ObjectCheckerTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ObjectCheckerTest.java index 9fc7fca98..c6578ccfa 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ObjectCheckerTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ObjectCheckerTest.java @@ -1295,12 +1295,11 @@ public class ObjectCheckerTest { } @Test - public void testInvalidTreeNameIsMixedCaseGitWindows() { + public void testInvalidTreeNameIsMixedCaseGit() { StringBuilder b = new StringBuilder(); entry(b, "100644 .GiT"); byte[] data = Constants.encodeASCII(b.toString()); try { - checker.setSafeForWindows(true); checker.checkTree(data); fail("incorrectly accepted an invalid tree"); } catch (CorruptObjectException e) { @@ -1309,19 +1308,255 @@ public class ObjectCheckerTest { } @Test - public void testInvalidTreeNameIsMixedCaseGitMacOS() { + public void testInvalidTreeNameIsMacHFSGit() { StringBuilder b = new StringBuilder(); - entry(b, "100644 .GiT"); - byte[] data = Constants.encodeASCII(b.toString()); + entry(b, "100644 .gi\u200Ct"); + byte[] data = Constants.encode(b.toString()); try { checker.setSafeForMacOS(true); checker.checkTree(data); fail("incorrectly accepted an invalid tree"); } catch (CorruptObjectException e) { - assertEquals("invalid name '.GiT'", e.getMessage()); + assertEquals( + "invalid name '.gi\u200Ct' contains ignorable Unicode characters", + e.getMessage()); + } + } + + @Test + public void testInvalidTreeNameIsMacHFSGit2() { + StringBuilder b = new StringBuilder(); + entry(b, "100644 \u206B.git"); + byte[] data = Constants.encode(b.toString()); + try { + checker.setSafeForMacOS(true); + checker.checkTree(data); + fail("incorrectly accepted an invalid tree"); + } catch (CorruptObjectException e) { + assertEquals( + "invalid name '\u206B.git' contains ignorable Unicode characters", + e.getMessage()); + } + } + + @Test + public void testInvalidTreeNameIsMacHFSGit3() { + StringBuilder b = new StringBuilder(); + entry(b, "100644 .git\uFEFF"); + byte[] data = Constants.encode(b.toString()); + try { + checker.setSafeForMacOS(true); + checker.checkTree(data); + fail("incorrectly accepted an invalid tree"); + } catch (CorruptObjectException e) { + assertEquals( + "invalid name '.git\uFEFF' contains ignorable Unicode characters", + e.getMessage()); + } + } + + private static byte[] concat(byte[] b1, byte[] b2) { + byte[] data = new byte[b1.length + b2.length]; + System.arraycopy(b1, 0, data, 0, b1.length); + System.arraycopy(b2, 0, data, b1.length, b2.length); + return data; + } + + @Test + public void testInvalidTreeNameIsMacHFSGitCorruptUTF8AtEnd() { + byte[] data = concat(Constants.encode("100644 .git"), + new byte[] { (byte) 0xef }); + StringBuilder b = new StringBuilder(); + entry(b, ""); + data = concat(data, Constants.encode(b.toString())); + try { + checker.setSafeForMacOS(true); + checker.checkTree(data); + fail("incorrectly accepted an invalid tree"); + } catch (CorruptObjectException e) { + assertEquals( + "invalid name contains byte sequence '0xef' which is not a valid UTF-8 character", + e.getMessage()); + } + } + + @Test + public void testInvalidTreeNameIsMacHFSGitCorruptUTF8AtEnd2() { + byte[] data = concat(Constants.encode("100644 .git"), new byte[] { + (byte) 0xe2, (byte) 0xab }); + StringBuilder b = new StringBuilder(); + entry(b, ""); + data = concat(data, Constants.encode(b.toString())); + try { + checker.setSafeForMacOS(true); + checker.checkTree(data); + fail("incorrectly accepted an invalid tree"); + } catch (CorruptObjectException e) { + assertEquals( + "invalid name contains byte sequence '0xe2ab' which is not a valid UTF-8 character", + e.getMessage()); + } + } + + @Test + public void testInvalidTreeNameIsNotMacHFSGit() + throws CorruptObjectException { + StringBuilder b = new StringBuilder(); + entry(b, "100644 .git\u200Cx"); + byte[] data = Constants.encode(b.toString()); + checker.setSafeForMacOS(true); + checker.checkTree(data); + } + + @Test + public void testInvalidTreeNameIsNotMacHFSGit2() + throws CorruptObjectException { + StringBuilder b = new StringBuilder(); + entry(b, "100644 .kit\u200C"); + byte[] data = Constants.encode(b.toString()); + checker.setSafeForMacOS(true); + checker.checkTree(data); + } + + @Test + public void testInvalidTreeNameIsNotMacHFSGitOtherPlatform() + throws CorruptObjectException { + StringBuilder b = new StringBuilder(); + entry(b, "100644 .git\u200C"); + byte[] data = Constants.encode(b.toString()); + checker.checkTree(data); + } + + @Test + public void testInvalidTreeNameIsDotGitDot() { + StringBuilder b = new StringBuilder(); + entry(b, "100644 .git."); + byte[] data = Constants.encodeASCII(b.toString()); + try { + checker.checkTree(data); + fail("incorrectly accepted an invalid tree"); + } catch (CorruptObjectException e) { + assertEquals("invalid name '.git.'", e.getMessage()); + } + } + + @Test + public void testValidTreeNameIsDotGitDotDot() + throws CorruptObjectException { + StringBuilder b = new StringBuilder(); + entry(b, "100644 .git.."); + checker.checkTree(Constants.encodeASCII(b.toString())); + } + + @Test + public void testInvalidTreeNameIsDotGitSpace() { + StringBuilder b = new StringBuilder(); + entry(b, "100644 .git "); + byte[] data = Constants.encodeASCII(b.toString()); + try { + checker.checkTree(data); + fail("incorrectly accepted an invalid tree"); + } catch (CorruptObjectException e) { + assertEquals("invalid name '.git '", e.getMessage()); } } + @Test + public void testInvalidTreeNameIsDotGitSomething() + throws CorruptObjectException { + StringBuilder b = new StringBuilder(); + entry(b, "100644 .gitfoobar"); + byte[] data = Constants.encodeASCII(b.toString()); + checker.checkTree(data); + } + + @Test + public void testInvalidTreeNameIsDotGitSomethingSpaceSomething() + throws CorruptObjectException { + StringBuilder b = new StringBuilder(); + entry(b, "100644 .gitfoo bar"); + byte[] data = Constants.encodeASCII(b.toString()); + checker.checkTree(data); + } + + @Test + public void testInvalidTreeNameIsDotGitSomethingDot() + throws CorruptObjectException { + StringBuilder b = new StringBuilder(); + entry(b, "100644 .gitfoobar."); + byte[] data = Constants.encodeASCII(b.toString()); + checker.checkTree(data); + } + + @Test + public void testInvalidTreeNameIsDotGitSomethingDotDot() + throws CorruptObjectException { + StringBuilder b = new StringBuilder(); + entry(b, "100644 .gitfoobar.."); + byte[] data = Constants.encodeASCII(b.toString()); + checker.checkTree(data); + } + + @Test + public void testInvalidTreeNameIsDotGitDotSpace() { + StringBuilder b = new StringBuilder(); + entry(b, "100644 .git. "); + byte[] data = Constants.encodeASCII(b.toString()); + try { + checker.checkTree(data); + fail("incorrectly accepted an invalid tree"); + } catch (CorruptObjectException e) { + assertEquals("invalid name '.git. '", e.getMessage()); + } + } + + @Test + public void testInvalidTreeNameIsDotGitSpaceDot() { + StringBuilder b = new StringBuilder(); + entry(b, "100644 .git . "); + byte[] data = Constants.encodeASCII(b.toString()); + try { + checker.checkTree(data); + fail("incorrectly accepted an invalid tree"); + } catch (CorruptObjectException e) { + assertEquals("invalid name '.git . '", e.getMessage()); + } + } + + @Test + public void testInvalidTreeNameIsGITTilde1() { + StringBuilder b = new StringBuilder(); + entry(b, "100644 GIT~1"); + byte[] data = Constants.encodeASCII(b.toString()); + try { + checker.checkTree(data); + fail("incorrectly accepted an invalid tree"); + } catch (CorruptObjectException e) { + assertEquals("invalid name 'GIT~1'", e.getMessage()); + } + } + + @Test + public void testInvalidTreeNameIsGiTTilde1() { + StringBuilder b = new StringBuilder(); + entry(b, "100644 GiT~1"); + byte[] data = Constants.encodeASCII(b.toString()); + try { + checker.checkTree(data); + fail("incorrectly accepted an invalid tree"); + } catch (CorruptObjectException e) { + assertEquals("invalid name 'GiT~1'", e.getMessage()); + } + } + + @Test + public void testValidTreeNameIsGitTilde11() throws CorruptObjectException { + StringBuilder b = new StringBuilder(); + entry(b, "100644 GIT~11"); + byte[] data = Constants.encodeASCII(b.toString()); + checker.checkTree(data); + } + @Test public void testInvalidTreeTruncatedInName() { final StringBuilder b = new StringBuilder(); 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 b17b991ad..b13c4cd80 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 @@ -131,7 +131,8 @@ public class SubmoduleAddTest extends RepositoryTestCase { command.setURI(uri); Repository repo = command.call(); assertNotNull(repo); - addRepoToClose(repo); + ObjectId subCommit = repo.resolve(Constants.HEAD); + repo.close(); SubmoduleWalk generator = SubmoduleWalk.forIndex(db); assertTrue(generator.next()); @@ -141,9 +142,9 @@ public class SubmoduleAddTest extends RepositoryTestCase { assertEquals(path, generator.getModulesPath()); assertEquals(uri, generator.getConfigUrl()); Repository subModRepo = generator.getRepository(); - addRepoToClose(subModRepo); assertNotNull(subModRepo); - assertEquals(commit, repo.resolve(Constants.HEAD)); + assertEquals(subCommit, commit); + subModRepo.close(); Status status = Git.wrap(db).status().call(); assertTrue(status.getAdded().contains(Constants.DOT_GIT_MODULES)); @@ -206,7 +207,6 @@ public class SubmoduleAddTest extends RepositoryTestCase { fullUri = fullUri.replace('\\', '/'); assertEquals(fullUri, generator.getConfigUrl()); Repository subModRepo = generator.getRepository(); - addRepoToClose(subModRepo); assertNotNull(subModRepo); assertEquals( fullUri, @@ -215,6 +215,7 @@ public class SubmoduleAddTest extends RepositoryTestCase { .getString(ConfigConstants.CONFIG_REMOTE_SECTION, Constants.DEFAULT_REMOTE_NAME, ConfigConstants.CONFIG_KEY_URL)); + subModRepo.close(); assertEquals(commit, repo.resolve(Constants.HEAD)); Status status = Git.wrap(db).status().call(); 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 b00d45287..54a6f77b4 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 @@ -135,8 +135,8 @@ public class SubmoduleSyncTest extends RepositoryTestCase { assertTrue(generator.next()); assertEquals(url, generator.getConfigUrl()); Repository subModRepository = generator.getRepository(); - addRepoToClose(subModRepository); StoredConfig submoduleConfig = subModRepository.getConfig(); + subModRepository.close(); assertEquals(url, submoduleConfig.getString( ConfigConstants.CONFIG_REMOTE_SECTION, Constants.DEFAULT_REMOTE_NAME, ConfigConstants.CONFIG_KEY_URL)); @@ -207,8 +207,8 @@ public class SubmoduleSyncTest extends RepositoryTestCase { assertTrue(generator.next()); assertEquals("git://server/sub.git", generator.getConfigUrl()); Repository subModRepository1 = generator.getRepository(); - addRepoToClose(subModRepository1); StoredConfig submoduleConfig = subModRepository1.getConfig(); + subModRepository1.close(); 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 eac4c873f..bcdd5e21b 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 @@ -121,9 +121,9 @@ public class SubmoduleUpdateTest extends RepositoryTestCase { SubmoduleWalk generator = SubmoduleWalk.forIndex(db); assertTrue(generator.next()); Repository subRepo = generator.getRepository(); - addRepoToClose(subRepo); assertNotNull(subRepo); assertEquals(commit, subRepo.resolve(Constants.HEAD)); + subRepo.close(); } @Test 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 251938fec..f7acaa788 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 @@ -175,12 +175,12 @@ public class SubmoduleWalkTest extends RepositoryTestCase { assertNull(gen.getModulesUpdate()); assertNull(gen.getModulesUrl()); Repository subRepo = gen.getRepository(); - addRepoToClose(subRepo); assertNotNull(subRepo); assertEquals(modulesGitDir.getAbsolutePath(), subRepo.getDirectory().getAbsolutePath()); assertEquals(new File(db.getWorkTree(), path).getAbsolutePath(), subRepo.getWorkTree().getAbsolutePath()); + subRepo.close(); assertFalse(gen.next()); } @@ -227,11 +227,11 @@ public class SubmoduleWalkTest extends RepositoryTestCase { assertNull(gen.getModulesUpdate()); assertNull(gen.getModulesUrl()); Repository subRepo = gen.getRepository(); - addRepoToClose(subRepo); assertNotNull(subRepo); assertEqualsFile(modulesGitDir, subRepo.getDirectory()); assertEqualsFile(new File(db.getWorkTree(), path), subRepo.getWorkTree()); + subRepo.close(); assertFalse(gen.next()); } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/filter/PathFilterGroupTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/filter/PathFilterGroupTest.java index 4c329cb19..d0062e199 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/filter/PathFilterGroupTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/filter/PathFilterGroupTest.java @@ -169,7 +169,7 @@ public class PathFilterGroupTest { } // less obvious due to git sorting order - filter.include(fakeWalk("d.")); + filter.include(fakeWalk("d-")); // less obvious due to git sorting order try { diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/TemporaryBufferTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/TemporaryBufferTest.java index 5f5968dbc..9817cdc0a 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/TemporaryBufferTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/TemporaryBufferTest.java @@ -59,7 +59,7 @@ import org.junit.Test; public class TemporaryBufferTest { @Test public void testEmpty() throws IOException { - final TemporaryBuffer b = new TemporaryBuffer.LocalFile(); + final TemporaryBuffer b = new TemporaryBuffer.LocalFile(null); try { b.close(); assertEquals(0, b.length()); @@ -73,7 +73,7 @@ public class TemporaryBufferTest { @Test public void testOneByte() throws IOException { - final TemporaryBuffer b = new TemporaryBuffer.LocalFile(); + final TemporaryBuffer b = new TemporaryBuffer.LocalFile(null); final byte test = (byte) new TestRng(getName()).nextInt(); try { b.write(test); @@ -100,7 +100,7 @@ public class TemporaryBufferTest { @Test public void testOneBlock_BulkWrite() throws IOException { - final TemporaryBuffer b = new TemporaryBuffer.LocalFile(); + final TemporaryBuffer b = new TemporaryBuffer.LocalFile(null); final byte[] test = new TestRng(getName()) .nextBytes(TemporaryBuffer.Block.SZ); try { @@ -131,7 +131,7 @@ public class TemporaryBufferTest { @Test public void testOneBlockAndHalf_BulkWrite() throws IOException { - final TemporaryBuffer b = new TemporaryBuffer.LocalFile(); + final TemporaryBuffer b = new TemporaryBuffer.LocalFile(null); final byte[] test = new TestRng(getName()) .nextBytes(TemporaryBuffer.Block.SZ * 3 / 2); try { @@ -162,7 +162,7 @@ public class TemporaryBufferTest { @Test public void testOneBlockAndHalf_SingleWrite() throws IOException { - final TemporaryBuffer b = new TemporaryBuffer.LocalFile(); + final TemporaryBuffer b = new TemporaryBuffer.LocalFile(null); final byte[] test = new TestRng(getName()) .nextBytes(TemporaryBuffer.Block.SZ * 3 / 2); try { @@ -191,7 +191,7 @@ public class TemporaryBufferTest { @Test public void testOneBlockAndHalf_Copy() throws IOException { - final TemporaryBuffer b = new TemporaryBuffer.LocalFile(); + final TemporaryBuffer b = new TemporaryBuffer.LocalFile(null); final byte[] test = new TestRng(getName()) .nextBytes(TemporaryBuffer.Block.SZ * 3 / 2); try { @@ -221,7 +221,7 @@ public class TemporaryBufferTest { @Test public void testLarge_SingleWrite() throws IOException { - final TemporaryBuffer b = new TemporaryBuffer.LocalFile(); + final TemporaryBuffer b = new TemporaryBuffer.LocalFile(null); final byte[] test = new TestRng(getName()) .nextBytes(TemporaryBuffer.DEFAULT_IN_CORE_LIMIT * 3); try { @@ -263,7 +263,7 @@ public class TemporaryBufferTest { @Test public void testInCoreLimit_SwitchOnAppendByte() throws IOException { - final TemporaryBuffer b = new TemporaryBuffer.LocalFile(); + final TemporaryBuffer b = new TemporaryBuffer.LocalFile(null); final byte[] test = new TestRng(getName()) .nextBytes(TemporaryBuffer.DEFAULT_IN_CORE_LIMIT + 1); try { @@ -292,7 +292,7 @@ public class TemporaryBufferTest { @Test public void testInCoreLimit_SwitchBeforeAppendByte() throws IOException { - final TemporaryBuffer b = new TemporaryBuffer.LocalFile(); + final TemporaryBuffer b = new TemporaryBuffer.LocalFile(null); final byte[] test = new TestRng(getName()) .nextBytes(TemporaryBuffer.DEFAULT_IN_CORE_LIMIT * 3); try { @@ -321,7 +321,7 @@ public class TemporaryBufferTest { @Test public void testInCoreLimit_SwitchOnCopy() throws IOException { - final TemporaryBuffer b = new TemporaryBuffer.LocalFile(); + final TemporaryBuffer b = new TemporaryBuffer.LocalFile(null); final byte[] test = new TestRng(getName()) .nextBytes(TemporaryBuffer.DEFAULT_IN_CORE_LIMIT * 2); try { @@ -354,7 +354,7 @@ public class TemporaryBufferTest { @Test public void testDestroyWhileOpen() throws IOException { @SuppressWarnings("resource" /* java 7 */) - final TemporaryBuffer b = new TemporaryBuffer.LocalFile(); + final TemporaryBuffer b = new TemporaryBuffer.LocalFile(null); try { b.write(new TestRng(getName()) .nextBytes(TemporaryBuffer.DEFAULT_IN_CORE_LIMIT * 2)); @@ -365,7 +365,7 @@ public class TemporaryBufferTest { @Test public void testRandomWrites() throws IOException { - final TemporaryBuffer b = new TemporaryBuffer.LocalFile(); + final TemporaryBuffer b = new TemporaryBuffer.LocalFile(null); final TestRng rng = new TestRng(getName()); final int max = TemporaryBuffer.DEFAULT_IN_CORE_LIMIT * 2; final byte[] expect = new byte[max]; diff --git a/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties b/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties index 76c709422..a753188e8 100644 --- a/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties +++ b/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties @@ -249,6 +249,8 @@ indexFileIsInUse=Index file is in use indexFileIsTooLargeForJgit=Index file is too large for jgit indexSignatureIsInvalid=Index signature is invalid: {0} indexWriteException=Modified index could not be written +initFailedBareRepoDifferentDirs=When initializing a bare repo with directory {0} and separate git-dir {1} specified both folders must point to the same location +initFailedNonBareRepoSameDirs=When initializing a non-bare repo with directory {0} and separate git-dir {1} specified both folders should not point to the same location inMemoryBufferLimitExceeded=In-memory buffer limit exceeded inputStreamMustSupportMark=InputStream must support mark() integerValueOutOfRange=Integer value {0}.{1} out of range diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/CheckoutCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/CheckoutCommand.java index 182093228..3787ac511 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/CheckoutCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/CheckoutCommand.java @@ -405,14 +405,17 @@ public class CheckoutCommand extends GitCommand { DirCacheIterator dci = new DirCacheIterator(dc); treeWalk.addTree(dci); + String previousPath = null; + final ObjectReader r = treeWalk.getObjectReader(); DirCacheEditor editor = dc.editor(); while (treeWalk.next()) { - DirCacheEntry entry = dci.getDirCacheEntry(); + String path = treeWalk.getPathString(); // Only add one edit per path - if (entry != null && entry.getStage() > DirCacheEntry.STAGE_1) + if (path.equals(previousPath)) continue; - editor.add(new PathEdit(treeWalk.getPathString()) { + + editor.add(new PathEdit(path) { public void apply(DirCacheEntry ent) { int stage = ent.getStage(); if (stage > DirCacheEntry.STAGE_0) { @@ -429,6 +432,8 @@ public class CheckoutCommand extends GitCommand { } } }); + + previousPath = path; } editor.commit(); } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/CloneCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/CloneCommand.java index 645d3e781..de24dadff 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/CloneCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/CloneCommand.java @@ -86,6 +86,8 @@ public class CloneCommand extends TransportCommand { private File directory; + private File gitDir; + private boolean bare; private String remote = Constants.DEFAULT_REMOTE_NAME; @@ -137,12 +139,19 @@ public class CloneCommand extends TransportCommand { private Repository init(URIish u) throws GitAPIException { InitCommand command = Git.init(); command.setBare(bare); - if (directory == null) + if (directory == null && gitDir == null) directory = new File(u.getHumanishName(), Constants.DOT_GIT); - if (directory.exists() && directory.listFiles().length != 0) + if (directory != null && directory.exists() + && directory.listFiles().length != 0) throw new JGitInternalException(MessageFormat.format( JGitText.get().cloneNonEmptyDirectory, directory.getName())); - command.setDirectory(directory); + if (gitDir != null && gitDir.exists() && gitDir.listFiles().length != 0) + throw new JGitInternalException(MessageFormat.format( + JGitText.get().cloneNonEmptyDirectory, gitDir.getName())); + if (directory != null) + command.setDirectory(directory); + if (gitDir != null) + command.setGitDir(gitDir); return command.call().getRepository(); } @@ -336,18 +345,47 @@ public class CloneCommand extends TransportCommand { * @param directory * the directory to clone to * @return this instance + * @throws IllegalStateException + * if the combination of directory, gitDir and bare is illegal. + * E.g. if for a non-bare repository directory and gitDir point + * to the same directory of if for a bare repository both + * directory and gitDir are specified */ public CloneCommand setDirectory(File directory) { + validateDirs(directory, gitDir, bare); this.directory = directory; return this; } + /** + * @param gitDir + * the repository meta directory + * @return this instance + * @throws IllegalStateException + * if the combination of directory, gitDir and bare is illegal. + * E.g. if for a non-bare repository directory and gitDir point + * to the same directory of if for a bare repository both + * directory and gitDir are specified + * @since 3.6 + */ + public CloneCommand setGitDir(File gitDir) { + validateDirs(directory, gitDir, bare); + this.gitDir = gitDir; + return this; + } + /** * @param bare * whether the cloned repository is bare or not * @return this instance + * @throws IllegalStateException + * if the combination of directory, gitDir and bare is illegal. + * E.g. if for a non-bare repository directory and gitDir point + * to the same directory of if for a bare repository both + * directory and gitDir are specified */ - public CloneCommand setBare(boolean bare) { + public CloneCommand setBare(boolean bare) throws IllegalStateException { + validateDirs(directory, gitDir, bare); this.bare = bare; return this; } @@ -438,4 +476,21 @@ public class CloneCommand extends TransportCommand { this.noCheckout = noCheckout; return this; } + + private static void validateDirs(File directory, File gitDir, boolean bare) + throws IllegalStateException { + if (directory != null) { + if (bare) { + if (gitDir != null && !gitDir.equals(directory)) + throw new IllegalStateException(MessageFormat.format( + JGitText.get().initFailedBareRepoDifferentDirs, + gitDir, directory)); + } else { + if (gitDir != null && gitDir.equals(directory)) + throw new IllegalStateException(MessageFormat.format( + JGitText.get().initFailedNonBareRepoSameDirs, + gitDir, directory)); + } + } + } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/InitCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/InitCommand.java index bf43e90d4..37a788e85 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/InitCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/InitCommand.java @@ -44,13 +44,16 @@ package org.eclipse.jgit.api; import java.io.File; import java.io.IOException; +import java.text.MessageFormat; import java.util.concurrent.Callable; import org.eclipse.jgit.api.errors.GitAPIException; import org.eclipse.jgit.api.errors.JGitInternalException; +import org.eclipse.jgit.internal.JGitText; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.lib.RepositoryBuilder; +import org.eclipse.jgit.util.SystemReader; /** * Create an empty git repository or reinitalize an existing one @@ -61,6 +64,8 @@ import org.eclipse.jgit.lib.RepositoryBuilder; public class InitCommand implements Callable { private File directory; + private File gitDir; + private boolean bare; /** @@ -74,18 +79,36 @@ public class InitCommand implements Callable { if (bare) builder.setBare(); builder.readEnvironment(); + if (gitDir != null) + builder.setGitDir(gitDir); + else + gitDir = builder.getGitDir(); if (directory != null) { - File d = directory; - if (!bare) - d = new File(d, Constants.DOT_GIT); - builder.setGitDir(d); + if (bare) + builder.setGitDir(directory); + else { + builder.setWorkTree(directory); + if (gitDir == null) + builder.setGitDir(new File(directory, Constants.DOT_GIT)); + } } else if (builder.getGitDir() == null) { - File d = new File("."); //$NON-NLS-1$ - if (d.getParentFile() != null) - d = d.getParentFile(); + String dStr = SystemReader.getInstance() + .getProperty("user.dir"); //$NON-NLS-1$ + if (dStr == null) + dStr = "."; //$NON-NLS-1$ + File d = new File(dStr); if (!bare) d = new File(d, Constants.DOT_GIT); builder.setGitDir(d); + } else { + // directory was not set but gitDir was set + if (!bare) { + String dStr = SystemReader.getInstance().getProperty( + "user.dir"); //$NON-NLS-1$ + if (dStr == null) + dStr = "."; //$NON-NLS-1$ + builder.setWorkTree(new File(dStr)); + } } Repository repository = builder.build(); if (!repository.getObjectDatabase().exists()) @@ -103,20 +126,67 @@ public class InitCommand implements Callable { * @param directory * the directory to init to * @return this instance + * @throws IllegalStateException + * if the combination of directory, gitDir and bare is illegal. + * E.g. if for a non-bare repository directory and gitDir point + * to the same directory of if for a bare repository both + * directory and gitDir are specified */ - public InitCommand setDirectory(File directory) { + public InitCommand setDirectory(File directory) + throws IllegalStateException { + validateDirs(directory, gitDir, bare); this.directory = directory; return this; } + /** + * @param gitDir + * the repository meta directory + * @return this instance + * @throws IllegalStateException + * if the combination of directory, gitDir and bare is illegal. + * E.g. if for a non-bare repository directory and gitDir point + * to the same directory of if for a bare repository both + * directory and gitDir are specified + * @since 3.6 + */ + public InitCommand setGitDir(File gitDir) + throws IllegalStateException { + validateDirs(directory, gitDir, bare); + this.gitDir = gitDir; + return this; + } + + private static void validateDirs(File directory, File gitDir, boolean bare) + throws IllegalStateException { + if (directory != null) { + if (bare) { + if (gitDir != null && !gitDir.equals(directory)) + throw new IllegalStateException(MessageFormat.format( + JGitText.get().initFailedBareRepoDifferentDirs, + gitDir, directory)); + } else { + if (gitDir != null && gitDir.equals(directory)) + throw new IllegalStateException(MessageFormat.format( + JGitText.get().initFailedNonBareRepoSameDirs, + gitDir, directory)); + } + } + } + /** * @param bare * whether the repository is bare or not + * @throws IllegalStateException + * if the combination of directory, gitDir and bare is illegal. + * E.g. if for a non-bare repository directory and gitDir point + * to the same directory of if for a bare repository both + * directory and gitDir are specified * @return this instance */ public InitCommand setBare(boolean bare) { + validateDirs(directory, gitDir, bare); this.bare = bare; return this; } - } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/ReflogCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/ReflogCommand.java index 8cd78aebe..4536af1be 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/ReflogCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/ReflogCommand.java @@ -48,6 +48,7 @@ import java.util.Collection; import org.eclipse.jgit.api.errors.GitAPIException; import org.eclipse.jgit.api.errors.InvalidRefNameException; +import org.eclipse.jgit.api.errors.RefNotFoundException; import org.eclipse.jgit.internal.JGitText; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.ReflogEntry; @@ -97,6 +98,9 @@ public class ReflogCommand extends GitCommand> { try { ReflogReader reader = repo.getReflogReader(ref); + if (reader == null) + throw new RefNotFoundException(MessageFormat.format( + JGitText.get().refNotResolved, ref)); return reader.getReverseEntries(); } catch (IOException e) { throw new InvalidRefNameException(MessageFormat.format( diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleUpdateCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleUpdateCommand.java index de1a3e9fd..81a30156a 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleUpdateCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleUpdateCommand.java @@ -42,6 +42,7 @@ */ package org.eclipse.jgit.api; +import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; @@ -163,6 +164,8 @@ public class SubmoduleUpdateCommand extends configure(clone); clone.setURI(url); clone.setDirectory(generator.getDirectory()); + clone.setGitDir(new File(new File(repo.getDirectory(), + Constants.MODULES), generator.getPath())); if (monitor != null) clone.setProgressMonitor(monitor); submoduleRepo = clone.call().getRepository(); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCache.java b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCache.java index 645de2704..98a1c8ca4 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCache.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCache.java @@ -607,7 +607,8 @@ public class DirCache { final LockFile tmp = myLock; requireLocked(tmp); try { - writeTo(new SafeBufferedOutputStream(tmp.getOutputStream())); + writeTo(liveFile.getParentFile(), + new SafeBufferedOutputStream(tmp.getOutputStream())); } catch (IOException err) { tmp.unlock(); throw err; @@ -620,7 +621,7 @@ public class DirCache { } } - void writeTo(final OutputStream os) throws IOException { + void writeTo(File dir, final OutputStream os) throws IOException { final MessageDigest foot = Constants.newMessageDigest(); final DigestOutputStream dos = new DigestOutputStream(os, foot); @@ -670,14 +671,18 @@ public class DirCache { } if (writeTree) { - final TemporaryBuffer bb = new TemporaryBuffer.LocalFile(); - tree.write(tmp, bb); - bb.close(); - - NB.encodeInt32(tmp, 0, EXT_TREE); - NB.encodeInt32(tmp, 4, (int) bb.length()); - dos.write(tmp, 0, 8); - bb.writeTo(dos, null); + TemporaryBuffer bb = new TemporaryBuffer.LocalFile(dir, 5 << 20); + try { + tree.write(tmp, bb); + bb.close(); + + NB.encodeInt32(tmp, 0, EXT_TREE); + NB.encodeInt32(tmp, 4, (int) bb.length()); + dos.write(tmp, 0, 8); + bb.writeTo(dos, null); + } finally { + bb.destroy(); + } } writeIndexChecksum = foot.digest(); os.write(writeIndexChecksum); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheCheckout.java b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheCheckout.java index c7dd03dd4..015d9d6a8 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheCheckout.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheCheckout.java @@ -1245,9 +1245,9 @@ public class DirCacheCheckout { } finally { channel.close(); } - entry.setLength(opt.getAutoCRLF() == AutoCRLF.TRUE - ? f.length() // AutoCRLF wants on-disk-size - : (int) ol.getSize()); + entry.setLength(opt.getAutoCRLF() == AutoCRLF.TRUE ? // + tmpFile.length() // AutoCRLF wants on-disk-size + : (int) ol.getSize()); if (opt.isFileMode() && fs.supportsExecute()) { if (FileMode.EXECUTABLE_FILE.equals(entry.getRawMode())) { @@ -1291,7 +1291,9 @@ public class DirCacheCheckout { try { SystemReader.getInstance().checkPath(path); } catch (CorruptObjectException e) { - throw new InvalidPathException(path); + InvalidPathException p = new InvalidPathException(path); + p.initCause(e); + throw p; } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheEntry.java b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheEntry.java index 65188c8f4..eef2e6d3c 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheEntry.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheEntry.java @@ -56,6 +56,7 @@ import java.security.MessageDigest; import java.text.MessageFormat; import java.util.Arrays; +import org.eclipse.jgit.errors.CorruptObjectException; import org.eclipse.jgit.internal.JGitText; import org.eclipse.jgit.lib.AnyObjectId; import org.eclipse.jgit.lib.Constants; @@ -64,7 +65,6 @@ import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.util.IO; import org.eclipse.jgit.util.MutableInteger; import org.eclipse.jgit.util.NB; -import org.eclipse.jgit.util.SystemReader; /** * A single file (or stage of a file) in a {@link DirCache}. @@ -190,6 +190,16 @@ public class DirCacheEntry { md.update((byte) 0); } + try { + DirCacheCheckout.checkValidPath(toString(path)); + } catch (InvalidPathException e) { + CorruptObjectException p = + new CorruptObjectException(e.getMessage()); + if (e.getCause() != null) + p.initCause(e.getCause()); + throw p; + } + // Index records are padded out to the next 8 byte alignment // for historical reasons related to how C Git read the files. // @@ -203,7 +213,6 @@ public class DirCacheEntry { if (mightBeRacilyClean(smudge_s, smudge_ns)) smudgeRacilyClean(); - } /** @@ -217,7 +226,7 @@ public class DirCacheEntry { * or DirCache file. */ public DirCacheEntry(final String newPath) { - this(Constants.encode(newPath)); + this(Constants.encode(newPath), STAGE_0); } /** @@ -266,11 +275,11 @@ public class DirCacheEntry { */ @SuppressWarnings("boxing") public DirCacheEntry(final byte[] newPath, final int stage) { - if (!isValidPath(newPath)) - throw new InvalidPathException(toString(newPath)); + DirCacheCheckout.checkValidPath(toString(newPath)); if (stage < 0 || 3 < stage) - throw new IllegalArgumentException(MessageFormat.format(JGitText.get().invalidStageForPath - , stage, toString(newPath))); + throw new IllegalArgumentException(MessageFormat.format( + JGitText.get().invalidStageForPath, + stage, toString(newPath))); info = new byte[INFO_LEN]; infoOffset = 0; @@ -725,36 +734,6 @@ public class DirCacheEntry { return Constants.CHARSET.decode(ByteBuffer.wrap(path)).toString(); } - static boolean isValidPath(final byte[] path) { - if (path.length == 0) - return false; // empty path is not permitted. - - boolean componentHasChars = false; - for (final byte c : path) { - switch (c) { - case 0: - return false; // NUL is never allowed within the path. - - case '/': - if (componentHasChars) - componentHasChars = false; - else - return false; - break; - case '\\': - case ':': - // Tree's never have a backslash in them, not even on Windows - // but even there we regard it as an invalid path - if (SystemReader.getInstance().isWindows()) - return false; - //$FALL-THROUGH$ - default: - componentHasChars = true; - } - } - return componentHasChars; - } - static int getMaximumInfoLength(boolean extended) { return extended ? INFO_LEN_EXTENDED : INFO_LEN; } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoCommand.java index 1c4c3db0d..4207513e7 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoCommand.java @@ -193,6 +193,7 @@ public class RepoCommand extends GitCommand { try { return readFileFromRepo(repo, ref, path); } finally { + repo.close(); FileUtils.delete(dir, FileUtils.RECURSIVE); } } @@ -860,6 +861,7 @@ public class RepoCommand extends GitCommand { if (revision != null) { Git sub = new Git(subRepo); sub.checkout().setName(findRef(revision, subRepo)).call(); + subRepo.close(); git.add().addFilepattern(name).call(); } for (CopyFile copyfile : copyfiles) { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java index d1f0deec9..65272fb0b 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java @@ -308,6 +308,8 @@ public class JGitText extends TranslationBundle { /***/ public String indexFileIsTooLargeForJgit; /***/ public String indexSignatureIsInvalid; /***/ public String indexWriteException; + /***/ public String initFailedBareRepoDifferentDirs; + /***/ public String initFailedNonBareRepoSameDirs; /***/ public String inMemoryBufferLimitExceeded; /***/ public String inputStreamMustSupportMark; /***/ public String integerValueOutOfRange; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileRepository.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileRepository.java index 9670bf10a..995621ee3 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileRepository.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileRepository.java @@ -273,7 +273,8 @@ public class FileRepository extends Repository { ConfigConstants.CONFIG_CORE_SECTION, null, ConfigConstants.CONFIG_KEY_HIDEDOTFILES, HideDotFiles.DOTGITONLY); - if (hideDotFiles != HideDotFiles.FALSE && !isBare()) + if (hideDotFiles != HideDotFiles.FALSE && !isBare() + && getDirectory().getName().startsWith(".")) //$NON-NLS-1$ getFS().setHidden(getDirectory(), true); refs.create(); objectDatabase.create(); @@ -329,6 +330,25 @@ public class FileRepository extends Repository { // Java has no other way cfg.setBoolean(ConfigConstants.CONFIG_CORE_SECTION, null, ConfigConstants.CONFIG_KEY_PRECOMPOSEUNICODE, true); + if (!bare) { + File workTree = getWorkTree(); + if (!getDirectory().getParentFile().equals(workTree)) { + cfg.setString(ConfigConstants.CONFIG_CORE_SECTION, null, + ConfigConstants.CONFIG_KEY_WORKTREE, getWorkTree() + .getAbsolutePath()); + LockFile dotGitLockFile = new LockFile(new File(workTree, + Constants.DOT_GIT), getFS()); + try { + if (dotGitLockFile.lock()) { + dotGitLockFile.write(Constants.encode(Constants.GITDIR + + getDirectory().getAbsolutePath())); + dotGitLockFile.commit(); + } + } finally { + dotGitLockFile.unlock(); + } + } + } cfg.save(); } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectory.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectory.java index 48a6b9d67..58276051e 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectory.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectory.java @@ -131,14 +131,6 @@ public class ObjectDirectory extends FileObjectDatabase { private Set shallowCommitsIds; - // Whether to trust the pack folder's modification time. If set - // to false we will always scan the .git/objects/pack folder to - // check for new pack files. If set to true (default) we use the - // lastmodified attribute of the folder and assume that no new - // pack files can be in this folder if his modification time has - // not changed. - private boolean trustFolderStat = true; - /** * Initialize a reference to an on-disk object directory. * @@ -161,9 +153,6 @@ public class ObjectDirectory extends FileObjectDatabase { File[] alternatePaths, FS fs, File shallowFile) throws IOException { config = cfg; objects = dir; - trustFolderStat = config.getBoolean( - ConfigConstants.CONFIG_CORE_SECTION, - ConfigConstants.CONFIG_KEY_TRUSTFOLDERSTAT, true); infoDirectory = new File(objects, "info"); //$NON-NLS-1$ packDirectory = new File(objects, "pack"); //$NON-NLS-1$ alternatesFile = new File(infoDirectory, "alternates"); //$NON-NLS-1$ @@ -618,6 +607,16 @@ public class ObjectDirectory extends FileObjectDatabase { } private boolean searchPacksAgain(PackList old) { + // Whether to trust the pack folder's modification time. If set + // to false we will always scan the .git/objects/pack folder to + // check for new pack files. If set to true (default) we use the + // lastmodified attribute of the folder and assume that no new + // pack files can be in this folder if his modification time has + // not changed. + boolean trustFolderStat = config.getBoolean( + ConfigConstants.CONFIG_CORE_SECTION, + ConfigConstants.CONFIG_KEY_TRUSTFOLDERSTAT, true); + return ((!trustFolderStat) || old.snapshot.isModified(packDirectory)) && old != scanPacks(old); } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Constants.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Constants.java index d14614dc3..f14974984 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Constants.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Constants.java @@ -272,7 +272,14 @@ public final class Constants { */ public static final String INFO_EXCLUDE = "info/exclude"; - /** The environment variable that contains the system user name */ + /** + * The system property that contains the system user name + * + * @since 3.6 + */ + public static final String OS_USER_DIR = "user.dir"; + + /** The system property that contains the system user name */ public static final String OS_USER_NAME_KEY = "user.name"; /** The environment variable that contains the author's name */ @@ -358,6 +365,20 @@ public final class Constants { /** Name of the .git/shallow file */ public static final String SHALLOW = "shallow"; + /** + * Prefix of the first line in a ".git" file + * + * @since 3.6 + */ + public static final String GITDIR = "gitdir: "; + + /** + * Name of the folder (inside gitDir) where submodules are stored + * + * @since 3.6 + */ + public static final String MODULES = "modules"; + /** * Create a new digest function for objects. * diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/IndexDiff.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/IndexDiff.java index d62b1f58a..1b049f615 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/IndexDiff.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/IndexDiff.java @@ -533,28 +533,35 @@ public class IndexDiff { } Repository subRepo = smw.getRepository(); if (subRepo != null) { - ObjectId subHead = subRepo.resolve("HEAD"); //$NON-NLS-1$ - if (subHead != null && !subHead.equals(smw.getObjectId())) - modified.add(smw.getPath()); - else if (ignoreSubmoduleMode != IgnoreSubmoduleMode.DIRTY) { - IndexDiff smid = submoduleIndexDiffs.get(smw.getPath()); - if (smid == null) { - smid = new IndexDiff(subRepo, smw.getObjectId(), - wTreeIt.getWorkingTreeIterator(subRepo)); - submoduleIndexDiffs.put(smw.getPath(), smid); - } - if (smid.diff()) { - if (ignoreSubmoduleMode == IgnoreSubmoduleMode.UNTRACKED - && smid.getAdded().isEmpty() - && smid.getChanged().isEmpty() - && smid.getConflicting().isEmpty() - && smid.getMissing().isEmpty() - && smid.getModified().isEmpty() - && smid.getRemoved().isEmpty()) { - continue; - } + try { + ObjectId subHead = subRepo.resolve("HEAD"); //$NON-NLS-1$ + if (subHead != null + && !subHead.equals(smw.getObjectId())) modified.add(smw.getPath()); + else if (ignoreSubmoduleMode != IgnoreSubmoduleMode.DIRTY) { + IndexDiff smid = submoduleIndexDiffs.get(smw + .getPath()); + if (smid == null) { + smid = new IndexDiff(subRepo, + smw.getObjectId(), + wTreeIt.getWorkingTreeIterator(subRepo)); + submoduleIndexDiffs.put(smw.getPath(), smid); + } + if (smid.diff()) { + if (ignoreSubmoduleMode == IgnoreSubmoduleMode.UNTRACKED + && smid.getAdded().isEmpty() + && smid.getChanged().isEmpty() + && smid.getConflicting().isEmpty() + && smid.getMissing().isEmpty() + && smid.getModified().isEmpty() + && smid.getRemoved().isEmpty()) { + continue; + } + modified.add(smw.getPath()); + } } + } finally { + subRepo.close(); } } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectChecker.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectChecker.java index 9fe54b0c5..8435c9a64 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectChecker.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectChecker.java @@ -492,13 +492,27 @@ public class ObjectChecker { throw new CorruptObjectException("invalid name '..'"); break; case 4: - if (isDotGit(raw, ptr + 1)) + if (isGit(raw, ptr + 1)) + throw new CorruptObjectException(String.format( + "invalid name '%s'", + RawParseUtils.decode(raw, ptr, end))); + break; + default: + if (end - ptr > 4 && isNormalizedGit(raw, ptr + 1, end)) throw new CorruptObjectException(String.format( "invalid name '%s'", RawParseUtils.decode(raw, ptr, end))); } + } else if (isGitTilde1(raw, ptr, end)) { + throw new CorruptObjectException(String.format("invalid name '%s'", + RawParseUtils.decode(raw, ptr, end))); } + if (macosx && isMacHFSGit(raw, ptr, end)) + throw new CorruptObjectException(String.format( + "invalid name '%s' contains ignorable Unicode characters", + RawParseUtils.decode(raw, ptr, end))); + if (windows) { // Windows ignores space and dot at end of file name. if (raw[end - 1] == ' ' || raw[end - 1] == '.') @@ -509,6 +523,88 @@ public class ObjectChecker { } } + // Mac's HFS+ folds permutations of ".git" and Unicode ignorable characters + // to ".git" therefore we should prevent such names + private static boolean isMacHFSGit(byte[] raw, int ptr, int end) + throws CorruptObjectException { + boolean ignorable = false; + byte[] git = new byte[] { '.', 'g', 'i', 't' }; + int g = 0; + while (ptr < end) { + switch (raw[ptr]) { + case (byte) 0xe2: // http://www.utf8-chartable.de/unicode-utf8-table.pl?start=8192 + checkTruncatedIgnorableUTF8(raw, ptr, end); + switch (raw[ptr + 1]) { + case (byte) 0x80: + switch (raw[ptr + 2]) { + case (byte) 0x8c: // U+200C 0xe2808c ZERO WIDTH NON-JOINER + case (byte) 0x8d: // U+200D 0xe2808d ZERO WIDTH JOINER + case (byte) 0x8e: // U+200E 0xe2808e LEFT-TO-RIGHT MARK + case (byte) 0x8f: // U+200F 0xe2808f RIGHT-TO-LEFT MARK + case (byte) 0xaa: // U+202A 0xe280aa LEFT-TO-RIGHT EMBEDDING + case (byte) 0xab: // U+202B 0xe280ab RIGHT-TO-LEFT EMBEDDING + case (byte) 0xac: // U+202C 0xe280ac POP DIRECTIONAL FORMATTING + case (byte) 0xad: // U+202D 0xe280ad LEFT-TO-RIGHT OVERRIDE + case (byte) 0xae: // U+202E 0xe280ae RIGHT-TO-LEFT OVERRIDE + ignorable = true; + ptr += 3; + continue; + default: + return false; + } + case (byte) 0x81: + switch (raw[ptr + 2]) { + case (byte) 0xaa: // U+206A 0xe281aa INHIBIT SYMMETRIC SWAPPING + case (byte) 0xab: // U+206B 0xe281ab ACTIVATE SYMMETRIC SWAPPING + case (byte) 0xac: // U+206C 0xe281ac INHIBIT ARABIC FORM SHAPING + case (byte) 0xad: // U+206D 0xe281ad ACTIVATE ARABIC FORM SHAPING + case (byte) 0xae: // U+206E 0xe281ae NATIONAL DIGIT SHAPES + case (byte) 0xaf: // U+206F 0xe281af NOMINAL DIGIT SHAPES + ignorable = true; + ptr += 3; + continue; + default: + return false; + } + } + break; + case (byte) 0xef: // http://www.utf8-chartable.de/unicode-utf8-table.pl?start=65024 + checkTruncatedIgnorableUTF8(raw, ptr, end); + // U+FEFF 0xefbbbf ZERO WIDTH NO-BREAK SPACE + if ((raw[ptr + 1] == (byte) 0xbb) + && (raw[ptr + 2] == (byte) 0xbf)) { + ignorable = true; + ptr += 3; + continue; + } + return false; + default: + if (g == 4) + return false; + if (raw[ptr++] != git[g++]) + return false; + } + } + if (g == 4 && ignorable) + return true; + return false; + } + + private static void checkTruncatedIgnorableUTF8(byte[] raw, int ptr, int end) + throws CorruptObjectException { + if ((ptr + 2) >= end) + throw new CorruptObjectException(MessageFormat.format( + "invalid name contains byte sequence ''{0}'' which is not a valid UTF-8 character", + toHexString(raw, ptr, end))); + } + + private static String toHexString(byte[] raw, int ptr, int end) { + StringBuilder b = new StringBuilder("0x"); //$NON-NLS-1$ + for (int i = ptr; i < end; i++) + b.append(String.format("%02x", Byte.valueOf(raw[i]))); //$NON-NLS-1$ + return b.toString(); + } + private static void checkNotWindowsDevice(byte[] raw, int ptr, int end) throws CorruptObjectException { switch (toLower(raw[ptr])) { @@ -579,12 +675,36 @@ public class ObjectChecker { return 1 <= c && c <= 31; } - private boolean isDotGit(byte[] buf, int p) { - if (windows || macosx) - return toLower(buf[p]) == 'g' - && toLower(buf[p + 1]) == 'i' - && toLower(buf[p + 2]) == 't'; - return buf[p] == 'g' && buf[p + 1] == 'i' && buf[p + 2] == 't'; + private static boolean isGit(byte[] buf, int p) { + return toLower(buf[p]) == 'g' + && toLower(buf[p + 1]) == 'i' + && toLower(buf[p + 2]) == 't'; + } + + private static boolean isGitTilde1(byte[] buf, int p, int end) { + if (end - p != 5) + return false; + return toLower(buf[p]) == 'g' && toLower(buf[p + 1]) == 'i' + && toLower(buf[p + 2]) == 't' && buf[p + 3] == '~' + && buf[p + 4] == '1'; + } + + private static boolean isNormalizedGit(byte[] raw, int ptr, int end) { + if (isGit(raw, ptr)) { + int dots = 0; + boolean space = false; + int p = end - 1; + for (; (ptr + 2) < p; p--) { + if (raw[p] == '.') + dots++; + else if (raw[p] == ' ') + space = true; + else + break; + } + return p == ptr + 2 && (dots == 1 || space); + } + return false; } private static char toLower(byte b) { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RebaseTodoFile.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RebaseTodoFile.java index ef61e2203..4ebe5fedf 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RebaseTodoFile.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RebaseTodoFile.java @@ -43,17 +43,17 @@ package org.eclipse.jgit.lib; -import java.io.BufferedWriter; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; -import java.io.OutputStreamWriter; +import java.io.OutputStream; import java.util.LinkedList; import java.util.List; import org.eclipse.jgit.lib.RebaseTodoLine.Action; import org.eclipse.jgit.util.IO; import org.eclipse.jgit.util.RawParseUtils; +import org.eclipse.jgit.util.io.SafeBufferedOutputStream; /** * Offers methods to read and write files formatted like the git-rebase-todo @@ -216,9 +216,8 @@ public class RebaseTodoFile { */ public void writeRebaseTodoFile(String path, List steps, boolean append) throws IOException { - BufferedWriter fw = new BufferedWriter(new OutputStreamWriter( - new FileOutputStream(new File(repo.getDirectory(), path), - append), Constants.CHARACTER_ENCODING)); + OutputStream fw = new SafeBufferedOutputStream(new FileOutputStream( + new File(repo.getDirectory(), path), append)); try { StringBuilder sb = new StringBuilder(); for (RebaseTodoLine step : steps) { @@ -232,8 +231,8 @@ public class RebaseTodoFile { sb.append(" "); //$NON-NLS-1$ sb.append(step.getShortMessage().trim()); } - fw.write(sb.toString()); - fw.newLine(); + sb.append('\n'); + fw.write(Constants.encode(sb.toString())); } } finally { fw.close(); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/patch/FileHeader.java b/org.eclipse.jgit/src/org/eclipse/jgit/patch/FileHeader.java index 8171669bc..534c82731 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/patch/FileHeader.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/patch/FileHeader.java @@ -267,7 +267,7 @@ public class FileHeader extends DiffEntry { final TemporaryBuffer[] tmp = new TemporaryBuffer[getParentCount() + 1]; try { for (int i = 0; i < tmp.length; i++) - tmp[i] = new TemporaryBuffer.LocalFile(); + tmp[i] = new TemporaryBuffer.Heap(Integer.MAX_VALUE); for (final HunkHeader h : getHunks()) h.extractFileLines(tmp); @@ -281,11 +281,6 @@ public class FileHeader extends DiffEntry { return r; } catch (IOException ioe) { throw new RuntimeException(JGitText.get().cannotConvertScriptToText, ioe); - } finally { - for (final TemporaryBuffer b : tmp) { - if (b != null) - b.destroy(); - } } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/patch/Patch.java b/org.eclipse.jgit/src/org/eclipse/jgit/patch/Patch.java index 7b4847352..383c1f8fe 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/patch/Patch.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/patch/Patch.java @@ -139,14 +139,10 @@ public class Patch { } private static byte[] readFully(final InputStream is) throws IOException { - final TemporaryBuffer b = new TemporaryBuffer.LocalFile(); - try { - b.copy(is); - b.close(); - return b.toByteArray(); - } finally { - b.destroy(); - } + TemporaryBuffer b = new TemporaryBuffer.Heap(Integer.MAX_VALUE); + b.copy(is); + b.close(); + return b.toByteArray(); } /** diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/AmazonS3.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/AmazonS3.java index 99d8b09d8..722bfc489 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/AmazonS3.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/AmazonS3.java @@ -182,6 +182,9 @@ public class AmazonS3 { /** Encryption algorithm, may be a null instance that provides pass-through. */ private final WalkEncryption encryption; + /** Directory for locally buffered content. */ + private final File tmpDir; + /** * Create a new S3 client for the supplied user information. *

@@ -251,6 +254,9 @@ public class AmazonS3 { maxAttempts = Integer.parseInt(props.getProperty( "httpclient.retry-max", "3")); //$NON-NLS-1$ //$NON-NLS-2$ proxySelector = ProxySelector.getDefault(); + + String tmp = props.getProperty("tmpdir"); //$NON-NLS-1$ + tmpDir = tmp != null && tmp.length() > 0 ? new File(tmp) : null; } /** @@ -452,7 +458,7 @@ public class AmazonS3 { final ProgressMonitor monitor, final String monitorTask) throws IOException { final MessageDigest md5 = newMD5(); - final TemporaryBuffer buffer = new TemporaryBuffer.LocalFile() { + final TemporaryBuffer buffer = new TemporaryBuffer.LocalFile(tmpDir) { @Override public void close() throws IOException { super.close(); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportAmazonS3.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportAmazonS3.java index b3a55a581..afaaa69a4 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportAmazonS3.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportAmazonS3.java @@ -147,7 +147,11 @@ public class TransportAmazonS3 extends HttpTransport implements WalkTransport { throws NotSupportedException { super(local, uri); - s3 = new AmazonS3(loadProperties()); + Properties props = loadProperties(); + if (!props.contains("tmpdir") && local.getDirectory() != null) //$NON-NLS-1$ + props.put("tmpdir", local.getDirectory().getPath()); //$NON-NLS-1$ + + s3 = new AmazonS3(props); bucket = uri.getHost(); String p = uri.getPath(); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/TemporaryBuffer.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/TemporaryBuffer.java index 88c32d2f5..10aade4e1 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/TemporaryBuffer.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/TemporaryBuffer.java @@ -361,7 +361,12 @@ public abstract class TemporaryBuffer extends OutputStream { */ private File onDiskFile; - /** Create a new temporary buffer. */ + /** + * Create a new temporary buffer. + * + * @deprecated Use the {@code File} overload to supply a directory. + */ + @Deprecated public LocalFile() { this(null, DEFAULT_IN_CORE_LIMIT); } @@ -372,7 +377,9 @@ public abstract class TemporaryBuffer extends OutputStream { * @param inCoreLimit * maximum number of bytes to store in memory. Storage beyond * this limit will use the local file. + * @deprecated Use the {@code File,int} overload to supply a directory. */ + @Deprecated public LocalFile(final int inCoreLimit) { this(null, inCoreLimit); }