Support gitdir: refs in BaseRepositoryBuilder.findGitDir

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>
This commit is contained in:
Kevin Sawicki 2012-05-10 13:32:16 -07:00 committed by Chris Aniszczyk
parent 8a0169727f
commit 2a18bb304c
2 changed files with 89 additions and 25 deletions

View File

@ -45,13 +45,16 @@
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 void unknownRepositoryFormatVersion() throws Exception {
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());
}
}

View File

@ -100,6 +100,29 @@ private static boolean isSymRef(byte[] ref) {
&& 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 B findGitDir(File current) {
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 @@ protected void setupGitDir() throws IOException {
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));
}
}