Browse Source

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>
stable-2.0
Kevin Sawicki 13 years ago committed by Chris Aniszczyk
parent
commit
2a18bb304c
  1. 57
      org.eclipse.jgit.test/tst/org/eclipse/jgit/storage/file/FileRepositoryBuilderTest.java
  2. 53
      org.eclipse.jgit/src/org/eclipse/jgit/lib/BaseRepositoryBuilder.java

57
org.eclipse.jgit.test/tst/org/eclipse/jgit/storage/file/FileRepositoryBuilderTest.java

@ -45,13 +45,16 @@ package org.eclipse.jgit.storage.file;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail; import static org.junit.Assert.fail;
import java.io.File; import java.io.File;
import java.io.FileWriter;
import java.io.IOException; import java.io.IOException;
import org.eclipse.jgit.junit.LocalDiskRepositoryTestCase; import org.eclipse.jgit.junit.LocalDiskRepositoryTestCase;
import org.eclipse.jgit.lib.ConfigConstants; import org.eclipse.jgit.lib.ConfigConstants;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.util.FileUtils; import org.eclipse.jgit.util.FileUtils;
import org.junit.Test; import org.junit.Test;
@ -108,4 +111,58 @@ public class FileRepositoryBuilderTest extends LocalDiskRepositoryTestCase {
assertNotNull(e.getMessage()); 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());
}
} }

53
org.eclipse.jgit/src/org/eclipse/jgit/lib/BaseRepositoryBuilder.java

@ -100,6 +100,29 @@ public class BaseRepositoryBuilder<B extends BaseRepositoryBuilder, R extends Re
&& ref[7] == ' '; && 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 FS fs;
private File gitDir; private File gitDir;
@ -491,6 +514,12 @@ public class BaseRepositoryBuilder<B extends BaseRepositoryBuilder, R extends Re
if (FileKey.isGitRepository(dir, tryFS)) { if (FileKey.isGitRepository(dir, tryFS)) {
setGitDir(dir); setGitDir(dir);
break; 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(); current = current.getParentFile();
@ -567,30 +596,8 @@ public class BaseRepositoryBuilder<B extends BaseRepositoryBuilder, R extends Re
File dotGit = new File(getWorkTree(), DOT_GIT); File dotGit = new File(getWorkTree(), DOT_GIT);
if (!dotGit.isFile()) if (!dotGit.isFile())
setGitDir(dotGit); 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 else
setGitDir(new File(getWorkTree(), gitdirPath) setGitDir(getSymRef(getWorkTree(), dotGit));
.getCanonicalFile());
}
} }
} }

Loading…
Cancel
Save