This allows findGitDir to be used for repositories containing a .git file with a gitdir: ref to the repository's directory such as submodule repositories that point to a folder under the parent repository's .git/modules folder Change-Id: I2f1ec7215a2208aa90511c065cadc7e816522f62 Signed-off-by: Chris Aniszczyk <zx@twitter.com>tags/v2.0.0.201206130900-r
@@ -45,13 +45,16 @@ package org.eclipse.jgit.storage.file; | |||
import static org.junit.Assert.assertEquals; | |||
import static org.junit.Assert.assertNotNull; | |||
import static org.junit.Assert.assertTrue; | |||
import static org.junit.Assert.fail; | |||
import java.io.File; | |||
import java.io.FileWriter; | |||
import java.io.IOException; | |||
import org.eclipse.jgit.junit.LocalDiskRepositoryTestCase; | |||
import org.eclipse.jgit.lib.ConfigConstants; | |||
import org.eclipse.jgit.lib.Constants; | |||
import org.eclipse.jgit.util.FileUtils; | |||
import org.junit.Test; | |||
@@ -108,4 +111,58 @@ public class FileRepositoryBuilderTest extends LocalDiskRepositoryTestCase { | |||
assertNotNull(e.getMessage()); | |||
} | |||
} | |||
@Test | |||
public void absoluteGitDirRef() throws Exception { | |||
FileRepository repo1 = createWorkRepository(); | |||
File dir = createTempDirectory("dir"); | |||
File dotGit = new File(dir, Constants.DOT_GIT); | |||
new FileWriter(dotGit).append( | |||
"gitdir: " + repo1.getDirectory().getAbsolutePath()).close(); | |||
FileRepositoryBuilder builder = new FileRepositoryBuilder(); | |||
builder.setWorkTree(dir); | |||
builder.setMustExist(true); | |||
FileRepository repo2 = builder.build(); | |||
assertEquals(repo1.getDirectory(), repo2.getDirectory()); | |||
assertEquals(dir, repo2.getWorkTree()); | |||
} | |||
@Test | |||
public void relativeGitDirRef() throws Exception { | |||
FileRepository repo1 = createWorkRepository(); | |||
File dir = new File(repo1.getWorkTree(), "dir"); | |||
assertTrue(dir.mkdir()); | |||
File dotGit = new File(dir, Constants.DOT_GIT); | |||
new FileWriter(dotGit).append("gitdir: ../" + Constants.DOT_GIT) | |||
.close(); | |||
FileRepositoryBuilder builder = new FileRepositoryBuilder(); | |||
builder.setWorkTree(dir); | |||
builder.setMustExist(true); | |||
FileRepository repo2 = builder.build(); | |||
assertEquals(repo1.getDirectory(), repo2.getDirectory()); | |||
assertEquals(dir, repo2.getWorkTree()); | |||
} | |||
@Test | |||
public void scanWithGitDirRef() throws Exception { | |||
FileRepository repo1 = createWorkRepository(); | |||
File dir = createTempDirectory("dir"); | |||
File dotGit = new File(dir, Constants.DOT_GIT); | |||
new FileWriter(dotGit).append( | |||
"gitdir: " + repo1.getDirectory().getAbsolutePath()).close(); | |||
FileRepositoryBuilder builder = new FileRepositoryBuilder(); | |||
builder.setWorkTree(dir); | |||
builder.findGitDir(dir); | |||
assertEquals(repo1.getDirectory(), builder.getGitDir()); | |||
builder.setMustExist(true); | |||
FileRepository repo2 = builder.build(); | |||
assertEquals(repo1.getDirectory(), repo2.getDirectory()); | |||
assertEquals(dir, repo2.getWorkTree()); | |||
} | |||
} |
@@ -100,6 +100,29 @@ public class BaseRepositoryBuilder<B extends BaseRepositoryBuilder, R extends Re | |||
&& ref[7] == ' '; | |||
} | |||
private static File getSymRef(File workTree, File dotGit) | |||
throws IOException { | |||
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()) | |||
return gitdirFile; | |||
else | |||
return new File(workTree, gitdirPath).getCanonicalFile(); | |||
} | |||
private FS fs; | |||
private File gitDir; | |||
@@ -491,7 +514,13 @@ public class BaseRepositoryBuilder<B extends BaseRepositoryBuilder, R extends Re | |||
if (FileKey.isGitRepository(dir, tryFS)) { | |||
setGitDir(dir); | |||
break; | |||
} | |||
} else if (dir.isFile()) | |||
try { | |||
setGitDir(getSymRef(current, dir)); | |||
break; | |||
} catch (IOException ignored) { | |||
// Continue searching if gitdir ref isn't found | |||
} | |||
current = current.getParentFile(); | |||
if (current != null && ceilingDirectories != null | |||
@@ -567,30 +596,8 @@ public class BaseRepositoryBuilder<B extends BaseRepositoryBuilder, R extends Re | |||
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()); | |||
} | |||
else | |||
setGitDir(getSymRef(getWorkTree(), dotGit)); | |||
} | |||
} | |||