summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/MockSystemReader.java1
-rw-r--r--org.eclipse.jgit.test/tst/org/eclipse/jgit/api/InitCommandTest.java110
-rw-r--r--org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties2
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/api/InitCommand.java88
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java2
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileRepository.java22
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/lib/Constants.java16
7 files changed, 230 insertions, 11 deletions
diff --git a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/MockSystemReader.java b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/MockSystemReader.java
index deca341067..3d21f9f8ad 100644
--- a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/MockSystemReader.java
+++ b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/MockSystemReader.java
@@ -90,6 +90,7 @@ public class MockSystemReader extends SystemReader {
init(Constants.GIT_AUTHOR_EMAIL_KEY);
init(Constants.GIT_COMMITTER_NAME_KEY);
init(Constants.GIT_COMMITTER_EMAIL_KEY);
+ setProperty(Constants.OS_USER_DIR, ".");
userGitConfig = new MockConfig(null, null);
systemGitConfig = new MockConfig(null, null);
setCurrentPlatform();
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/InitCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/InitCommandTest.java
index 3296717c0e..e850223762 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/InitCommandTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/InitCommandTest.java
@@ -43,6 +43,7 @@
package org.eclipse.jgit.api;
import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import java.io.File;
@@ -50,8 +51,12 @@ import java.io.IOException;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.api.errors.JGitInternalException;
+import org.eclipse.jgit.errors.NoWorkTreeException;
+import org.eclipse.jgit.junit.MockSystemReader;
import org.eclipse.jgit.junit.RepositoryTestCase;
+import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.util.SystemReader;
import org.junit.Before;
import org.junit.Test;
@@ -101,4 +106,109 @@ public class InitCommandTest extends RepositoryTestCase {
assertNotNull(repository);
assertTrue(repository.isBare());
}
+
+ // non-bare repos where gitDir and directory is set. Same as
+ // "git init --separate-git-dir /tmp/a /tmp/b"
+ @Test
+ public void testInitWithExplicitGitDir() throws IOException,
+ JGitInternalException, GitAPIException {
+ File wt = createTempDirectory("testInitRepositoryWT");
+ File gitDir = createTempDirectory("testInitRepositoryGIT");
+ InitCommand command = new InitCommand();
+ command.setDirectory(wt);
+ command.setGitDir(gitDir);
+ Repository repository = command.call().getRepository();
+ addRepoToClose(repository);
+ assertNotNull(repository);
+ assertEqualsFile(wt, repository.getWorkTree());
+ assertEqualsFile(gitDir, repository.getDirectory());
+ }
+
+ // non-bare repos where only gitDir is set. Same as
+ // "git init --separate-git-dir /tmp/a"
+ @Test
+ public void testInitWithOnlyExplicitGitDir() throws IOException,
+ JGitInternalException, GitAPIException {
+ MockSystemReader reader = (MockSystemReader) SystemReader.getInstance();
+ reader.setProperty(Constants.OS_USER_DIR, getTemporaryDirectory()
+ .getAbsolutePath());
+ File gitDir = createTempDirectory("testInitRepository/.git");
+ InitCommand command = new InitCommand();
+ command.setGitDir(gitDir);
+ Repository repository = command.call().getRepository();
+ addRepoToClose(repository);
+ assertNotNull(repository);
+ assertEqualsFile(gitDir, repository.getDirectory());
+ assertEqualsFile(new File(reader.getProperty("user.dir")),
+ repository.getWorkTree());
+ }
+
+ // Bare repos where gitDir and directory is set will only work if gitDir and
+ // directory is pointing to same dir. Same as
+ // "git init --bare --separate-git-dir /tmp/a /tmp/b"
+ // (works in native git but I guess that's more a bug)
+ @Test(expected = IllegalStateException.class)
+ public void testInitBare_DirAndGitDirMustBeEqual() throws IOException,
+ JGitInternalException, GitAPIException {
+ File gitDir = createTempDirectory("testInitRepository.git");
+ InitCommand command = new InitCommand();
+ command.setBare(true);
+ command.setDirectory(gitDir);
+ command.setGitDir(new File(gitDir, ".."));
+ command.call();
+ }
+
+ // If neither directory nor gitDir is set in a non-bare repo make sure
+ // worktree and gitDir are set correctly. Standard case. Same as
+ // "git init"
+ @Test
+ public void testInitWithDefaultsNonBare() throws JGitInternalException,
+ GitAPIException, IOException {
+ MockSystemReader reader = (MockSystemReader) SystemReader.getInstance();
+ reader.setProperty(Constants.OS_USER_DIR, getTemporaryDirectory()
+ .getAbsolutePath());
+ InitCommand command = new InitCommand();
+ command.setBare(false);
+ Repository repository = command.call().getRepository();
+ addRepoToClose(repository);
+ assertNotNull(repository);
+ assertEqualsFile(new File(reader.getProperty("user.dir"), ".git"),
+ repository.getDirectory());
+ assertEqualsFile(new File(reader.getProperty("user.dir")),
+ repository.getWorkTree());
+ }
+
+ // If neither directory nor gitDir is set in a bare repo make sure
+ // worktree and gitDir are set correctly. Standard case. Same as
+ // "git init --bare"
+ @Test(expected = NoWorkTreeException.class)
+ public void testInitWithDefaultsBare() throws JGitInternalException,
+ GitAPIException, IOException {
+ MockSystemReader reader = (MockSystemReader) SystemReader.getInstance();
+ reader.setProperty(Constants.OS_USER_DIR, getTemporaryDirectory()
+ .getAbsolutePath());
+ InitCommand command = new InitCommand();
+ command.setBare(true);
+ Repository repository = command.call().getRepository();
+ addRepoToClose(repository);
+ assertNotNull(repository);
+ assertEqualsFile(new File(reader.getProperty("user.dir")),
+ repository.getDirectory());
+ assertNull(repository.getWorkTree());
+ }
+
+ // In a non-bare repo when directory and gitDir is set then they shouldn't
+ // point to the same dir. Same as
+ // "git init --separate-git-dir /tmp/a /tmp/a"
+ // (works in native git but I guess that's more a bug)
+ @Test(expected = IllegalStateException.class)
+ public void testInitNonBare_GitdirAndDirShouldntBeSame()
+ throws JGitInternalException, GitAPIException, IOException {
+ File gitDir = createTempDirectory("testInitRepository.git");
+ InitCommand command = new InitCommand();
+ command.setBare(false);
+ command.setGitDir(gitDir);
+ command.setDirectory(gitDir);
+ command.call().getRepository();
+ }
}
diff --git a/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties b/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties
index 76c709422e..a753188e88 100644
--- a/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties
+++ b/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties
@@ -249,6 +249,8 @@ indexFileIsInUse=Index file is in use
indexFileIsTooLargeForJgit=Index file is too large for jgit
indexSignatureIsInvalid=Index signature is invalid: {0}
indexWriteException=Modified index could not be written
+initFailedBareRepoDifferentDirs=When initializing a bare repo with directory {0} and separate git-dir {1} specified both folders must point to the same location
+initFailedNonBareRepoSameDirs=When initializing a non-bare repo with directory {0} and separate git-dir {1} specified both folders should not point to the same location
inMemoryBufferLimitExceeded=In-memory buffer limit exceeded
inputStreamMustSupportMark=InputStream must support mark()
integerValueOutOfRange=Integer value {0}.{1} out of range
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/InitCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/InitCommand.java
index bf43e90d42..37a788e85c 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/InitCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/InitCommand.java
@@ -44,13 +44,16 @@ package org.eclipse.jgit.api;
import java.io.File;
import java.io.IOException;
+import java.text.MessageFormat;
import java.util.concurrent.Callable;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.api.errors.JGitInternalException;
+import org.eclipse.jgit.internal.JGitText;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.lib.RepositoryBuilder;
+import org.eclipse.jgit.util.SystemReader;
/**
* Create an empty git repository or reinitalize an existing one
@@ -61,6 +64,8 @@ import org.eclipse.jgit.lib.RepositoryBuilder;
public class InitCommand implements Callable<Git> {
private File directory;
+ private File gitDir;
+
private boolean bare;
/**
@@ -74,18 +79,36 @@ public class InitCommand implements Callable<Git> {
if (bare)
builder.setBare();
builder.readEnvironment();
+ if (gitDir != null)
+ builder.setGitDir(gitDir);
+ else
+ gitDir = builder.getGitDir();
if (directory != null) {
- File d = directory;
- if (!bare)
- d = new File(d, Constants.DOT_GIT);
- builder.setGitDir(d);
+ if (bare)
+ builder.setGitDir(directory);
+ else {
+ builder.setWorkTree(directory);
+ if (gitDir == null)
+ builder.setGitDir(new File(directory, Constants.DOT_GIT));
+ }
} else if (builder.getGitDir() == null) {
- File d = new File("."); //$NON-NLS-1$
- if (d.getParentFile() != null)
- d = d.getParentFile();
+ String dStr = SystemReader.getInstance()
+ .getProperty("user.dir"); //$NON-NLS-1$
+ if (dStr == null)
+ dStr = "."; //$NON-NLS-1$
+ File d = new File(dStr);
if (!bare)
d = new File(d, Constants.DOT_GIT);
builder.setGitDir(d);
+ } else {
+ // directory was not set but gitDir was set
+ if (!bare) {
+ String dStr = SystemReader.getInstance().getProperty(
+ "user.dir"); //$NON-NLS-1$
+ if (dStr == null)
+ dStr = "."; //$NON-NLS-1$
+ builder.setWorkTree(new File(dStr));
+ }
}
Repository repository = builder.build();
if (!repository.getObjectDatabase().exists())
@@ -103,20 +126,67 @@ public class InitCommand implements Callable<Git> {
* @param directory
* the directory to init to
* @return this instance
+ * @throws IllegalStateException
+ * if the combination of directory, gitDir and bare is illegal.
+ * E.g. if for a non-bare repository directory and gitDir point
+ * to the same directory of if for a bare repository both
+ * directory and gitDir are specified
*/
- public InitCommand setDirectory(File directory) {
+ public InitCommand setDirectory(File directory)
+ throws IllegalStateException {
+ validateDirs(directory, gitDir, bare);
this.directory = directory;
return this;
}
/**
+ * @param gitDir
+ * the repository meta directory
+ * @return this instance
+ * @throws IllegalStateException
+ * if the combination of directory, gitDir and bare is illegal.
+ * E.g. if for a non-bare repository directory and gitDir point
+ * to the same directory of if for a bare repository both
+ * directory and gitDir are specified
+ * @since 3.6
+ */
+ public InitCommand setGitDir(File gitDir)
+ throws IllegalStateException {
+ validateDirs(directory, gitDir, bare);
+ this.gitDir = gitDir;
+ return this;
+ }
+
+ private static void validateDirs(File directory, File gitDir, boolean bare)
+ throws IllegalStateException {
+ if (directory != null) {
+ if (bare) {
+ if (gitDir != null && !gitDir.equals(directory))
+ throw new IllegalStateException(MessageFormat.format(
+ JGitText.get().initFailedBareRepoDifferentDirs,
+ gitDir, directory));
+ } else {
+ if (gitDir != null && gitDir.equals(directory))
+ throw new IllegalStateException(MessageFormat.format(
+ JGitText.get().initFailedNonBareRepoSameDirs,
+ gitDir, directory));
+ }
+ }
+ }
+
+ /**
* @param bare
* whether the repository is bare or not
+ * @throws IllegalStateException
+ * if the combination of directory, gitDir and bare is illegal.
+ * E.g. if for a non-bare repository directory and gitDir point
+ * to the same directory of if for a bare repository both
+ * directory and gitDir are specified
* @return this instance
*/
public InitCommand setBare(boolean bare) {
+ validateDirs(directory, gitDir, bare);
this.bare = bare;
return this;
}
-
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java
index d1f0deec9d..65272fb0bd 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java
@@ -308,6 +308,8 @@ public class JGitText extends TranslationBundle {
/***/ public String indexFileIsTooLargeForJgit;
/***/ public String indexSignatureIsInvalid;
/***/ public String indexWriteException;
+ /***/ public String initFailedBareRepoDifferentDirs;
+ /***/ public String initFailedNonBareRepoSameDirs;
/***/ public String inMemoryBufferLimitExceeded;
/***/ public String inputStreamMustSupportMark;
/***/ public String integerValueOutOfRange;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileRepository.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileRepository.java
index 9670bf10a2..995621ee3e 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileRepository.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileRepository.java
@@ -273,7 +273,8 @@ public class FileRepository extends Repository {
ConfigConstants.CONFIG_CORE_SECTION, null,
ConfigConstants.CONFIG_KEY_HIDEDOTFILES,
HideDotFiles.DOTGITONLY);
- if (hideDotFiles != HideDotFiles.FALSE && !isBare())
+ if (hideDotFiles != HideDotFiles.FALSE && !isBare()
+ && getDirectory().getName().startsWith(".")) //$NON-NLS-1$
getFS().setHidden(getDirectory(), true);
refs.create();
objectDatabase.create();
@@ -329,6 +330,25 @@ public class FileRepository extends Repository {
// Java has no other way
cfg.setBoolean(ConfigConstants.CONFIG_CORE_SECTION, null,
ConfigConstants.CONFIG_KEY_PRECOMPOSEUNICODE, true);
+ if (!bare) {
+ File workTree = getWorkTree();
+ if (!getDirectory().getParentFile().equals(workTree)) {
+ cfg.setString(ConfigConstants.CONFIG_CORE_SECTION, null,
+ ConfigConstants.CONFIG_KEY_WORKTREE, getWorkTree()
+ .getAbsolutePath());
+ LockFile dotGitLockFile = new LockFile(new File(workTree,
+ Constants.DOT_GIT), getFS());
+ try {
+ if (dotGitLockFile.lock()) {
+ dotGitLockFile.write(Constants.encode(Constants.GITDIR
+ + getDirectory().getAbsolutePath()));
+ dotGitLockFile.commit();
+ }
+ } finally {
+ dotGitLockFile.unlock();
+ }
+ }
+ }
cfg.save();
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Constants.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Constants.java
index d14614dc38..32ccc7c335 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Constants.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Constants.java
@@ -272,7 +272,14 @@ public final class Constants {
*/
public static final String INFO_EXCLUDE = "info/exclude";
- /** The environment variable that contains the system user name */
+ /**
+ * The system property that contains the system user name
+ *
+ * @since 3.6
+ */
+ public static final String OS_USER_DIR = "user.dir";
+
+ /** The system property that contains the system user name */
public static final String OS_USER_NAME_KEY = "user.name";
/** The environment variable that contains the author's name */
@@ -359,6 +366,13 @@ public final class Constants {
public static final String SHALLOW = "shallow";
/**
+ * Prefix of the first line in a ".git" file
+ *
+ * @since 3.6
+ */
+ public static final String GITDIR = "gitdir: ";
+
+ /**
* Create a new digest function for objects.
*
* @return a new digest object.