Browse Source

Merge branch 'stable-3.6'

* stable-3.6: (26 commits)
  JGit v3.5.3.201412180710-r
  JGit v3.4.2.201412180340-r
  ObjectChecker: Disallow names potentially mapping to ".git" on HFS+
  ObjectChecker: Disallow Windows shortname "GIT~1"
  ObjectChecker: Disallow ".git." and ".git<space>"
  Always ignore case when forbidding .git in ObjectChecker
  DirCache: Refuse to read files with invalid paths
  DirCache: Replace isValidPath with DirCacheCheckout.checkValidPath
  Replace "a." with "a-" in unit tests
  Support the new repository layout for submodules
  Allow explicit configuration of git directory in CloneCommand
  Allow explicit configuration of git directory in InitCommand
  Fix tests on windows by closing repos
  RepoCommand should close opened repos
  Fix LocalDiskRepositoryTestCase to create correct type of repos
  Prevent NPE if ref can't be resolved when executing ReflogCommand
  Fix DirCacheCheckout to set correct file length if core.autocrlf=true
  CheckoutCommand: Fix checking out ours/theirs when no base stage exists
  Make sure modifications to config-param trustFolderStat are detected
  Apache HttpClientConnection: replace calls to deprecated LocalFile()
  ...

Change-Id: Ife6f21d64a148dbb0d0d9055356b1568188806fe
stable-3.7
Shawn Pearce 10 years ago
parent
commit
90cccb96d2
  1. 6
      org.eclipse.jgit.http.apache/src/org/eclipse/jgit/transport/http/apache/HttpClientConnection.java
  2. 5
      org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/SmartClientSmartServerTest.java
  3. 2
      org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/LocalDiskRepositoryTestCase.java
  4. 1
      org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/MockSystemReader.java
  5. 2
      org.eclipse.jgit.test/exttst/org/eclipse/jgit/patch/EGitPatchHistoryTest.java
  6. 48
      org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CheckoutCommandTest.java
  7. 70
      org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CloneCommandTest.java
  8. 4
      org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CommitCommandTest.java
  9. 110
      org.eclipse.jgit.test/tst/org/eclipse/jgit/api/InitCommandTest.java
  10. 34
      org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PathCheckoutCommandTest.java
  11. 46
      org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheBasicTest.java
  12. 2
      org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheBuilderIteratorTest.java
  13. 6
      org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheBuilderTest.java
  14. 2
      org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheCGitCompatabilityTest.java
  15. 8
      org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheEntryTest.java
  16. 10
      org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheFindTest.java
  17. 24
      org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheIteratorTest.java
  18. 8
      org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCachePathEditTest.java
  19. 6
      org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheTreeTest.java
  20. 458
      org.eclipse.jgit.test/tst/org/eclipse/jgit/gitrepo/RepoCommandTest.java
  21. 10
      org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/DirCacheCheckoutMaliciousPathTest.java
  22. 2
      org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/IndexDiffSubmoduleTest.java
  23. 247
      org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ObjectCheckerTest.java
  24. 9
      org.eclipse.jgit.test/tst/org/eclipse/jgit/submodule/SubmoduleAddTest.java
  25. 4
      org.eclipse.jgit.test/tst/org/eclipse/jgit/submodule/SubmoduleSyncTest.java
  26. 2
      org.eclipse.jgit.test/tst/org/eclipse/jgit/submodule/SubmoduleUpdateTest.java
  27. 4
      org.eclipse.jgit.test/tst/org/eclipse/jgit/submodule/SubmoduleWalkTest.java
  28. 2
      org.eclipse.jgit.test/tst/org/eclipse/jgit/treewalk/filter/PathFilterGroupTest.java
  29. 24
      org.eclipse.jgit.test/tst/org/eclipse/jgit/util/TemporaryBufferTest.java
  30. 2
      org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties
  31. 11
      org.eclipse.jgit/src/org/eclipse/jgit/api/CheckoutCommand.java
  32. 63
      org.eclipse.jgit/src/org/eclipse/jgit/api/CloneCommand.java
  33. 88
      org.eclipse.jgit/src/org/eclipse/jgit/api/InitCommand.java
  34. 4
      org.eclipse.jgit/src/org/eclipse/jgit/api/ReflogCommand.java
  35. 3
      org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleUpdateCommand.java
  36. 25
      org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCache.java
  37. 10
      org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheCheckout.java
  38. 53
      org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheEntry.java
  39. 2
      org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoCommand.java
  40. 2
      org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java
  41. 22
      org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileRepository.java
  42. 21
      org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectory.java
  43. 23
      org.eclipse.jgit/src/org/eclipse/jgit/lib/Constants.java
  44. 47
      org.eclipse.jgit/src/org/eclipse/jgit/lib/IndexDiff.java
  45. 134
      org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectChecker.java
  46. 13
      org.eclipse.jgit/src/org/eclipse/jgit/lib/RebaseTodoFile.java
  47. 7
      org.eclipse.jgit/src/org/eclipse/jgit/patch/FileHeader.java
  48. 12
      org.eclipse.jgit/src/org/eclipse/jgit/patch/Patch.java
  49. 8
      org.eclipse.jgit/src/org/eclipse/jgit/transport/AmazonS3.java
  50. 6
      org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportAmazonS3.java
  51. 9
      org.eclipse.jgit/src/org/eclipse/jgit/util/TemporaryBuffer.java

6
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) { public void setFixedLengthStreamingMode(int contentLength) {
if (entity != null) if (entity != null)
throw new IllegalArgumentException(); throw new IllegalArgumentException();
entity = new TemporaryBufferEntity(new LocalFile()); entity = new TemporaryBufferEntity(new LocalFile(null));
entity.setContentLength(contentLength); entity.setContentLength(contentLength);
} }
public OutputStream getOutputStream() throws IOException { public OutputStream getOutputStream() throws IOException {
if (entity == null) if (entity == null)
entity = new TemporaryBufferEntity(new LocalFile()); entity = new TemporaryBufferEntity(new LocalFile(null));
return entity.getBuffer(); return entity.getBuffer();
} }
public void setChunkedStreamingMode(int chunklen) { public void setChunkedStreamingMode(int chunklen) {
if (entity == null) if (entity == null)
entity = new TemporaryBufferEntity(new LocalFile()); entity = new TemporaryBufferEntity(new LocalFile(null));
entity.setChunked(true); entity.setChunked(true);
} }

5
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.TestRng;
import org.eclipse.jgit.junit.http.AccessEvent; import org.eclipse.jgit.junit.http.AccessEvent;
import org.eclipse.jgit.junit.http.HttpTestCase; import org.eclipse.jgit.junit.http.HttpTestCase;
import org.eclipse.jgit.lib.ConfigConstants;
import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.NullProgressMonitor; import org.eclipse.jgit.lib.NullProgressMonitor;
import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.ObjectId;
@ -143,6 +144,10 @@ public class SmartClientSmartServerTest extends HttpTestCase {
final TestRepository<Repository> src = createTestRepository(); final TestRepository<Repository> src = createTestRepository();
final String srcName = src.getRepository().getDirectory().getName(); 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"); ServletContextHandler app = server.addContext("/git");
GitServlet gs = new GitServlet(); GitServlet gs = new GitServlet();

2
org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/LocalDiskRepositoryTestCase.java

@ -265,7 +265,7 @@ public abstract class LocalDiskRepositoryTestCase {
File gitdir = createUniqueTestGitDir(bare); File gitdir = createUniqueTestGitDir(bare);
FileRepository db = new FileRepository(gitdir); FileRepository db = new FileRepository(gitdir);
assertFalse(gitdir.exists()); assertFalse(gitdir.exists());
db.create(); db.create(bare);
toClose.add(db); toClose.add(db);
return db; return db;
} }

1
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_AUTHOR_EMAIL_KEY);
init(Constants.GIT_COMMITTER_NAME_KEY); init(Constants.GIT_COMMITTER_NAME_KEY);
init(Constants.GIT_COMMITTER_EMAIL_KEY); init(Constants.GIT_COMMITTER_EMAIL_KEY);
setProperty(Constants.OS_USER_DIR, ".");
userGitConfig = new MockConfig(null, null); userGitConfig = new MockConfig(null, null);
systemGitConfig = new MockConfig(null, null); systemGitConfig = new MockConfig(null, null);
setCurrentPlatform(); setCurrentPlatform();

2
org.eclipse.jgit.test/exttst/org/eclipse/jgit/patch/EGitPatchHistoryTest.java

@ -216,7 +216,7 @@ public class EGitPatchHistoryTest {
buf.destroy(); buf.destroy();
} }
commitId = line.substring("commit ".length()); commitId = line.substring("commit ".length());
buf = new TemporaryBuffer.LocalFile(); buf = new TemporaryBuffer.LocalFile(null);
} else if (buf != null) { } else if (buf != null) {
buf.write(line.getBytes("ISO-8859-1")); buf.write(line.getBytes("ISO-8859-1"));
buf.write('\n'); buf.write('\n');

48
org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CheckoutCommandTest.java

@ -43,8 +43,8 @@
*/ */
package org.eclipse.jgit.api; package org.eclipse.jgit.api;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull; 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.Repository;
import org.eclipse.jgit.lib.StoredConfig; import org.eclipse.jgit.lib.StoredConfig;
import org.eclipse.jgit.revwalk.RevCommit; import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.storage.file.FileBasedConfig;
import org.eclipse.jgit.transport.RefSpec; import org.eclipse.jgit.transport.RefSpec;
import org.eclipse.jgit.transport.RemoteConfig; import org.eclipse.jgit.transport.RemoteConfig;
import org.eclipse.jgit.transport.URIish; 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);
}
} }

70
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.assertEquals;
import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail; 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.ListBranchCommand.ListMode;
import org.eclipse.jgit.api.errors.GitAPIException; import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.api.errors.JGitInternalException; import org.eclipse.jgit.api.errors.JGitInternalException;
import org.eclipse.jgit.errors.NoWorkTreeException;
import org.eclipse.jgit.junit.RepositoryTestCase; import org.eclipse.jgit.junit.RepositoryTestCase;
import org.eclipse.jgit.junit.TestRepository; import org.eclipse.jgit.junit.TestRepository;
import org.eclipse.jgit.lib.ConfigConstants; import org.eclipse.jgit.lib.ConfigConstants;
@ -135,6 +137,54 @@ public class CloneCommandTest extends RepositoryTestCase {
fetchRefSpec(git2.getRepository())); 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 @Test
public void testBareCloneRepository() throws IOException, public void testBareCloneRepository() throws IOException,
JGitInternalException, GitAPIException, URISyntaxException { JGitInternalException, GitAPIException, URISyntaxException {
@ -360,6 +410,18 @@ public class CloneCommandTest extends RepositoryTestCase {
assertEquals(SubmoduleStatusType.INITIALIZED, pathStatus.getType()); assertEquals(SubmoduleStatusType.INITIALIZED, pathStatus.getType());
assertEquals(commit, pathStatus.getHeadId()); assertEquals(commit, pathStatus.getHeadId());
assertEquals(commit, pathStatus.getIndexId()); 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 @Test
@ -441,10 +503,16 @@ public class CloneCommandTest extends RepositoryTestCase {
SubmoduleWalk walk = SubmoduleWalk.forIndex(git2.getRepository()); SubmoduleWalk walk = SubmoduleWalk.forIndex(git2.getRepository());
assertTrue(walk.next()); assertTrue(walk.next());
Repository clonedSub1 = walk.getRepository(); Repository clonedSub1 = walk.getRepository();
addRepoToClose(clonedSub1);
assertNotNull(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); status = new SubmoduleStatusCommand(clonedSub1);
statuses = status.call(); statuses = status.call();
clonedSub1.close();
pathStatus = statuses.get(path); pathStatus = statuses.get(path);
assertNotNull(pathStatus); assertNotNull(pathStatus);
assertEquals(SubmoduleStatusType.INITIALIZED, pathStatus.getType()); assertEquals(SubmoduleStatusType.INITIALIZED, pathStatus.getType());

4
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(path, generator.getModulesPath());
assertEquals(uri, generator.getConfigUrl()); assertEquals(uri, generator.getConfigUrl());
Repository subModRepo = generator.getRepository(); Repository subModRepo = generator.getRepository();
addRepoToClose(subModRepo);
assertNotNull(subModRepo); assertNotNull(subModRepo);
subModRepo.close();
assertEquals(commit, repo.resolve(Constants.HEAD)); assertEquals(commit, repo.resolve(Constants.HEAD));
RevCommit submoduleCommit = git.commit().setMessage("submodule add") RevCommit submoduleCommit = git.commit().setMessage("submodule add")
@ -253,8 +253,8 @@ public class CommitCommandTest extends RepositoryTestCase {
assertEquals(path, generator.getModulesPath()); assertEquals(path, generator.getModulesPath());
assertEquals(uri, generator.getConfigUrl()); assertEquals(uri, generator.getConfigUrl());
Repository subModRepo = generator.getRepository(); Repository subModRepo = generator.getRepository();
addRepoToClose(subModRepo);
assertNotNull(subModRepo); assertNotNull(subModRepo);
subModRepo.close();
assertEquals(commit2, repo.resolve(Constants.HEAD)); assertEquals(commit2, repo.resolve(Constants.HEAD));
RevCommit submoduleAddCommit = git.commit().setMessage("submodule add") RevCommit submoduleAddCommit = git.commit().setMessage("submodule add")

110
org.eclipse.jgit.test/tst/org/eclipse/jgit/api/InitCommandTest.java

@ -43,6 +43,7 @@
package org.eclipse.jgit.api; package org.eclipse.jgit.api;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import java.io.File; 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.GitAPIException;
import org.eclipse.jgit.api.errors.JGitInternalException; 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.junit.RepositoryTestCase;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.util.SystemReader;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
@ -101,4 +106,109 @@ public class InitCommandTest extends RepositoryTestCase {
assertNotNull(repository); assertNotNull(repository);
assertTrue(repository.isBare()); 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();
}
} }

34
org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PathCheckoutCommandTest.java

@ -43,6 +43,7 @@
package org.eclipse.jgit.api; package org.eclipse.jgit.api;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
@ -276,6 +277,39 @@ public class PathCheckoutCommandTest extends RepositoryTestCase {
assertStageOneToThree(FILE1); 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) @Test(expected = IllegalStateException.class)
public void testStageNotPossibleWithBranch() throws Exception { public void testStageNotPossibleWithBranch() throws Exception {
git.checkout().setStage(Stage.OURS).setStartPoint("master").call(); git.checkout().setStage(Stage.OURS).setStartPoint("master").call();

46
org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheBasicTest.java vendored

@ -47,12 +47,19 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.io.File; 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.junit.RepositoryTestCase;
import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.FileMode; import org.eclipse.jgit.lib.FileMode;
import org.eclipse.jgit.lib.ObjectInserter;
import org.eclipse.jgit.util.SystemReader;
import org.junit.Test; import org.junit.Test;
public class DirCacheBasicTest extends RepositoryTestCase { public class DirCacheBasicTest extends RepositoryTestCase {
@ -190,7 +197,7 @@ public class DirCacheBasicTest extends RepositoryTestCase {
public void testBuildThenClear() throws Exception { public void testBuildThenClear() throws Exception {
final DirCache dc = db.readDirCache(); 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]; final DirCacheEntry[] ents = new DirCacheEntry[paths.length];
for (int i = 0; i < paths.length; i++) { for (int i = 0; i < paths.length; i++) {
ents[i] = new DirCacheEntry(paths[i]); ents[i] = new DirCacheEntry(paths[i]);
@ -234,4 +241,41 @@ public class DirCacheBasicTest extends RepositoryTestCase {
final byte[] path = Constants.encode("a"); final byte[] path = Constants.encode("a");
assertEquals(-1, dc.findEntry(path, path.length)); 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());
}
}
} }

2
org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheBuilderIteratorTest.java vendored

@ -63,7 +63,7 @@ public class DirCacheBuilderIteratorTest extends RepositoryTestCase {
final DirCache dc = db.readDirCache(); final DirCache dc = db.readDirCache();
final FileMode mode = FileMode.REGULAR_FILE; 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]; final DirCacheEntry[] ents = new DirCacheEntry[paths.length];
for (int i = 0; i < paths.length; i++) { for (int i = 0; i < paths.length; i++) {
ents[i] = new DirCacheEntry(paths[i]); ents[i] = new DirCacheEntry(paths[i]);

6
org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheBuilderTest.java vendored

@ -290,7 +290,7 @@ public class DirCacheBuilderTest extends RepositoryTestCase {
public void testAdd_InGitSortOrder() throws Exception { public void testAdd_InGitSortOrder() throws Exception {
final DirCache dc = db.readDirCache(); 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]; final DirCacheEntry[] ents = new DirCacheEntry[paths.length];
for (int i = 0; i < paths.length; i++) { for (int i = 0; i < paths.length; i++) {
ents[i] = new DirCacheEntry(paths[i]); ents[i] = new DirCacheEntry(paths[i]);
@ -315,7 +315,7 @@ public class DirCacheBuilderTest extends RepositoryTestCase {
public void testAdd_ReverseGitSortOrder() throws Exception { public void testAdd_ReverseGitSortOrder() throws Exception {
final DirCache dc = db.readDirCache(); 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]; final DirCacheEntry[] ents = new DirCacheEntry[paths.length];
for (int i = 0; i < paths.length; i++) { for (int i = 0; i < paths.length; i++) {
ents[i] = new DirCacheEntry(paths[i]); ents[i] = new DirCacheEntry(paths[i]);
@ -340,7 +340,7 @@ public class DirCacheBuilderTest extends RepositoryTestCase {
public void testBuilderClear() throws Exception { public void testBuilderClear() throws Exception {
final DirCache dc = db.readDirCache(); 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]; final DirCacheEntry[] ents = new DirCacheEntry[paths.length];
for (int i = 0; i < paths.length; i++) { for (int i = 0; i < paths.length; i++) {
ents[i] = new DirCacheEntry(paths[i]); ents[i] = new DirCacheEntry(paths[i]);

2
org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheCGitCompatabilityTest.java vendored

@ -213,7 +213,7 @@ public class DirCacheCGitCompatabilityTest extends LocalDiskRepositoryTestCase {
assertV3TreeEntry(9, "newfile.txt", false, true, dc); assertV3TreeEntry(9, "newfile.txt", false, true, dc);
final ByteArrayOutputStream bos = new ByteArrayOutputStream(); final ByteArrayOutputStream bos = new ByteArrayOutputStream();
dc.writeTo(bos); dc.writeTo(null, bos);
final byte[] indexBytes = bos.toByteArray(); final byte[] indexBytes = bos.toByteArray();
final byte[] expectedBytes = IO.readFully(file); final byte[] expectedBytes = IO.readFully(file);
assertArrayEquals(expectedBytes, indexBytes); assertArrayEquals(expectedBytes, indexBytes);

8
org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheEntryTest.java vendored

@ -49,7 +49,6 @@ import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail; import static org.junit.Assert.fail;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.FileMode; import org.eclipse.jgit.lib.FileMode;
import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.ObjectId;
import org.junit.Test; import org.junit.Test;
@ -71,7 +70,12 @@ public class DirCacheEntryTest {
} }
private static boolean isValidPath(final String path) { 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 @Test

10
org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheFindTest.java vendored

@ -56,7 +56,7 @@ public class DirCacheFindTest extends RepositoryTestCase {
public void testEntriesWithin() throws Exception { public void testEntriesWithin() throws Exception {
final DirCache dc = db.readDirCache(); 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]; final DirCacheEntry[] ents = new DirCacheEntry[paths.length];
for (int i = 0; i < paths.length; i++) { for (int i = 0; i < paths.length; i++) {
ents[i] = new DirCacheEntry(paths[i]); ents[i] = new DirCacheEntry(paths[i]);
@ -96,13 +96,13 @@ public class DirCacheFindTest extends RepositoryTestCase {
assertSame(ents[i], aContents[i]); assertSame(ents[i], aContents[i]);
} }
assertNotNull(dc.getEntriesWithin("a.")); assertNotNull(dc.getEntriesWithin("a-"));
assertEquals(0, dc.getEntriesWithin("a.").length); assertEquals(0, dc.getEntriesWithin("a-").length);
assertNotNull(dc.getEntriesWithin("a0b")); assertNotNull(dc.getEntriesWithin("a0b"));
assertEquals(0, dc.getEntriesWithin("a0b.").length); assertEquals(0, dc.getEntriesWithin("a0b-").length);
assertNotNull(dc.getEntriesWithin("zoo")); assertNotNull(dc.getEntriesWithin("zoo"));
assertEquals(0, dc.getEntriesWithin("zoo.").length); assertEquals(0, dc.getEntriesWithin("zoo-").length);
} }
} }

24
org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheIteratorTest.java vendored

@ -85,7 +85,7 @@ public class DirCacheIteratorTest extends RepositoryTestCase {
public void testNoSubtree_NoTreeWalk() throws Exception { public void testNoSubtree_NoTreeWalk() throws Exception {
final DirCache dc = DirCache.newInCore(); final DirCache dc = DirCache.newInCore();
final String[] paths = { "a.", "a0b" }; final String[] paths = { "a-", "a0b" };
final DirCacheEntry[] ents = new DirCacheEntry[paths.length]; final DirCacheEntry[] ents = new DirCacheEntry[paths.length];
for (int i = 0; i < paths.length; i++) { for (int i = 0; i < paths.length; i++) {
ents[i] = new DirCacheEntry(paths[i]); ents[i] = new DirCacheEntry(paths[i]);
@ -111,7 +111,7 @@ public class DirCacheIteratorTest extends RepositoryTestCase {
public void testNoSubtree_WithTreeWalk() throws Exception { public void testNoSubtree_WithTreeWalk() throws Exception {
final DirCache dc = DirCache.newInCore(); final DirCache dc = DirCache.newInCore();
final String[] paths = { "a.", "a0b" }; final String[] paths = { "a-", "a0b" };
final FileMode[] modes = { FileMode.EXECUTABLE_FILE, FileMode.GITLINK }; final FileMode[] modes = { FileMode.EXECUTABLE_FILE, FileMode.GITLINK };
final DirCacheEntry[] ents = new DirCacheEntry[paths.length]; final DirCacheEntry[] ents = new DirCacheEntry[paths.length];
for (int i = 0; i < paths.length; i++) { for (int i = 0; i < paths.length; i++) {
@ -144,7 +144,7 @@ public class DirCacheIteratorTest extends RepositoryTestCase {
public void testSingleSubtree_NoRecursion() throws Exception { public void testSingleSubtree_NoRecursion() throws Exception {
final DirCache dc = DirCache.newInCore(); 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]; final DirCacheEntry[] ents = new DirCacheEntry[paths.length];
for (int i = 0; i < paths.length; i++) { for (int i = 0; i < paths.length; i++) {
ents[i] = new DirCacheEntry(paths[i]); ents[i] = new DirCacheEntry(paths[i]);
@ -156,7 +156,7 @@ public class DirCacheIteratorTest extends RepositoryTestCase {
b.add(ents[i]); b.add(ents[i]);
b.finish(); b.finish();
final String[] expPaths = { "a.", "a", "a0b" }; final String[] expPaths = { "a-", "a", "a0b" };
final FileMode[] expModes = { FileMode.REGULAR_FILE, FileMode.TREE, final FileMode[] expModes = { FileMode.REGULAR_FILE, FileMode.TREE,
FileMode.REGULAR_FILE }; FileMode.REGULAR_FILE };
final int expPos[] = { 0, -1, 4 }; final int expPos[] = { 0, -1, 4 };
@ -189,7 +189,7 @@ public class DirCacheIteratorTest extends RepositoryTestCase {
final DirCache dc = DirCache.newInCore(); final DirCache dc = DirCache.newInCore();
final FileMode mode = FileMode.REGULAR_FILE; 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]; final DirCacheEntry[] ents = new DirCacheEntry[paths.length];
for (int i = 0; i < paths.length; i++) { for (int i = 0; i < paths.length; i++) {
ents[i] = new DirCacheEntry(paths[i]); ents[i] = new DirCacheEntry(paths[i]);
@ -224,7 +224,7 @@ public class DirCacheIteratorTest extends RepositoryTestCase {
final DirCache dc = DirCache.newInCore(); final DirCache dc = DirCache.newInCore();
final FileMode mode = FileMode.REGULAR_FILE; 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]; final DirCacheEntry[] ents = new DirCacheEntry[paths.length];
for (int i = 0; i < paths.length; i++) { for (int i = 0; i < paths.length; i++) {
ents[i] = new DirCacheEntry(paths[i]); ents[i] = new DirCacheEntry(paths[i]);
@ -258,7 +258,7 @@ public class DirCacheIteratorTest extends RepositoryTestCase {
final DirCache dc = DirCache.newInCore(); final DirCache dc = DirCache.newInCore();
final FileMode mode = FileMode.REGULAR_FILE; 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]; final DirCacheEntry[] ents = new DirCacheEntry[paths.length];
for (int i = 0; i < paths.length; i++) { for (int i = 0; i < paths.length; i++) {
ents[i] = new DirCacheEntry(paths[i]); ents[i] = new DirCacheEntry(paths[i]);
@ -272,7 +272,7 @@ public class DirCacheIteratorTest extends RepositoryTestCase {
DirCacheIterator dci = new DirCacheIterator(dc); DirCacheIterator dci = new DirCacheIterator(dc);
assertFalse(dci.eof()); assertFalse(dci.eof());
assertEquals("a.", dci.getEntryPathString()); assertEquals("a-", dci.getEntryPathString());
dci.next(1); dci.next(1);
assertFalse(dci.eof()); assertFalse(dci.eof());
assertEquals("a", dci.getEntryPathString()); assertEquals("a", dci.getEntryPathString());
@ -285,7 +285,7 @@ public class DirCacheIteratorTest extends RepositoryTestCase {
// same entries the second time // same entries the second time
dci.reset(); dci.reset();
assertFalse(dci.eof()); assertFalse(dci.eof());
assertEquals("a.", dci.getEntryPathString()); assertEquals("a-", dci.getEntryPathString());
dci.next(1); dci.next(1);
assertFalse(dci.eof()); assertFalse(dci.eof());
assertEquals("a", dci.getEntryPathString()); assertEquals("a", dci.getEntryPathString());
@ -304,12 +304,12 @@ public class DirCacheIteratorTest extends RepositoryTestCase {
assertEquals("a", dci.getEntryPathString()); assertEquals("a", dci.getEntryPathString());
dci.back(1); dci.back(1);
assertFalse(dci.eof()); assertFalse(dci.eof());
assertEquals("a.", dci.getEntryPathString()); assertEquals("a-", dci.getEntryPathString());
assertTrue(dci.first()); assertTrue(dci.first());
// forward // forward
assertFalse(dci.eof()); assertFalse(dci.eof());
assertEquals("a.", dci.getEntryPathString()); assertEquals("a-", dci.getEntryPathString());
dci.next(1); dci.next(1);
assertFalse(dci.eof()); assertFalse(dci.eof());
assertEquals("a", dci.getEntryPathString()); assertEquals("a", dci.getEntryPathString());
@ -385,7 +385,7 @@ public class DirCacheIteratorTest extends RepositoryTestCase {
final DirCache dc = DirCache.newInCore(); final DirCache dc = DirCache.newInCore();
final FileMode mode = FileMode.REGULAR_FILE; 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]; final DirCacheEntry[] ents = new DirCacheEntry[paths.length];
for (int i = 0; i < paths.length; i++) { for (int i = 0; i < paths.length; i++) {
ents[i] = new DirCacheEntry(paths[i]); ents[i] = new DirCacheEntry(paths[i]);

8
org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCachePathEditTest.java vendored

@ -113,21 +113,23 @@ public class DirCachePathEditTest {
DirCache dc = DirCache.newInCore(); DirCache dc = DirCache.newInCore();
DirCacheEditor editor = dc.editor(); DirCacheEditor editor = dc.editor();
editor.add(new AddEdit("a/b")); editor.add(new AddEdit("a/b"));
editor.add(new AddEdit("a.")); editor.add(new AddEdit("a-"));
editor.add(new AddEdit("ab")); editor.add(new AddEdit("ab"));
editor.finish(); editor.finish();
assertEquals(3, dc.getEntryCount()); assertEquals(3, dc.getEntryCount());
// Validate sort order // Validate sort order
assertEquals("a.", dc.getEntry(0).getPathString()); assertEquals("a-", dc.getEntry(0).getPathString());
assertEquals("a/b", dc.getEntry(1).getPathString()); assertEquals("a/b", dc.getEntry(1).getPathString());
assertEquals("ab", dc.getEntry(2).getPathString()); assertEquals("ab", dc.getEntry(2).getPathString());
editor = dc.editor(); editor = dc.editor();
// Sort order should not confuse DeleteTree // Sort order should not confuse DeleteTree
editor.add(new DirCacheEditor.DeleteTree("a")); editor.add(new DirCacheEditor.DeleteTree("a"));
editor.finish(); editor.finish();
assertEquals(2, dc.getEntryCount()); assertEquals(2, dc.getEntryCount());
assertEquals("a.", dc.getEntry(0).getPathString()); assertEquals("a-", dc.getEntry(0).getPathString());
assertEquals("ab", dc.getEntry(1).getPathString()); assertEquals("ab", dc.getEntry(1).getPathString());
} }

6
org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheTreeTest.java vendored

@ -92,7 +92,7 @@ public class DirCacheTreeTest extends RepositoryTestCase {
public void testSingleSubtree() throws Exception { public void testSingleSubtree() throws Exception {
final DirCache dc = db.readDirCache(); 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]; final DirCacheEntry[] ents = new DirCacheEntry[paths.length];
for (int i = 0; i < paths.length; i++) { for (int i = 0; i < paths.length; i++) {
ents[i] = new DirCacheEntry(paths[i]); ents[i] = new DirCacheEntry(paths[i]);
@ -130,7 +130,7 @@ public class DirCacheTreeTest extends RepositoryTestCase {
public void testTwoLevelSubtree() throws Exception { public void testTwoLevelSubtree() throws Exception {
final DirCache dc = db.readDirCache(); 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]; final DirCacheEntry[] ents = new DirCacheEntry[paths.length];
for (int i = 0; i < paths.length; i++) { for (int i = 0; i < paths.length; i++) {
ents[i] = new DirCacheEntry(paths[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 A = String.format("a%2000s", "a");
final String B = String.format("b%2000s", "b"); 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]; final DirCacheEntry[] ents = new DirCacheEntry[paths.length];
for (int i = 0; i < paths.length; i++) { for (int i = 0; i < paths.length; i++) {
ents[i] = new DirCacheEntry(paths[i]); ents[i] = new DirCacheEntry(paths[i]);

458
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"); JGitTestUtil.writeTrashFile(defaultDb, "hello.txt", "master world");
git.add().addFilepattern("hello.txt").call(); git.add().addFilepattern("hello.txt").call();
git.commit().setMessage("Second commit").call(); git.commit().setMessage("Second commit").call();
addRepoToClose(defaultDb);
notDefaultDb = createWorkRepository(); notDefaultDb = createWorkRepository();
git = new Git(notDefaultDb); git = new Git(notDefaultDb);
JGitTestUtil.writeTrashFile(notDefaultDb, "world.txt", "hello"); JGitTestUtil.writeTrashFile(notDefaultDb, "world.txt", "hello");
git.add().addFilepattern("world.txt").call(); git.add().addFilepattern("world.txt").call();
git.commit().setMessage("Initial commit").call(); git.commit().setMessage("Initial commit").call();
addRepoToClose(notDefaultDb);
groupADb = createWorkRepository(); groupADb = createWorkRepository();
git = new Git(groupADb); git = new Git(groupADb);
JGitTestUtil.writeTrashFile(groupADb, "a.txt", "world"); JGitTestUtil.writeTrashFile(groupADb, "a.txt", "world");
git.add().addFilepattern("a.txt").call(); git.add().addFilepattern("a.txt").call();
git.commit().setMessage("Initial commit").call(); git.commit().setMessage("Initial commit").call();
addRepoToClose(groupADb);
groupBDb = createWorkRepository(); groupBDb = createWorkRepository();
git = new Git(groupBDb); git = new Git(groupBDb);
JGitTestUtil.writeTrashFile(groupBDb, "b.txt", "world"); JGitTestUtil.writeTrashFile(groupBDb, "b.txt", "world");
git.add().addFilepattern("b.txt").call(); git.add().addFilepattern("b.txt").call();
git.commit().setMessage("Initial commit").call(); git.commit().setMessage("Initial commit").call();
addRepoToClose(groupBDb);
resolveRelativeUris(); resolveRelativeUris();
} }
@ -239,45 +243,47 @@ public class RepoCommandTest extends RepositoryTestCase {
public void testBareRepo() throws Exception { public void testBareRepo() throws Exception {
Repository remoteDb = createBareRepository(); Repository remoteDb = createBareRepository();
Repository tempDb = createWorkRepository(); Repository tempDb = createWorkRepository();
StringBuilder xmlContent = new StringBuilder(); try {
xmlContent.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n") StringBuilder xmlContent = new StringBuilder();
.append("<manifest>") xmlContent
.append("<remote name=\"remote1\" fetch=\".\" />") .append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
.append("<default revision=\"master\" remote=\"remote1\" />") .append("<manifest>")
.append("<project path=\"foo\" name=\"") .append("<remote name=\"remote1\" fetch=\".\" />")
.append(defaultUri) .append("<default revision=\"master\" remote=\"remote1\" />")
.append("\" />") .append("<project path=\"foo\" name=\"").append(defaultUri)
.append("</manifest>"); .append("\" />").append("</manifest>");
JGitTestUtil.writeTrashFile( JGitTestUtil.writeTrashFile(tempDb, "manifest.xml",
tempDb, "manifest.xml", xmlContent.toString()); xmlContent.toString());
RepoCommand command = new RepoCommand(remoteDb); RepoCommand command = new RepoCommand(remoteDb);
command command.setPath(
.setPath(tempDb.getWorkTree().getAbsolutePath() + "/manifest.xml") tempDb.getWorkTree().getAbsolutePath() + "/manifest.xml")
.setURI(rootUri) .setURI(rootUri).call();
.call(); // Clone it
// Clone it File directory = createTempDirectory("testBareRepo");
File directory = createTempDirectory("testBareRepo"); Repository localDb = Git.cloneRepository().setDirectory(directory)
Repository localDb = Git .setURI(remoteDb.getDirectory().toURI().toString()).call()
.cloneRepository() .getRepository();
.setDirectory(directory) // The .gitmodules file should exist
.setURI(remoteDb.getDirectory().toURI().toString()) File gitmodules = new File(localDb.getWorkTree(), ".gitmodules");
.call() assertTrue("The .gitmodules file should exist", gitmodules.exists());
.getRepository(); // The first line of .gitmodules file should be expected
// The .gitmodules file should exist BufferedReader reader = new BufferedReader(new FileReader(
File gitmodules = new File(localDb.getWorkTree(), ".gitmodules"); gitmodules));
assertTrue("The .gitmodules file should exist", gitmodules.exists()); String content = reader.readLine();
// The first line of .gitmodules file should be expected reader.close();
BufferedReader reader = new BufferedReader(new FileReader(gitmodules)); assertEquals(
String content = reader.readLine(); "The first line of .gitmodules file should be as expected",
reader.close(); "[submodule \"foo\"]", content);
assertEquals( // The gitlink should be the same as remote head sha1
"The first line of .gitmodules file should be as expected", String gitlink = localDb.resolve(Constants.HEAD + ":foo").name();
"[submodule \"foo\"]", content); localDb.close();
// The gitlink should be the same as remote head sha1 String remote = defaultDb.resolve(Constants.HEAD).name();
String gitlink = localDb.resolve(Constants.HEAD + ":foo").name(); assertEquals("The gitlink should be the same as remote head",
String remote = defaultDb.resolve(Constants.HEAD).name(); remote, gitlink);
assertEquals("The gitlink should be the same as remote head", } finally {
remote, gitlink); tempDb.close();
remoteDb.close();
}
} }
@Test @Test
@ -362,213 +368,213 @@ public class RepoCommandTest extends RepositoryTestCase {
public void testRevisionBare() throws Exception { public void testRevisionBare() throws Exception {
Repository remoteDb = createBareRepository(); Repository remoteDb = createBareRepository();
Repository tempDb = createWorkRepository(); Repository tempDb = createWorkRepository();
StringBuilder xmlContent = new StringBuilder(); try {
xmlContent.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n") StringBuilder xmlContent = new StringBuilder();
.append("<manifest>") xmlContent.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
.append("<remote name=\"remote1\" fetch=\".\" />") .append("<manifest>")
.append("<default revision=\"") .append("<remote name=\"remote1\" fetch=\".\" />")
.append(BRANCH) .append("<default revision=\"").append(BRANCH)
.append("\" remote=\"remote1\" />") .append("\" remote=\"remote1\" />")
.append("<project path=\"foo\" name=\"") .append("<project path=\"foo\" name=\"").append(defaultUri)
.append(defaultUri) .append("\" />").append("</manifest>");
.append("\" />") JGitTestUtil.writeTrashFile(tempDb, "manifest.xml",
.append("</manifest>"); xmlContent.toString());
JGitTestUtil.writeTrashFile( RepoCommand command = new RepoCommand(remoteDb);
tempDb, "manifest.xml", xmlContent.toString()); command.setPath(
RepoCommand command = new RepoCommand(remoteDb); tempDb.getWorkTree().getAbsolutePath() + "/manifest.xml")
command .setURI(rootUri).call();
.setPath(tempDb.getWorkTree().getAbsolutePath() + "/manifest.xml") // Clone it
.setURI(rootUri) File directory = createTempDirectory("testRevisionBare");
.call(); Repository localDb = Git.cloneRepository().setDirectory(directory)
// Clone it .setURI(remoteDb.getDirectory().toURI().toString()).call()
File directory = createTempDirectory("testRevisionBare"); .getRepository();
Repository localDb = Git // The gitlink should be the same as oldCommitId
.cloneRepository() String gitlink = localDb.resolve(Constants.HEAD + ":foo").name();
.setDirectory(directory) localDb.close();
.setURI(remoteDb.getDirectory().toURI().toString()) assertEquals("The gitlink is same as remote head",
.call() oldCommitId.name(), gitlink);
.getRepository(); } finally {
// The gitlink should be the same as oldCommitId tempDb.close();
String gitlink = localDb.resolve(Constants.HEAD + ":foo").name(); remoteDb.close();
assertEquals("The gitlink is same as remote head", }
oldCommitId.name(), gitlink);
} }
@Test @Test
public void testCopyFileBare() throws Exception { public void testCopyFileBare() throws Exception {
Repository remoteDb = createBareRepository(); Repository remoteDb = createBareRepository();
Repository tempDb = createWorkRepository(); Repository tempDb = createWorkRepository();
StringBuilder xmlContent = new StringBuilder(); try {
xmlContent.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n") StringBuilder xmlContent = new StringBuilder();
.append("<manifest>") xmlContent
.append("<remote name=\"remote1\" fetch=\".\" />") .append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
.append("<default revision=\"master\" remote=\"remote1\" />") .append("<manifest>")
.append("<project path=\"foo\" name=\"") .append("<remote name=\"remote1\" fetch=\".\" />")
.append(defaultUri) .append("<default revision=\"master\" remote=\"remote1\" />")
.append("\" revision=\"") .append("<project path=\"foo\" name=\"").append(defaultUri)
.append(BRANCH) .append("\" revision=\"").append(BRANCH).append("\" >")
.append("\" >") .append("<copyfile src=\"hello.txt\" dest=\"Hello\" />")
.append("<copyfile src=\"hello.txt\" dest=\"Hello\" />") .append("</project>").append("</manifest>");
.append("</project>") JGitTestUtil.writeTrashFile(tempDb, "manifest.xml",
.append("</manifest>"); xmlContent.toString());
JGitTestUtil.writeTrashFile( RepoCommand command = new RepoCommand(remoteDb);
tempDb, "manifest.xml", xmlContent.toString()); command.setPath(
RepoCommand command = new RepoCommand(remoteDb); tempDb.getWorkTree().getAbsolutePath() + "/manifest.xml")
command .setURI(rootUri).call();
.setPath(tempDb.getWorkTree().getAbsolutePath() + "/manifest.xml") // Clone it
.setURI(rootUri) File directory = createTempDirectory("testCopyFileBare");
.call(); Repository localDb = Git.cloneRepository().setDirectory(directory)
// Clone it .setURI(remoteDb.getDirectory().toURI().toString()).call()
File directory = createTempDirectory("testCopyFileBare"); .getRepository();
Repository localDb = Git // The Hello file should exist
.cloneRepository() File hello = new File(localDb.getWorkTree(), "Hello");
.setDirectory(directory) localDb.close();
.setURI(remoteDb.getDirectory().toURI().toString()) assertTrue("The Hello file should exist", hello.exists());
.call() // The content of Hello file should be expected
.getRepository(); BufferedReader reader = new BufferedReader(new FileReader(hello));
// The Hello file should exist String content = reader.readLine();
File hello = new File(localDb.getWorkTree(), "Hello"); reader.close();
assertTrue("The Hello file should exist", hello.exists()); assertEquals("The Hello file should have expected content",
// The content of Hello file should be expected "branch world", content);
BufferedReader reader = new BufferedReader(new FileReader(hello)); } finally {
String content = reader.readLine(); tempDb.close();
reader.close(); remoteDb.close();
assertEquals("The Hello file should have expected content", }
"branch world", content);
} }
@Test @Test
public void testReplaceManifestBare() throws Exception { public void testReplaceManifestBare() throws Exception {
Repository remoteDb = createBareRepository(); Repository remoteDb = createBareRepository();
Repository tempDb = createWorkRepository(); Repository tempDb = createWorkRepository();
StringBuilder xmlContent = new StringBuilder(); try {
xmlContent.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n") StringBuilder xmlContent = new StringBuilder();
.append("<manifest>") xmlContent
.append("<remote name=\"remote1\" fetch=\".\" />") .append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
.append("<default revision=\"master\" remote=\"remote1\" />") .append("<manifest>")
.append("<project path=\"foo\" name=\"") .append("<remote name=\"remote1\" fetch=\".\" />")
.append(defaultUri) .append("<default revision=\"master\" remote=\"remote1\" />")
.append("\" revision=\"") .append("<project path=\"foo\" name=\"").append(defaultUri)
.append(BRANCH) .append("\" revision=\"").append(BRANCH).append("\" >")
.append("\" >") .append("<copyfile src=\"hello.txt\" dest=\"Hello\" />")
.append("<copyfile src=\"hello.txt\" dest=\"Hello\" />") .append("</project>").append("</manifest>");
.append("</project>") JGitTestUtil.writeTrashFile(tempDb, "old.xml",
.append("</manifest>"); xmlContent.toString());
JGitTestUtil.writeTrashFile(tempDb, "old.xml", xmlContent.toString()); RepoCommand command = new RepoCommand(remoteDb);
RepoCommand command = new RepoCommand(remoteDb); command.setPath(tempDb.getWorkTree().getAbsolutePath() + "/old.xml")
command.setPath(tempDb.getWorkTree().getAbsolutePath() + "/old.xml") .setURI(rootUri).call();
.setURI(rootUri) xmlContent = new StringBuilder();
.call(); xmlContent
xmlContent = new StringBuilder(); .append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
xmlContent.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n") .append("<manifest>")
.append("<manifest>") .append("<remote name=\"remote1\" fetch=\".\" />")
.append("<remote name=\"remote1\" fetch=\".\" />") .append("<default revision=\"master\" remote=\"remote1\" />")
.append("<default revision=\"master\" remote=\"remote1\" />") .append("<project path=\"bar\" name=\"")
.append("<project path=\"bar\" name=\"") .append(defaultUri)
.append(defaultUri) .append("\" revision=\"")
.append("\" revision=\"") .append(BRANCH)
.append(BRANCH) .append("\" >")
.append("\" >") .append("<copyfile src=\"hello.txt\" dest=\"Hello.txt\" />")
.append("<copyfile src=\"hello.txt\" dest=\"Hello.txt\" />") .append("</project>").append("</manifest>");
.append("</project>") JGitTestUtil.writeTrashFile(tempDb, "new.xml",
.append("</manifest>"); xmlContent.toString());
JGitTestUtil.writeTrashFile(tempDb, "new.xml", xmlContent.toString()); command = new RepoCommand(remoteDb);
command = new RepoCommand(remoteDb); command.setPath(tempDb.getWorkTree().getAbsolutePath() + "/new.xml")
command.setPath(tempDb.getWorkTree().getAbsolutePath() + "/new.xml") .setURI(rootUri).call();
.setURI(rootUri) // Clone it
.call(); File directory = createTempDirectory("testReplaceManifestBare");
// Clone it Repository localDb = Git.cloneRepository().setDirectory(directory)
File directory = createTempDirectory("testReplaceManifestBare"); .setURI(remoteDb.getDirectory().toURI().toString()).call()
Repository localDb = Git .getRepository();
.cloneRepository() // The Hello file should not exist
.setDirectory(directory) File hello = new File(localDb.getWorkTree(), "Hello");
.setURI(remoteDb.getDirectory().toURI().toString()) assertFalse("The Hello file shouldn't exist", hello.exists());
.call() // The Hello.txt file should exist
.getRepository(); File hellotxt = new File(localDb.getWorkTree(), "Hello.txt");
// The Hello file should not exist assertTrue("The Hello.txt file should exist", hellotxt.exists());
File hello = new File(localDb.getWorkTree(), "Hello"); // The .gitmodules file should have 'submodule "bar"' and shouldn't
assertFalse("The Hello file shouldn't exist", hello.exists()); // have
// The Hello.txt file should exist // 'submodule "foo"' lines.
File hellotxt = new File(localDb.getWorkTree(), "Hello.txt"); File dotmodules = new File(localDb.getWorkTree(),
assertTrue("The Hello.txt file should exist", hellotxt.exists()); Constants.DOT_GIT_MODULES);
// The .gitmodules file should have 'submodule "bar"' and shouldn't have localDb.close();
// 'submodule "foo"' lines. BufferedReader reader = new BufferedReader(new FileReader(
File dotmodules = new File(localDb.getWorkTree(), dotmodules));
Constants.DOT_GIT_MODULES); boolean foo = false;
BufferedReader reader = new BufferedReader(new FileReader(dotmodules)); boolean bar = false;
boolean foo = false; while (true) {
boolean bar = false; String line = reader.readLine();
while (true) { if (line == null)
String line = reader.readLine(); break;
if (line == null) if (line.contains("submodule \"foo\""))
break; foo = true;
if (line.contains("submodule \"foo\"")) if (line.contains("submodule \"bar\""))
foo = true; bar = 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 @Test
public void testRemoveOverlappingBare() throws Exception { public void testRemoveOverlappingBare() throws Exception {
Repository remoteDb = createBareRepository(); Repository remoteDb = createBareRepository();
Repository tempDb = createWorkRepository(); Repository tempDb = createWorkRepository();
StringBuilder xmlContent = new StringBuilder(); try {
xmlContent.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n") StringBuilder xmlContent = new StringBuilder();
.append("<manifest>") xmlContent
.append("<remote name=\"remote1\" fetch=\".\" />") .append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
.append("<default revision=\"master\" remote=\"remote1\" />") .append("<manifest>")
.append("<project path=\"foo/bar\" name=\"") .append("<remote name=\"remote1\" fetch=\".\" />")
.append(groupBUri) .append("<default revision=\"master\" remote=\"remote1\" />")
.append("\" />") .append("<project path=\"foo/bar\" name=\"")
.append("<project path=\"a\" name=\"") .append(groupBUri).append("\" />")
.append(groupAUri) .append("<project path=\"a\" name=\"").append(groupAUri)
.append("\" />") .append("\" />").append("<project path=\"foo\" name=\"")
.append("<project path=\"foo\" name=\"") .append(defaultUri).append("\" />").append("</manifest>");
.append(defaultUri) JGitTestUtil.writeTrashFile(tempDb, "manifest.xml",
.append("\" />") xmlContent.toString());
.append("</manifest>"); RepoCommand command = new RepoCommand(remoteDb);
JGitTestUtil.writeTrashFile( command.setPath(
tempDb, "manifest.xml", xmlContent.toString()); tempDb.getWorkTree().getAbsolutePath() + "/manifest.xml")
RepoCommand command = new RepoCommand(remoteDb); .setURI(rootUri).call();
command // Clone it
.setPath(tempDb.getWorkTree().getAbsolutePath() + "/manifest.xml") File directory = createTempDirectory("testRemoveOverlappingBare");
.setURI(rootUri) Repository localDb = Git.cloneRepository().setDirectory(directory)
.call(); .setURI(remoteDb.getDirectory().toURI().toString()).call()
// Clone it .getRepository();
File directory = createTempDirectory("testRemoveOverlappingBare"); // The .gitmodules file should have 'submodule "foo"' and shouldn't
Repository localDb = Git // have
.cloneRepository() // 'submodule "foo/bar"' lines.
.setDirectory(directory) File dotmodules = new File(localDb.getWorkTree(),
.setURI(remoteDb.getDirectory().toURI().toString()) Constants.DOT_GIT_MODULES);
.call() localDb.close();
.getRepository(); BufferedReader reader = new BufferedReader(new FileReader(
// The .gitmodules file should have 'submodule "foo"' and shouldn't have dotmodules));
// 'submodule "foo/bar"' lines. boolean foo = false;
File dotmodules = new File(localDb.getWorkTree(), boolean foobar = false;
Constants.DOT_GIT_MODULES); boolean a = false;
BufferedReader reader = new BufferedReader(new FileReader(dotmodules)); while (true) {
boolean foo = false; String line = reader.readLine();
boolean foobar = false; if (line == null)
boolean a = false; break;
while (true) { if (line.contains("submodule \"foo\""))
String line = reader.readLine(); foo = true;
if (line == null) if (line.contains("submodule \"foo/bar\""))
break; foobar = true;
if (line.contains("submodule \"foo\"")) if (line.contains("submodule \"a\""))
foo = true; a = true;
if (line.contains("submodule \"foo/bar\"")) }
foobar = true; reader.close();
if (line.contains("submodule \"a\"")) assertTrue("The foo submodule should exist", foo);
a = true; 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 @Test

10
org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/DirCacheCheckoutMaliciousPathTest.java

@ -186,10 +186,7 @@ public class DirCacheCheckoutMaliciousPathTest extends RepositoryTestCase {
@Test @Test
public void testMaliciousGitPathEndSpaceUnixOk() throws Exception { public void testMaliciousGitPathEndSpaceUnixOk() throws Exception {
if (File.separatorChar == '\\') testMaliciousPathBadFirstCheckout(".git ", "konfig");
return; // cannot emulate Unix on Windows for this test
((MockSystemReader) SystemReader.getInstance()).setUnix();
testMaliciousPathGoodFirstCheckout(".git ", "konfig");
} }
@Test @Test
@ -212,10 +209,7 @@ public class DirCacheCheckoutMaliciousPathTest extends RepositoryTestCase {
@Test @Test
public void testMaliciousGitPathEndDotUnixOk() throws Exception { public void testMaliciousGitPathEndDotUnixOk() throws Exception {
if (File.separatorChar == '\\') testMaliciousPathBadFirstCheckout(".git.", "konfig");
return; // cannot emulate Unix on Windows for this test
((MockSystemReader) SystemReader.getInstance()).setUnix();
testMaliciousPathGoodFirstCheckout(".git.", "konfig");
} }
@Test @Test

2
org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/IndexDiffSubmoduleTest.java

@ -90,7 +90,9 @@ public class IndexDiffSubmoduleTest extends RepositoryTestCase {
.setPath("submodule") .setPath("submodule")
.setURI(submoduleStandalone.getDirectory().toURI().toString()) .setURI(submoduleStandalone.getDirectory().toURI().toString())
.call(); .call();
submoduleStandalone.close();
submodule_trash = submodule_db.getWorkTree(); submodule_trash = submodule_db.getWorkTree();
addRepoToClose(submodule_db);
writeTrashFile("fileInRoot", "root"); writeTrashFile("fileInRoot", "root");
Git rootGit = Git.wrap(db); Git rootGit = Git.wrap(db);
rootGit.add().addFilepattern("fileInRoot").call(); rootGit.add().addFilepattern("fileInRoot").call();

247
org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ObjectCheckerTest.java

@ -1295,12 +1295,11 @@ public class ObjectCheckerTest {
} }
@Test @Test
public void testInvalidTreeNameIsMixedCaseGitWindows() { public void testInvalidTreeNameIsMixedCaseGit() {
StringBuilder b = new StringBuilder(); StringBuilder b = new StringBuilder();
entry(b, "100644 .GiT"); entry(b, "100644 .GiT");
byte[] data = Constants.encodeASCII(b.toString()); byte[] data = Constants.encodeASCII(b.toString());
try { try {
checker.setSafeForWindows(true);
checker.checkTree(data); checker.checkTree(data);
fail("incorrectly accepted an invalid tree"); fail("incorrectly accepted an invalid tree");
} catch (CorruptObjectException e) { } catch (CorruptObjectException e) {
@ -1309,19 +1308,255 @@ public class ObjectCheckerTest {
} }
@Test @Test
public void testInvalidTreeNameIsMixedCaseGitMacOS() { public void testInvalidTreeNameIsMacHFSGit() {
StringBuilder b = new StringBuilder(); StringBuilder b = new StringBuilder();
entry(b, "100644 .GiT"); entry(b, "100644 .gi\u200Ct");
byte[] data = Constants.encodeASCII(b.toString()); byte[] data = Constants.encode(b.toString());
try { try {
checker.setSafeForMacOS(true); checker.setSafeForMacOS(true);
checker.checkTree(data); checker.checkTree(data);
fail("incorrectly accepted an invalid tree"); fail("incorrectly accepted an invalid tree");
} catch (CorruptObjectException e) { } 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 @Test
public void testInvalidTreeTruncatedInName() { public void testInvalidTreeTruncatedInName() {
final StringBuilder b = new StringBuilder(); final StringBuilder b = new StringBuilder();

9
org.eclipse.jgit.test/tst/org/eclipse/jgit/submodule/SubmoduleAddTest.java

@ -131,7 +131,8 @@ public class SubmoduleAddTest extends RepositoryTestCase {
command.setURI(uri); command.setURI(uri);
Repository repo = command.call(); Repository repo = command.call();
assertNotNull(repo); assertNotNull(repo);
addRepoToClose(repo); ObjectId subCommit = repo.resolve(Constants.HEAD);
repo.close();
SubmoduleWalk generator = SubmoduleWalk.forIndex(db); SubmoduleWalk generator = SubmoduleWalk.forIndex(db);
assertTrue(generator.next()); assertTrue(generator.next());
@ -141,9 +142,9 @@ public class SubmoduleAddTest extends RepositoryTestCase {
assertEquals(path, generator.getModulesPath()); assertEquals(path, generator.getModulesPath());
assertEquals(uri, generator.getConfigUrl()); assertEquals(uri, generator.getConfigUrl());
Repository subModRepo = generator.getRepository(); Repository subModRepo = generator.getRepository();
addRepoToClose(subModRepo);
assertNotNull(subModRepo); assertNotNull(subModRepo);
assertEquals(commit, repo.resolve(Constants.HEAD)); assertEquals(subCommit, commit);
subModRepo.close();
Status status = Git.wrap(db).status().call(); Status status = Git.wrap(db).status().call();
assertTrue(status.getAdded().contains(Constants.DOT_GIT_MODULES)); assertTrue(status.getAdded().contains(Constants.DOT_GIT_MODULES));
@ -206,7 +207,6 @@ public class SubmoduleAddTest extends RepositoryTestCase {
fullUri = fullUri.replace('\\', '/'); fullUri = fullUri.replace('\\', '/');
assertEquals(fullUri, generator.getConfigUrl()); assertEquals(fullUri, generator.getConfigUrl());
Repository subModRepo = generator.getRepository(); Repository subModRepo = generator.getRepository();
addRepoToClose(subModRepo);
assertNotNull(subModRepo); assertNotNull(subModRepo);
assertEquals( assertEquals(
fullUri, fullUri,
@ -215,6 +215,7 @@ public class SubmoduleAddTest extends RepositoryTestCase {
.getString(ConfigConstants.CONFIG_REMOTE_SECTION, .getString(ConfigConstants.CONFIG_REMOTE_SECTION,
Constants.DEFAULT_REMOTE_NAME, Constants.DEFAULT_REMOTE_NAME,
ConfigConstants.CONFIG_KEY_URL)); ConfigConstants.CONFIG_KEY_URL));
subModRepo.close();
assertEquals(commit, repo.resolve(Constants.HEAD)); assertEquals(commit, repo.resolve(Constants.HEAD));
Status status = Git.wrap(db).status().call(); Status status = Git.wrap(db).status().call();

4
org.eclipse.jgit.test/tst/org/eclipse/jgit/submodule/SubmoduleSyncTest.java

@ -135,8 +135,8 @@ public class SubmoduleSyncTest extends RepositoryTestCase {
assertTrue(generator.next()); assertTrue(generator.next());
assertEquals(url, generator.getConfigUrl()); assertEquals(url, generator.getConfigUrl());
Repository subModRepository = generator.getRepository(); Repository subModRepository = generator.getRepository();
addRepoToClose(subModRepository);
StoredConfig submoduleConfig = subModRepository.getConfig(); StoredConfig submoduleConfig = subModRepository.getConfig();
subModRepository.close();
assertEquals(url, submoduleConfig.getString( assertEquals(url, submoduleConfig.getString(
ConfigConstants.CONFIG_REMOTE_SECTION, ConfigConstants.CONFIG_REMOTE_SECTION,
Constants.DEFAULT_REMOTE_NAME, ConfigConstants.CONFIG_KEY_URL)); Constants.DEFAULT_REMOTE_NAME, ConfigConstants.CONFIG_KEY_URL));
@ -207,8 +207,8 @@ public class SubmoduleSyncTest extends RepositoryTestCase {
assertTrue(generator.next()); assertTrue(generator.next());
assertEquals("git://server/sub.git", generator.getConfigUrl()); assertEquals("git://server/sub.git", generator.getConfigUrl());
Repository subModRepository1 = generator.getRepository(); Repository subModRepository1 = generator.getRepository();
addRepoToClose(subModRepository1);
StoredConfig submoduleConfig = subModRepository1.getConfig(); StoredConfig submoduleConfig = subModRepository1.getConfig();
subModRepository1.close();
assertEquals("git://server/sub.git", submoduleConfig.getString( assertEquals("git://server/sub.git", submoduleConfig.getString(
ConfigConstants.CONFIG_REMOTE_SECTION, ConfigConstants.CONFIG_REMOTE_SECTION,
Constants.DEFAULT_REMOTE_NAME, ConfigConstants.CONFIG_KEY_URL)); Constants.DEFAULT_REMOTE_NAME, ConfigConstants.CONFIG_KEY_URL));

2
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); SubmoduleWalk generator = SubmoduleWalk.forIndex(db);
assertTrue(generator.next()); assertTrue(generator.next());
Repository subRepo = generator.getRepository(); Repository subRepo = generator.getRepository();
addRepoToClose(subRepo);
assertNotNull(subRepo); assertNotNull(subRepo);
assertEquals(commit, subRepo.resolve(Constants.HEAD)); assertEquals(commit, subRepo.resolve(Constants.HEAD));
subRepo.close();
} }
@Test @Test

4
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.getModulesUpdate());
assertNull(gen.getModulesUrl()); assertNull(gen.getModulesUrl());
Repository subRepo = gen.getRepository(); Repository subRepo = gen.getRepository();
addRepoToClose(subRepo);
assertNotNull(subRepo); assertNotNull(subRepo);
assertEquals(modulesGitDir.getAbsolutePath(), assertEquals(modulesGitDir.getAbsolutePath(),
subRepo.getDirectory().getAbsolutePath()); subRepo.getDirectory().getAbsolutePath());
assertEquals(new File(db.getWorkTree(), path).getAbsolutePath(), assertEquals(new File(db.getWorkTree(), path).getAbsolutePath(),
subRepo.getWorkTree().getAbsolutePath()); subRepo.getWorkTree().getAbsolutePath());
subRepo.close();
assertFalse(gen.next()); assertFalse(gen.next());
} }
@ -227,11 +227,11 @@ public class SubmoduleWalkTest extends RepositoryTestCase {
assertNull(gen.getModulesUpdate()); assertNull(gen.getModulesUpdate());
assertNull(gen.getModulesUrl()); assertNull(gen.getModulesUrl());
Repository subRepo = gen.getRepository(); Repository subRepo = gen.getRepository();
addRepoToClose(subRepo);
assertNotNull(subRepo); assertNotNull(subRepo);
assertEqualsFile(modulesGitDir, subRepo.getDirectory()); assertEqualsFile(modulesGitDir, subRepo.getDirectory());
assertEqualsFile(new File(db.getWorkTree(), path), assertEqualsFile(new File(db.getWorkTree(), path),
subRepo.getWorkTree()); subRepo.getWorkTree());
subRepo.close();
assertFalse(gen.next()); assertFalse(gen.next());
} }

2
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 // less obvious due to git sorting order
filter.include(fakeWalk("d.")); filter.include(fakeWalk("d-"));
// less obvious due to git sorting order // less obvious due to git sorting order
try { try {

24
org.eclipse.jgit.test/tst/org/eclipse/jgit/util/TemporaryBufferTest.java

@ -59,7 +59,7 @@ import org.junit.Test;
public class TemporaryBufferTest { public class TemporaryBufferTest {
@Test @Test
public void testEmpty() throws IOException { public void testEmpty() throws IOException {
final TemporaryBuffer b = new TemporaryBuffer.LocalFile(); final TemporaryBuffer b = new TemporaryBuffer.LocalFile(null);
try { try {
b.close(); b.close();
assertEquals(0, b.length()); assertEquals(0, b.length());
@ -73,7 +73,7 @@ public class TemporaryBufferTest {
@Test @Test
public void testOneByte() throws IOException { 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(); final byte test = (byte) new TestRng(getName()).nextInt();
try { try {
b.write(test); b.write(test);
@ -100,7 +100,7 @@ public class TemporaryBufferTest {
@Test @Test
public void testOneBlock_BulkWrite() throws IOException { 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()) final byte[] test = new TestRng(getName())
.nextBytes(TemporaryBuffer.Block.SZ); .nextBytes(TemporaryBuffer.Block.SZ);
try { try {
@ -131,7 +131,7 @@ public class TemporaryBufferTest {
@Test @Test
public void testOneBlockAndHalf_BulkWrite() throws IOException { 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()) final byte[] test = new TestRng(getName())
.nextBytes(TemporaryBuffer.Block.SZ * 3 / 2); .nextBytes(TemporaryBuffer.Block.SZ * 3 / 2);
try { try {
@ -162,7 +162,7 @@ public class TemporaryBufferTest {
@Test @Test
public void testOneBlockAndHalf_SingleWrite() throws IOException { 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()) final byte[] test = new TestRng(getName())
.nextBytes(TemporaryBuffer.Block.SZ * 3 / 2); .nextBytes(TemporaryBuffer.Block.SZ * 3 / 2);
try { try {
@ -191,7 +191,7 @@ public class TemporaryBufferTest {
@Test @Test
public void testOneBlockAndHalf_Copy() throws IOException { 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()) final byte[] test = new TestRng(getName())
.nextBytes(TemporaryBuffer.Block.SZ * 3 / 2); .nextBytes(TemporaryBuffer.Block.SZ * 3 / 2);
try { try {
@ -221,7 +221,7 @@ public class TemporaryBufferTest {
@Test @Test
public void testLarge_SingleWrite() throws IOException { 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()) final byte[] test = new TestRng(getName())
.nextBytes(TemporaryBuffer.DEFAULT_IN_CORE_LIMIT * 3); .nextBytes(TemporaryBuffer.DEFAULT_IN_CORE_LIMIT * 3);
try { try {
@ -263,7 +263,7 @@ public class TemporaryBufferTest {
@Test @Test
public void testInCoreLimit_SwitchOnAppendByte() throws IOException { 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()) final byte[] test = new TestRng(getName())
.nextBytes(TemporaryBuffer.DEFAULT_IN_CORE_LIMIT + 1); .nextBytes(TemporaryBuffer.DEFAULT_IN_CORE_LIMIT + 1);
try { try {
@ -292,7 +292,7 @@ public class TemporaryBufferTest {
@Test @Test
public void testInCoreLimit_SwitchBeforeAppendByte() throws IOException { 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()) final byte[] test = new TestRng(getName())
.nextBytes(TemporaryBuffer.DEFAULT_IN_CORE_LIMIT * 3); .nextBytes(TemporaryBuffer.DEFAULT_IN_CORE_LIMIT * 3);
try { try {
@ -321,7 +321,7 @@ public class TemporaryBufferTest {
@Test @Test
public void testInCoreLimit_SwitchOnCopy() throws IOException { 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()) final byte[] test = new TestRng(getName())
.nextBytes(TemporaryBuffer.DEFAULT_IN_CORE_LIMIT * 2); .nextBytes(TemporaryBuffer.DEFAULT_IN_CORE_LIMIT * 2);
try { try {
@ -354,7 +354,7 @@ public class TemporaryBufferTest {
@Test @Test
public void testDestroyWhileOpen() throws IOException { public void testDestroyWhileOpen() throws IOException {
@SuppressWarnings("resource" /* java 7 */) @SuppressWarnings("resource" /* java 7 */)
final TemporaryBuffer b = new TemporaryBuffer.LocalFile(); final TemporaryBuffer b = new TemporaryBuffer.LocalFile(null);
try { try {
b.write(new TestRng(getName()) b.write(new TestRng(getName())
.nextBytes(TemporaryBuffer.DEFAULT_IN_CORE_LIMIT * 2)); .nextBytes(TemporaryBuffer.DEFAULT_IN_CORE_LIMIT * 2));
@ -365,7 +365,7 @@ public class TemporaryBufferTest {
@Test @Test
public void testRandomWrites() throws IOException { 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 TestRng rng = new TestRng(getName());
final int max = TemporaryBuffer.DEFAULT_IN_CORE_LIMIT * 2; final int max = TemporaryBuffer.DEFAULT_IN_CORE_LIMIT * 2;
final byte[] expect = new byte[max]; final byte[] expect = new byte[max];

2
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 indexFileIsTooLargeForJgit=Index file is too large for jgit
indexSignatureIsInvalid=Index signature is invalid: {0} indexSignatureIsInvalid=Index signature is invalid: {0}
indexWriteException=Modified index could not be written 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 inMemoryBufferLimitExceeded=In-memory buffer limit exceeded
inputStreamMustSupportMark=InputStream must support mark() inputStreamMustSupportMark=InputStream must support mark()
integerValueOutOfRange=Integer value {0}.{1} out of range integerValueOutOfRange=Integer value {0}.{1} out of range

11
org.eclipse.jgit/src/org/eclipse/jgit/api/CheckoutCommand.java

@ -405,14 +405,17 @@ public class CheckoutCommand extends GitCommand<Ref> {
DirCacheIterator dci = new DirCacheIterator(dc); DirCacheIterator dci = new DirCacheIterator(dc);
treeWalk.addTree(dci); treeWalk.addTree(dci);
String previousPath = null;
final ObjectReader r = treeWalk.getObjectReader(); final ObjectReader r = treeWalk.getObjectReader();
DirCacheEditor editor = dc.editor(); DirCacheEditor editor = dc.editor();
while (treeWalk.next()) { while (treeWalk.next()) {
DirCacheEntry entry = dci.getDirCacheEntry(); String path = treeWalk.getPathString();
// Only add one edit per path // Only add one edit per path
if (entry != null && entry.getStage() > DirCacheEntry.STAGE_1) if (path.equals(previousPath))
continue; continue;
editor.add(new PathEdit(treeWalk.getPathString()) {
editor.add(new PathEdit(path) {
public void apply(DirCacheEntry ent) { public void apply(DirCacheEntry ent) {
int stage = ent.getStage(); int stage = ent.getStage();
if (stage > DirCacheEntry.STAGE_0) { if (stage > DirCacheEntry.STAGE_0) {
@ -429,6 +432,8 @@ public class CheckoutCommand extends GitCommand<Ref> {
} }
} }
}); });
previousPath = path;
} }
editor.commit(); editor.commit();
} }

63
org.eclipse.jgit/src/org/eclipse/jgit/api/CloneCommand.java

@ -86,6 +86,8 @@ public class CloneCommand extends TransportCommand<CloneCommand, Git> {
private File directory; private File directory;
private File gitDir;
private boolean bare; private boolean bare;
private String remote = Constants.DEFAULT_REMOTE_NAME; private String remote = Constants.DEFAULT_REMOTE_NAME;
@ -137,12 +139,19 @@ public class CloneCommand extends TransportCommand<CloneCommand, Git> {
private Repository init(URIish u) throws GitAPIException { private Repository init(URIish u) throws GitAPIException {
InitCommand command = Git.init(); InitCommand command = Git.init();
command.setBare(bare); command.setBare(bare);
if (directory == null) if (directory == null && gitDir == null)
directory = new File(u.getHumanishName(), Constants.DOT_GIT); 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( throw new JGitInternalException(MessageFormat.format(
JGitText.get().cloneNonEmptyDirectory, directory.getName())); 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(); return command.call().getRepository();
} }
@ -336,18 +345,47 @@ public class CloneCommand extends TransportCommand<CloneCommand, Git> {
* @param directory * @param directory
* the directory to clone to * the directory to clone to
* @return this instance * @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) { public CloneCommand setDirectory(File directory) {
validateDirs(directory, gitDir, bare);
this.directory = directory; this.directory = directory;
return this; 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 * @param bare
* whether the cloned repository is bare or not * whether the cloned repository is bare or not
* @return this instance * @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; this.bare = bare;
return this; return this;
} }
@ -438,4 +476,21 @@ public class CloneCommand extends TransportCommand<CloneCommand, Git> {
this.noCheckout = noCheckout; this.noCheckout = noCheckout;
return this; 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));
}
}
}
} }

88
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.File;
import java.io.IOException; import java.io.IOException;
import java.text.MessageFormat;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
import org.eclipse.jgit.api.errors.GitAPIException; import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.api.errors.JGitInternalException; import org.eclipse.jgit.api.errors.JGitInternalException;
import org.eclipse.jgit.internal.JGitText;
import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.lib.RepositoryBuilder; import org.eclipse.jgit.lib.RepositoryBuilder;
import org.eclipse.jgit.util.SystemReader;
/** /**
* Create an empty git repository or reinitalize an existing one * 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<Git> { public class InitCommand implements Callable<Git> {
private File directory; private File directory;
private File gitDir;
private boolean bare; private boolean bare;
/** /**
@ -74,18 +79,36 @@ public class InitCommand implements Callable<Git> {
if (bare) if (bare)
builder.setBare(); builder.setBare();
builder.readEnvironment(); builder.readEnvironment();
if (gitDir != null)
builder.setGitDir(gitDir);
else
gitDir = builder.getGitDir();
if (directory != null) { if (directory != null) {
File d = directory; if (bare)
if (!bare) builder.setGitDir(directory);
d = new File(d, Constants.DOT_GIT); else {
builder.setGitDir(d); builder.setWorkTree(directory);
if (gitDir == null)
builder.setGitDir(new File(directory, Constants.DOT_GIT));
}
} else if (builder.getGitDir() == null) { } else if (builder.getGitDir() == null) {
File d = new File("."); //$NON-NLS-1$ String dStr = SystemReader.getInstance()
if (d.getParentFile() != null) .getProperty("user.dir"); //$NON-NLS-1$
d = d.getParentFile(); if (dStr == null)
dStr = "."; //$NON-NLS-1$
File d = new File(dStr);
if (!bare) if (!bare)
d = new File(d, Constants.DOT_GIT); d = new File(d, Constants.DOT_GIT);
builder.setGitDir(d); 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(); Repository repository = builder.build();
if (!repository.getObjectDatabase().exists()) if (!repository.getObjectDatabase().exists())
@ -103,20 +126,67 @@ public class InitCommand implements Callable<Git> {
* @param directory * @param directory
* the directory to init to * the directory to init to
* @return this instance * @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; this.directory = directory;
return this; 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 * @param bare
* whether the repository is bare or not * 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 * @return this instance
*/ */
public InitCommand setBare(boolean bare) { public InitCommand setBare(boolean bare) {
validateDirs(directory, gitDir, bare);
this.bare = bare; this.bare = bare;
return this; return this;
} }
} }

4
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.GitAPIException;
import org.eclipse.jgit.api.errors.InvalidRefNameException; import org.eclipse.jgit.api.errors.InvalidRefNameException;
import org.eclipse.jgit.api.errors.RefNotFoundException;
import org.eclipse.jgit.internal.JGitText; import org.eclipse.jgit.internal.JGitText;
import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.ReflogEntry; import org.eclipse.jgit.lib.ReflogEntry;
@ -97,6 +98,9 @@ public class ReflogCommand extends GitCommand<Collection<ReflogEntry>> {
try { try {
ReflogReader reader = repo.getReflogReader(ref); ReflogReader reader = repo.getReflogReader(ref);
if (reader == null)
throw new RefNotFoundException(MessageFormat.format(
JGitText.get().refNotResolved, ref));
return reader.getReverseEntries(); return reader.getReverseEntries();
} catch (IOException e) { } catch (IOException e) {
throw new InvalidRefNameException(MessageFormat.format( throw new InvalidRefNameException(MessageFormat.format(

3
org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleUpdateCommand.java

@ -42,6 +42,7 @@
*/ */
package org.eclipse.jgit.api; package org.eclipse.jgit.api;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
@ -163,6 +164,8 @@ public class SubmoduleUpdateCommand extends
configure(clone); configure(clone);
clone.setURI(url); clone.setURI(url);
clone.setDirectory(generator.getDirectory()); clone.setDirectory(generator.getDirectory());
clone.setGitDir(new File(new File(repo.getDirectory(),
Constants.MODULES), generator.getPath()));
if (monitor != null) if (monitor != null)
clone.setProgressMonitor(monitor); clone.setProgressMonitor(monitor);
submoduleRepo = clone.call().getRepository(); submoduleRepo = clone.call().getRepository();

25
org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCache.java vendored

@ -607,7 +607,8 @@ public class DirCache {
final LockFile tmp = myLock; final LockFile tmp = myLock;
requireLocked(tmp); requireLocked(tmp);
try { try {
writeTo(new SafeBufferedOutputStream(tmp.getOutputStream())); writeTo(liveFile.getParentFile(),
new SafeBufferedOutputStream(tmp.getOutputStream()));
} catch (IOException err) { } catch (IOException err) {
tmp.unlock(); tmp.unlock();
throw err; 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 MessageDigest foot = Constants.newMessageDigest();
final DigestOutputStream dos = new DigestOutputStream(os, foot); final DigestOutputStream dos = new DigestOutputStream(os, foot);
@ -670,14 +671,18 @@ public class DirCache {
} }
if (writeTree) { if (writeTree) {
final TemporaryBuffer bb = new TemporaryBuffer.LocalFile(); TemporaryBuffer bb = new TemporaryBuffer.LocalFile(dir, 5 << 20);
tree.write(tmp, bb); try {
bb.close(); tree.write(tmp, bb);
bb.close();
NB.encodeInt32(tmp, 0, EXT_TREE);
NB.encodeInt32(tmp, 4, (int) bb.length()); NB.encodeInt32(tmp, 0, EXT_TREE);
dos.write(tmp, 0, 8); NB.encodeInt32(tmp, 4, (int) bb.length());
bb.writeTo(dos, null); dos.write(tmp, 0, 8);
bb.writeTo(dos, null);
} finally {
bb.destroy();
}
} }
writeIndexChecksum = foot.digest(); writeIndexChecksum = foot.digest();
os.write(writeIndexChecksum); os.write(writeIndexChecksum);

10
org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheCheckout.java vendored

@ -1245,9 +1245,9 @@ public class DirCacheCheckout {
} finally { } finally {
channel.close(); channel.close();
} }
entry.setLength(opt.getAutoCRLF() == AutoCRLF.TRUE entry.setLength(opt.getAutoCRLF() == AutoCRLF.TRUE ? //
? f.length() // AutoCRLF wants on-disk-size tmpFile.length() // AutoCRLF wants on-disk-size
: (int) ol.getSize()); : (int) ol.getSize());
if (opt.isFileMode() && fs.supportsExecute()) { if (opt.isFileMode() && fs.supportsExecute()) {
if (FileMode.EXECUTABLE_FILE.equals(entry.getRawMode())) { if (FileMode.EXECUTABLE_FILE.equals(entry.getRawMode())) {
@ -1291,7 +1291,9 @@ public class DirCacheCheckout {
try { try {
SystemReader.getInstance().checkPath(path); SystemReader.getInstance().checkPath(path);
} catch (CorruptObjectException e) { } catch (CorruptObjectException e) {
throw new InvalidPathException(path); InvalidPathException p = new InvalidPathException(path);
p.initCause(e);
throw p;
} }
} }

53
org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheEntry.java vendored

@ -56,6 +56,7 @@ import java.security.MessageDigest;
import java.text.MessageFormat; import java.text.MessageFormat;
import java.util.Arrays; import java.util.Arrays;
import org.eclipse.jgit.errors.CorruptObjectException;
import org.eclipse.jgit.internal.JGitText; import org.eclipse.jgit.internal.JGitText;
import org.eclipse.jgit.lib.AnyObjectId; import org.eclipse.jgit.lib.AnyObjectId;
import org.eclipse.jgit.lib.Constants; 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.IO;
import org.eclipse.jgit.util.MutableInteger; import org.eclipse.jgit.util.MutableInteger;
import org.eclipse.jgit.util.NB; import org.eclipse.jgit.util.NB;
import org.eclipse.jgit.util.SystemReader;
/** /**
* A single file (or stage of a file) in a {@link DirCache}. * A single file (or stage of a file) in a {@link DirCache}.
@ -190,6 +190,16 @@ public class DirCacheEntry {
md.update((byte) 0); 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 // Index records are padded out to the next 8 byte alignment
// for historical reasons related to how C Git read the files. // for historical reasons related to how C Git read the files.
// //
@ -203,7 +213,6 @@ public class DirCacheEntry {
if (mightBeRacilyClean(smudge_s, smudge_ns)) if (mightBeRacilyClean(smudge_s, smudge_ns))
smudgeRacilyClean(); smudgeRacilyClean();
} }
/** /**
@ -217,7 +226,7 @@ public class DirCacheEntry {
* or DirCache file. * or DirCache file.
*/ */
public DirCacheEntry(final String newPath) { public DirCacheEntry(final String newPath) {
this(Constants.encode(newPath)); this(Constants.encode(newPath), STAGE_0);
} }
/** /**
@ -266,11 +275,11 @@ public class DirCacheEntry {
*/ */
@SuppressWarnings("boxing") @SuppressWarnings("boxing")
public DirCacheEntry(final byte[] newPath, final int stage) { public DirCacheEntry(final byte[] newPath, final int stage) {
if (!isValidPath(newPath)) DirCacheCheckout.checkValidPath(toString(newPath));
throw new InvalidPathException(toString(newPath));
if (stage < 0 || 3 < stage) if (stage < 0 || 3 < stage)
throw new IllegalArgumentException(MessageFormat.format(JGitText.get().invalidStageForPath throw new IllegalArgumentException(MessageFormat.format(
, stage, toString(newPath))); JGitText.get().invalidStageForPath,
stage, toString(newPath)));
info = new byte[INFO_LEN]; info = new byte[INFO_LEN];
infoOffset = 0; infoOffset = 0;
@ -725,36 +734,6 @@ public class DirCacheEntry {
return Constants.CHARSET.decode(ByteBuffer.wrap(path)).toString(); 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) { static int getMaximumInfoLength(boolean extended) {
return extended ? INFO_LEN_EXTENDED : INFO_LEN; return extended ? INFO_LEN_EXTENDED : INFO_LEN;
} }

2
org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoCommand.java

@ -193,6 +193,7 @@ public class RepoCommand extends GitCommand<RevCommit> {
try { try {
return readFileFromRepo(repo, ref, path); return readFileFromRepo(repo, ref, path);
} finally { } finally {
repo.close();
FileUtils.delete(dir, FileUtils.RECURSIVE); FileUtils.delete(dir, FileUtils.RECURSIVE);
} }
} }
@ -860,6 +861,7 @@ public class RepoCommand extends GitCommand<RevCommit> {
if (revision != null) { if (revision != null) {
Git sub = new Git(subRepo); Git sub = new Git(subRepo);
sub.checkout().setName(findRef(revision, subRepo)).call(); sub.checkout().setName(findRef(revision, subRepo)).call();
subRepo.close();
git.add().addFilepattern(name).call(); git.add().addFilepattern(name).call();
} }
for (CopyFile copyfile : copyfiles) { for (CopyFile copyfile : copyfiles) {

2
org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java

@ -308,6 +308,8 @@ public class JGitText extends TranslationBundle {
/***/ public String indexFileIsTooLargeForJgit; /***/ public String indexFileIsTooLargeForJgit;
/***/ public String indexSignatureIsInvalid; /***/ public String indexSignatureIsInvalid;
/***/ public String indexWriteException; /***/ public String indexWriteException;
/***/ public String initFailedBareRepoDifferentDirs;
/***/ public String initFailedNonBareRepoSameDirs;
/***/ public String inMemoryBufferLimitExceeded; /***/ public String inMemoryBufferLimitExceeded;
/***/ public String inputStreamMustSupportMark; /***/ public String inputStreamMustSupportMark;
/***/ public String integerValueOutOfRange; /***/ public String integerValueOutOfRange;

22
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_CORE_SECTION, null,
ConfigConstants.CONFIG_KEY_HIDEDOTFILES, ConfigConstants.CONFIG_KEY_HIDEDOTFILES,
HideDotFiles.DOTGITONLY); HideDotFiles.DOTGITONLY);
if (hideDotFiles != HideDotFiles.FALSE && !isBare()) if (hideDotFiles != HideDotFiles.FALSE && !isBare()
&& getDirectory().getName().startsWith(".")) //$NON-NLS-1$
getFS().setHidden(getDirectory(), true); getFS().setHidden(getDirectory(), true);
refs.create(); refs.create();
objectDatabase.create(); objectDatabase.create();
@ -329,6 +330,25 @@ public class FileRepository extends Repository {
// Java has no other way // Java has no other way
cfg.setBoolean(ConfigConstants.CONFIG_CORE_SECTION, null, cfg.setBoolean(ConfigConstants.CONFIG_CORE_SECTION, null,
ConfigConstants.CONFIG_KEY_PRECOMPOSEUNICODE, true); 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(); cfg.save();
} }

21
org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectory.java

@ -131,14 +131,6 @@ public class ObjectDirectory extends FileObjectDatabase {
private Set<ObjectId> shallowCommitsIds; private Set<ObjectId> 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. * 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 { File[] alternatePaths, FS fs, File shallowFile) throws IOException {
config = cfg; config = cfg;
objects = dir; objects = dir;
trustFolderStat = config.getBoolean(
ConfigConstants.CONFIG_CORE_SECTION,
ConfigConstants.CONFIG_KEY_TRUSTFOLDERSTAT, true);
infoDirectory = new File(objects, "info"); //$NON-NLS-1$ infoDirectory = new File(objects, "info"); //$NON-NLS-1$
packDirectory = new File(objects, "pack"); //$NON-NLS-1$ packDirectory = new File(objects, "pack"); //$NON-NLS-1$
alternatesFile = new File(infoDirectory, "alternates"); //$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) { 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)) return ((!trustFolderStat) || old.snapshot.isModified(packDirectory))
&& old != scanPacks(old); && old != scanPacks(old);
} }

23
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"; 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"; public static final String OS_USER_NAME_KEY = "user.name";
/** The environment variable that contains the author's name */ /** The environment variable that contains the author's name */
@ -358,6 +365,20 @@ public final class Constants {
/** Name of the .git/shallow file */ /** Name of the .git/shallow file */
public static final String SHALLOW = "shallow"; 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. * Create a new digest function for objects.
* *

47
org.eclipse.jgit/src/org/eclipse/jgit/lib/IndexDiff.java

@ -533,28 +533,35 @@ public class IndexDiff {
} }
Repository subRepo = smw.getRepository(); Repository subRepo = smw.getRepository();
if (subRepo != null) { if (subRepo != null) {
ObjectId subHead = subRepo.resolve("HEAD"); //$NON-NLS-1$ try {
if (subHead != null && !subHead.equals(smw.getObjectId())) ObjectId subHead = subRepo.resolve("HEAD"); //$NON-NLS-1$
modified.add(smw.getPath()); if (subHead != null
else if (ignoreSubmoduleMode != IgnoreSubmoduleMode.DIRTY) { && !subHead.equals(smw.getObjectId()))
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()); 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();
} }
} }
} }

134
org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectChecker.java

@ -492,13 +492,27 @@ public class ObjectChecker {
throw new CorruptObjectException("invalid name '..'"); throw new CorruptObjectException("invalid name '..'");
break; break;
case 4: 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( throw new CorruptObjectException(String.format(
"invalid name '%s'", "invalid name '%s'",
RawParseUtils.decode(raw, ptr, end))); 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) { if (windows) {
// Windows ignores space and dot at end of file name. // Windows ignores space and dot at end of file name.
if (raw[end - 1] == ' ' || raw[end - 1] == '.') 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) private static void checkNotWindowsDevice(byte[] raw, int ptr, int end)
throws CorruptObjectException { throws CorruptObjectException {
switch (toLower(raw[ptr])) { switch (toLower(raw[ptr])) {
@ -579,12 +675,36 @@ public class ObjectChecker {
return 1 <= c && c <= 31; return 1 <= c && c <= 31;
} }
private boolean isDotGit(byte[] buf, int p) { private static boolean isGit(byte[] buf, int p) {
if (windows || macosx) return toLower(buf[p]) == 'g'
return toLower(buf[p]) == 'g' && toLower(buf[p + 1]) == 'i'
&& toLower(buf[p + 1]) == 'i' && toLower(buf[p + 2]) == 't';
&& toLower(buf[p + 2]) == 't'; }
return buf[p] == 'g' && buf[p + 1] == 'i' && 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) { private static char toLower(byte b) {

13
org.eclipse.jgit/src/org/eclipse/jgit/lib/RebaseTodoFile.java

@ -43,17 +43,17 @@
package org.eclipse.jgit.lib; package org.eclipse.jgit.lib;
import java.io.BufferedWriter;
import java.io.File; import java.io.File;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStreamWriter; import java.io.OutputStream;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import org.eclipse.jgit.lib.RebaseTodoLine.Action; import org.eclipse.jgit.lib.RebaseTodoLine.Action;
import org.eclipse.jgit.util.IO; import org.eclipse.jgit.util.IO;
import org.eclipse.jgit.util.RawParseUtils; 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 * 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<RebaseTodoLine> steps, public void writeRebaseTodoFile(String path, List<RebaseTodoLine> steps,
boolean append) throws IOException { boolean append) throws IOException {
BufferedWriter fw = new BufferedWriter(new OutputStreamWriter( OutputStream fw = new SafeBufferedOutputStream(new FileOutputStream(
new FileOutputStream(new File(repo.getDirectory(), path), new File(repo.getDirectory(), path), append));
append), Constants.CHARACTER_ENCODING));
try { try {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
for (RebaseTodoLine step : steps) { for (RebaseTodoLine step : steps) {
@ -232,8 +231,8 @@ public class RebaseTodoFile {
sb.append(" "); //$NON-NLS-1$ sb.append(" "); //$NON-NLS-1$
sb.append(step.getShortMessage().trim()); sb.append(step.getShortMessage().trim());
} }
fw.write(sb.toString()); sb.append('\n');
fw.newLine(); fw.write(Constants.encode(sb.toString()));
} }
} finally { } finally {
fw.close(); fw.close();

7
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]; final TemporaryBuffer[] tmp = new TemporaryBuffer[getParentCount() + 1];
try { try {
for (int i = 0; i < tmp.length; i++) 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()) for (final HunkHeader h : getHunks())
h.extractFileLines(tmp); h.extractFileLines(tmp);
@ -281,11 +281,6 @@ public class FileHeader extends DiffEntry {
return r; return r;
} catch (IOException ioe) { } catch (IOException ioe) {
throw new RuntimeException(JGitText.get().cannotConvertScriptToText, ioe); throw new RuntimeException(JGitText.get().cannotConvertScriptToText, ioe);
} finally {
for (final TemporaryBuffer b : tmp) {
if (b != null)
b.destroy();
}
} }
} }

12
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 { private static byte[] readFully(final InputStream is) throws IOException {
final TemporaryBuffer b = new TemporaryBuffer.LocalFile(); TemporaryBuffer b = new TemporaryBuffer.Heap(Integer.MAX_VALUE);
try { b.copy(is);
b.copy(is); b.close();
b.close(); return b.toByteArray();
return b.toByteArray();
} finally {
b.destroy();
}
} }
/** /**

8
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. */ /** Encryption algorithm, may be a null instance that provides pass-through. */
private final WalkEncryption encryption; private final WalkEncryption encryption;
/** Directory for locally buffered content. */
private final File tmpDir;
/** /**
* Create a new S3 client for the supplied user information. * Create a new S3 client for the supplied user information.
* <p> * <p>
@ -251,6 +254,9 @@ public class AmazonS3 {
maxAttempts = Integer.parseInt(props.getProperty( maxAttempts = Integer.parseInt(props.getProperty(
"httpclient.retry-max", "3")); //$NON-NLS-1$ //$NON-NLS-2$ "httpclient.retry-max", "3")); //$NON-NLS-1$ //$NON-NLS-2$
proxySelector = ProxySelector.getDefault(); 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) final ProgressMonitor monitor, final String monitorTask)
throws IOException { throws IOException {
final MessageDigest md5 = newMD5(); final MessageDigest md5 = newMD5();
final TemporaryBuffer buffer = new TemporaryBuffer.LocalFile() { final TemporaryBuffer buffer = new TemporaryBuffer.LocalFile(tmpDir) {
@Override @Override
public void close() throws IOException { public void close() throws IOException {
super.close(); super.close();

6
org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportAmazonS3.java

@ -147,7 +147,11 @@ public class TransportAmazonS3 extends HttpTransport implements WalkTransport {
throws NotSupportedException { throws NotSupportedException {
super(local, uri); 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(); bucket = uri.getHost();
String p = uri.getPath(); String p = uri.getPath();

9
org.eclipse.jgit/src/org/eclipse/jgit/util/TemporaryBuffer.java

@ -361,7 +361,12 @@ public abstract class TemporaryBuffer extends OutputStream {
*/ */
private File onDiskFile; 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() { public LocalFile() {
this(null, DEFAULT_IN_CORE_LIMIT); this(null, DEFAULT_IN_CORE_LIMIT);
} }
@ -372,7 +377,9 @@ public abstract class TemporaryBuffer extends OutputStream {
* @param inCoreLimit * @param inCoreLimit
* maximum number of bytes to store in memory. Storage beyond * maximum number of bytes to store in memory. Storage beyond
* this limit will use the local file. * this limit will use the local file.
* @deprecated Use the {@code File,int} overload to supply a directory.
*/ */
@Deprecated
public LocalFile(final int inCoreLimit) { public LocalFile(final int inCoreLimit) {
this(null, inCoreLimit); this(null, inCoreLimit);
} }

Loading…
Cancel
Save