Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKevin Sawicki2012-02-08 22:10:28 +0000
committerMatthias Sohn2012-02-08 22:10:28 +0000
commit2f79cf9900288991e51b8da408511ead05f4d085 (patch)
tree7a2afeef6e47a38e63cf4e4d2e6e022e085800bb /org.eclipse.jgit
parent7bde08e1d4e72385e55b6b31bc7bf5bffdf63a0a (diff)
downloadjgit-2f79cf9900288991e51b8da408511ead05f4d085.tar.gz
jgit-2f79cf9900288991e51b8da408511ead05f4d085.tar.xz
jgit-2f79cf9900288991e51b8da408511ead05f4d085.zip
Support gitdir references in working tree .git file
A '.git' file in a repository's working tree root is now parsed as a ref to a folder located elsewhere. This supports submodules having their repository location outside of the parent repository's working directory such as in the parent repository's '.git/modules' directory. This adds support to BaseRepositoryBuilder for repositories created with the '--separate-git-dir' option specified to 'git init'. Change-Id: I73c538f6d845bdbc0c4e2bce5a77f900cf36e1a9 Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
Diffstat (limited to 'org.eclipse.jgit')
-rw-r--r--org.eclipse.jgit/resources/org/eclipse/jgit/JGitText.properties1
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/JGitText.java1
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/lib/BaseRepositoryBuilder.java50
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/submodule/SubmoduleWalk.java53
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/treewalk/FileTreeIterator.java2
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java14
6 files changed, 74 insertions, 47 deletions
diff --git a/org.eclipse.jgit/resources/org/eclipse/jgit/JGitText.properties b/org.eclipse.jgit/resources/org/eclipse/jgit/JGitText.properties
index 5b22801342..8a5e023104 100644
--- a/org.eclipse.jgit/resources/org/eclipse/jgit/JGitText.properties
+++ b/org.eclipse.jgit/resources/org/eclipse/jgit/JGitText.properties
@@ -234,6 +234,7 @@ invalidChannel=Invalid channel {0}
invalidCharacterInBase64Data=Invalid character in Base64 data.
invalidCommitParentNumber=Invalid commit parent number
invalidEncryption=Invalid encryption
+invalidGitdirRef = Invalid .git reference in file ''{0}''
invalidGitType=invalid git type: {0}
invalidId=Invalid id {0}
invalidIdLength=Invalid id length {0}; should be {1}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/JGitText.java b/org.eclipse.jgit/src/org/eclipse/jgit/JGitText.java
index dbc3bcae62..bcd14c6a4f 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/JGitText.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/JGitText.java
@@ -294,6 +294,7 @@ public class JGitText extends TranslationBundle {
/***/ public String invalidCharacterInBase64Data;
/***/ public String invalidCommitParentNumber;
/***/ public String invalidEncryption;
+ /***/ public String invalidGitdirRef;
/***/ public String invalidGitType;
/***/ public String invalidId;
/***/ public String invalidIdLength;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/BaseRepositoryBuilder.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/BaseRepositoryBuilder.java
index 22a2ae505d..7db0b9f87f 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/BaseRepositoryBuilder.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/BaseRepositoryBuilder.java
@@ -69,6 +69,8 @@ import org.eclipse.jgit.storage.file.FileBasedConfig;
import org.eclipse.jgit.storage.file.FileRepository;
import org.eclipse.jgit.storage.file.FileRepositoryBuilder;
import org.eclipse.jgit.util.FS;
+import org.eclipse.jgit.util.IO;
+import org.eclipse.jgit.util.RawParseUtils;
import org.eclipse.jgit.util.SystemReader;
/**
@@ -85,6 +87,19 @@ import org.eclipse.jgit.util.SystemReader;
* @see FileRepositoryBuilder
*/
public class BaseRepositoryBuilder<B extends BaseRepositoryBuilder, R extends Repository> {
+ private static boolean isSymRef(byte[] ref) {
+ if (ref.length < 9)
+ return false;
+ return /**/ref[0] == 'g' //
+ && ref[1] == 'i' //
+ && ref[2] == 't' //
+ && ref[3] == 'd' //
+ && ref[4] == 'i' //
+ && ref[5] == 'r' //
+ && ref[6] == ':' //
+ && ref[7] == ' ';
+ }
+
private FS fs;
private File gitDir;
@@ -546,10 +561,37 @@ public class BaseRepositoryBuilder<B extends BaseRepositoryBuilder, R extends Re
* the repository could not be accessed
*/
protected void setupGitDir() throws IOException {
- // No gitDir? Try to assume its under the workTree.
- //
- if (getGitDir() == null && getWorkTree() != null)
- setGitDir(new File(getWorkTree(), DOT_GIT));
+ // No gitDir? Try to assume its under the workTree or a ref to another
+ // location
+ if (getGitDir() == null && getWorkTree() != null) {
+ File dotGit = new File(getWorkTree(), DOT_GIT);
+ if (!dotGit.isFile())
+ setGitDir(dotGit);
+ else {
+ byte[] content = IO.readFully(dotGit);
+ if (!isSymRef(content))
+ throw new IOException(MessageFormat.format(
+ JGitText.get().invalidGitdirRef,
+ dotGit.getAbsolutePath()));
+ int pathStart = 8;
+ int lineEnd = RawParseUtils.nextLF(content, pathStart);
+ if (content[lineEnd - 1] == '\n')
+ lineEnd--;
+ if (lineEnd == pathStart)
+ throw new IOException(MessageFormat.format(
+ JGitText.get().invalidGitdirRef,
+ dotGit.getAbsolutePath()));
+
+ String gitdirPath = RawParseUtils.decode(content, pathStart,
+ lineEnd);
+ File gitdirFile = new File(gitdirPath);
+ if (gitdirFile.isAbsolute())
+ setGitDir(gitdirFile);
+ else
+ setGitDir(new File(getWorkTree(), gitdirPath)
+ .getCanonicalFile());
+ }
+ }
}
/**
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/submodule/SubmoduleWalk.java b/org.eclipse.jgit/src/org/eclipse/jgit/submodule/SubmoduleWalk.java
index 78896f8a54..f07f4d6c66 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/submodule/SubmoduleWalk.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/submodule/SubmoduleWalk.java
@@ -155,27 +155,32 @@ public class SubmoduleWalk {
*/
public static Repository getSubmoduleRepository(final Repository parent,
final String path) throws IOException {
- File directory = getSubmoduleGitDirectory(parent, path);
- if (!directory.isDirectory())
- return null;
- try {
- return new RepositoryBuilder().setMustExist(true)
- .setFS(FS.DETECTED).setGitDir(directory).build();
- } catch (RepositoryNotFoundException e) {
- return null;
- }
+ return getSubmoduleRepository(parent.getWorkTree(), path);
}
/**
- * Get the .git directory for a repository submodule path
+ * Get submodule repository at path
*
* @param parent
* @param path
- * @return .git for submodule repository
+ * @return repository or null if repository doesn't exist
+ * @throws IOException
*/
- public static File getSubmoduleGitDirectory(final Repository parent,
- final String path) {
- return new File(getSubmoduleDirectory(parent, path), Constants.DOT_GIT);
+ public static Repository getSubmoduleRepository(final File parent,
+ final String path) throws IOException {
+ File subWorkTree = new File(parent, path);
+ if (!subWorkTree.isDirectory())
+ return null;
+ File workTree = new File(parent, path);
+ try {
+ return new RepositoryBuilder() //
+ .setMustExist(true) //
+ .setFS(FS.DETECTED) //
+ .setWorkTree(workTree) //
+ .build();
+ } catch (RepositoryNotFoundException e) {
+ return null;
+ }
}
/**
@@ -349,15 +354,6 @@ public class SubmoduleWalk {
}
/**
- * Get the .git directory for the current submodule entry
- *
- * @return .git for submodule repository
- */
- public File getGitDirectory() {
- return getSubmoduleGitDirectory(repository, path);
- }
-
- /**
* Advance to next submodule in the index tree.
*
* The object id and path of the next entry can be obtained by calling
@@ -467,19 +463,8 @@ public class SubmoduleWalk {
}
/**
- * Does the current submodule entry have a .git directory in the parent
- * repository's working tree?
- *
- * @return true if .git directory exists, false otherwise
- */
- public boolean hasGitDirectory() {
- return getGitDirectory().isDirectory();
- }
-
- /**
* Get repository for current submodule entry
*
- * @see #hasGitDirectory()
* @return repository or null if non-existent
* @throws IOException
*/
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/FileTreeIterator.java b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/FileTreeIterator.java
index c7ae7757ac..315d9091c5 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/FileTreeIterator.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/FileTreeIterator.java
@@ -159,7 +159,7 @@ public class FileTreeIterator extends WorkingTreeIterator {
file = f;
if (f.isDirectory()) {
- if (new File(f, Constants.DOT_GIT).isDirectory())
+ if (new File(f, Constants.DOT_GIT).exists())
mode = FileMode.GITLINK;
else
mode = FileMode.TREE;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java
index fa57b71ad1..89403993f8 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java
@@ -76,7 +76,7 @@ import org.eclipse.jgit.lib.CoreConfig.AutoCRLF;
import org.eclipse.jgit.lib.FileMode;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Repository;
-import org.eclipse.jgit.lib.RepositoryBuilder;
+import org.eclipse.jgit.submodule.SubmoduleWalk;
import org.eclipse.jgit.util.FS;
import org.eclipse.jgit.util.IO;
import org.eclipse.jgit.util.io.EolCanonicalizingInputStream;
@@ -280,18 +280,16 @@ public abstract class WorkingTreeIterator extends AbstractTreeIterator {
* @return non-null submodule id
*/
protected byte[] idSubmodule(File directory, Entry e) {
- final String gitDirPath = e.getName() + "/" + Constants.DOT_GIT;
- final File submoduleGitDir = new File(directory, gitDirPath);
- if (!submoduleGitDir.isDirectory())
- return zeroid;
final Repository submoduleRepo;
try {
- FS fs = repository != null ? repository.getFS() : FS.DETECTED;
- submoduleRepo = new RepositoryBuilder().setGitDir(submoduleGitDir)
- .setMustExist(true).setFS(fs).build();
+ submoduleRepo = SubmoduleWalk.getSubmoduleRepository(directory,
+ e.getName());
} catch (IOException exception) {
return zeroid;
}
+ if (submoduleRepo == null)
+ return zeroid;
+
final ObjectId head;
try {
head = submoduleRepo.resolve(Constants.HEAD);

Back to the top