import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.lib.RepositoryCache;
import org.eclipse.jgit.lib.RepositoryCache.FileKey;
+import org.eclipse.jgit.util.FS;
/** Default resolver serving from a single root path in local filesystem. */
public class FileResolver implements RepositoryResolver {
final Repository db;
try {
final File gitdir = new File(basePath, repositoryName);
- db = RepositoryCache.open(FileKey.lenient(gitdir), true);
+ db = RepositoryCache.open(FileKey.lenient(gitdir, FS.DETECTED), true);
} catch (IOException e) {
throw new RepositoryNotFoundException(repositoryName, e);
}
import org.eclipse.jgit.errors.ConfigInvalidException;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.FileBasedConfig;
+import org.eclipse.jgit.util.FS;
import org.eclipse.jgit.util.SystemReader;
public class MockSystemReader extends SystemReader {
}
@Override
- public FileBasedConfig openUserConfig() {
+ public FileBasedConfig openUserConfig(FS fs) {
return userGitConfig;
}
import org.eclipse.jgit.treewalk.AbstractTreeIterator;
import org.eclipse.jgit.treewalk.CanonicalTreeParser;
import org.eclipse.jgit.treewalk.FileTreeIterator;
+import org.eclipse.jgit.util.FS;
/**
* Custom argument handler {@link AbstractTreeIterator} from string values.
final String name = params.getParameter(0);
if (new File(name).isDirectory()) {
- setter.addValue(new FileTreeIterator(new File(name)));
+ setter.addValue(new FileTreeIterator(new File(name), FS.DETECTED));
return 1;
}
}
public void test030_executeBit_coreModeTrue() throws IllegalArgumentException, IllegalAccessException, InvocationTargetException, Error, Exception {
- if (!FS.INSTANCE.supportsExecute()) {
+ if (!FS.DETECTED.supportsExecute()) {
System.err.println("Test ignored since platform FS does not support the execute permission");
return;
}
}
public void test031_executeBit_coreModeFalse() throws IllegalArgumentException, IllegalAccessException, InvocationTargetException, Error, Exception {
- if (!FS.INSTANCE.supportsExecute()) {
+ if (!FS.DETECTED.supportsExecute()) {
System.err.println("Test ignored since platform FS does not support the execute permission");
return;
}
File gitdir = db.getDirectory();
File parent = gitdir.getParentFile();
File other = new File(parent, "notagit");
- assertEquals(gitdir, FileKey.exact(gitdir).getFile());
- assertEquals(parent, FileKey.exact(parent).getFile());
- assertEquals(other, FileKey.exact(other).getFile());
+ assertEquals(gitdir, FileKey.exact(gitdir, db.getFS()).getFile());
+ assertEquals(parent, FileKey.exact(parent, db.getFS()).getFile());
+ assertEquals(other, FileKey.exact(other, db.getFS()).getFile());
- assertEquals(gitdir, FileKey.lenient(gitdir).getFile());
- assertEquals(gitdir, FileKey.lenient(parent).getFile());
- assertEquals(other, FileKey.lenient(other).getFile());
+ assertEquals(gitdir, FileKey.lenient(gitdir, db.getFS()).getFile());
+ assertEquals(gitdir, FileKey.lenient(parent, db.getFS()).getFile());
+ assertEquals(other, FileKey.lenient(other, db.getFS()).getFile());
}
public void testBareFileKey() throws IOException {
assertTrue(name.endsWith(".git"));
name = name.substring(0, name.length() - 4);
- assertEquals(gitdir, FileKey.exact(gitdir).getFile());
+ assertEquals(gitdir, FileKey.exact(gitdir, db.getFS()).getFile());
- assertEquals(gitdir, FileKey.lenient(gitdir).getFile());
- assertEquals(gitdir, FileKey.lenient(new File(parent, name)).getFile());
+ assertEquals(gitdir, FileKey.lenient(gitdir, db.getFS()).getFile());
+ assertEquals(gitdir, FileKey.lenient(new File(parent, name), db.getFS()).getFile());
}
public void testFileKeyOpenExisting() throws IOException {
Repository r;
- r = new FileKey(db.getDirectory()).open(true);
+ r = new FileKey(db.getDirectory(), db.getFS()).open(true);
assertNotNull(r);
assertEquals(db.getDirectory(), r.getDirectory());
r.close();
- r = new FileKey(db.getDirectory()).open(false);
+ r = new FileKey(db.getDirectory(), db.getFS()).open(false);
assertNotNull(r);
assertEquals(db.getDirectory(), r.getDirectory());
r.close();
assertFalse(gitdir.exists());
try {
- new FileKey(gitdir).open(true);
+ new FileKey(gitdir, db.getFS()).open(true);
fail("incorrectly opened a non existant repository");
} catch (RepositoryNotFoundException e) {
assertEquals("repository not found: " + gitdir, e.getMessage());
}
- final Repository o = new FileKey(gitdir).open(false);
+ final Repository o = new FileKey(gitdir, db.getFS()).open(false);
assertNotNull(o);
assertEquals(gitdir, o.getDirectory());
assertFalse(gitdir.exists());
public void testCacheRegisterOpen() throws Exception {
final File dir = db.getDirectory();
RepositoryCache.register(db);
- assertSame(db, RepositoryCache.open(FileKey.exact(dir)));
+ assertSame(db, RepositoryCache.open(FileKey.exact(dir, db.getFS())));
assertEquals(".git", dir.getName());
final File parent = dir.getParentFile();
- assertSame(db, RepositoryCache.open(FileKey.lenient(parent)));
+ assertSame(db, RepositoryCache.open(FileKey.lenient(parent, db.getFS())));
}
public void testCacheOpen() throws Exception {
- final FileKey loc = FileKey.exact(db.getDirectory());
+ final FileKey loc = FileKey.exact(db.getDirectory(), db.getFS());
final Repository d2 = RepositoryCache.open(loc);
assertNotSame(db, d2);
- assertSame(d2, RepositoryCache.open(FileKey.exact(loc.getFile())));
+ assertSame(d2, RepositoryCache.open(FileKey.exact(loc.getFile(), db.getFS())));
d2.close();
d2.close();
}
import org.eclipse.jgit.errors.ConfigInvalidException;
import org.eclipse.jgit.junit.MockSystemReader;
+import org.eclipse.jgit.util.FS;
import org.eclipse.jgit.util.SystemReader;
/**
final MockSystemReader mockSystemReader = new MockSystemReader();
SystemReader.setInstance(mockSystemReader);
final String hostname = mockSystemReader.getHostname();
- final Config userGitConfig = mockSystemReader.openUserConfig();
+ final Config userGitConfig = mockSystemReader.openUserConfig(FS.DETECTED);
final Config localConfig = new Config(userGitConfig);
mockSystemReader.clearProperties();
public void testEmptyIfRootIsFile() throws Exception {
final File r = new File(trash, paths[0]);
assertTrue(r.isFile());
- final FileTreeIterator fti = new FileTreeIterator(r);
+ final FileTreeIterator fti = new FileTreeIterator(r, db.getFS());
assertTrue(fti.first());
assertTrue(fti.eof());
}
public void testEmptyIfRootDoesNotExist() throws Exception {
final File r = new File(trash, "not-existing-file");
assertFalse(r.exists());
- final FileTreeIterator fti = new FileTreeIterator(r);
+ final FileTreeIterator fti = new FileTreeIterator(r, db.getFS());
assertTrue(fti.first());
assertTrue(fti.eof());
}
r.mkdir();
assertTrue(r.isDirectory());
- final FileTreeIterator fti = new FileTreeIterator(r);
+ final FileTreeIterator fti = new FileTreeIterator(r, db.getFS());
assertTrue(fti.first());
assertTrue(fti.eof());
}
public void testSimpleIterate() throws Exception {
- final FileTreeIterator top = new FileTreeIterator(trash);
+ final FileTreeIterator top = new FileTreeIterator(trash, db.getFS());
assertTrue(top.first());
assertFalse(top.eof());
}
public void testComputeFileObjectId() throws Exception {
- final FileTreeIterator top = new FileTreeIterator(trash);
+ final FileTreeIterator top = new FileTreeIterator(trash, db.getFS());
final MessageDigest md = Constants.newMessageDigest();
md.update(Constants.encodeASCII(Constants.TYPE_BLOB));
import org.eclipse.jgit.dircache.DirCache;
import org.eclipse.jgit.errors.CorruptObjectException;
import org.eclipse.jgit.errors.NotSupportedException;
-import org.eclipse.jgit.util.FS;
import org.eclipse.jgit.util.RawParseUtils;
/**
}
}
- static boolean File_canExecute( File f){
- return FS.INSTANCE.canExecute(f);
+ private boolean File_canExecute(File f){
+ return db.getFS().canExecute(f);
}
- static boolean File_setExecute(File f, boolean value) {
- return FS.INSTANCE.setExecute(f, value);
+ private boolean File_setExecute(File f, boolean value) {
+ return db.getFS().setExecute(f, value);
}
- static boolean File_hasExecute() {
- return FS.INSTANCE.supportsExecute();
+ private boolean File_hasExecute() {
+ return db.getFS().supportsExecute();
}
static byte[] makeKey(File wd, File f) {
private final File[] alternateObjectDir;
+ private final FS fs;
+
/**
* Initialize a reference to an on-disk object directory.
*
* the location of the <code>objects</code> directory.
* @param alternateObjectDir
* a list of alternate object directories
+ * @param fs
+ * the file system abstraction which will be necessary to
+ * perform certain file system operations.
*/
- public ObjectDirectory(final File dir, File[] alternateObjectDir) {
+ public ObjectDirectory(final File dir, File[] alternateObjectDir, FS fs) {
objects = dir;
this.alternateObjectDir = alternateObjectDir;
infoDirectory = new File(objects, "info");
packDirectory = new File(objects, "pack");
alternatesFile = new File(infoDirectory, "alternates");
packList = new AtomicReference<PackList>(NO_PACKS);
+ this.fs = fs;
}
/**
private ObjectDatabase openAlternate(final String location)
throws IOException {
- final File objdir = FS.resolve(objects, location);
+ final File objdir = fs.resolve(objects, location);
return openAlternate(objdir);
}
private ObjectDatabase openAlternate(File objdir) throws IOException {
final File parent = objdir.getParentFile();
- if (FileKey.isGitRepository(parent)) {
- final Repository db = RepositoryCache.open(FileKey.exact(parent));
+ if (FileKey.isGitRepository(parent, fs)) {
+ final Repository db = RepositoryCache.open(FileKey.exact(parent, fs));
return new AlternateRepositoryDatabase(db);
}
- return new ObjectDirectory(objdir, null);
+ return new ObjectDirectory(objdir, null, fs);
}
private static final class PackList {
private final AtomicInteger lastNotifiedModCnt = new AtomicInteger();
RefDirectory(final Repository db) {
+ final FS fs = db.getFS();
parent = db;
gitDir = db.getDirectory();
- refsDir = FS.resolve(gitDir, R_REFS);
- logsDir = FS.resolve(gitDir, LOGS);
- logsRefsDir = FS.resolve(gitDir, LOGS + '/' + R_REFS);
- packedRefsFile = FS.resolve(gitDir, PACKED_REFS);
+ refsDir = fs.resolve(gitDir, R_REFS);
+ logsDir = fs.resolve(gitDir, LOGS);
+ logsRefsDir = fs.resolve(gitDir, LOGS + '/' + R_REFS);
+ packedRefsFile = fs.resolve(gitDir, PACKED_REFS);
looseRefs.set(RefList.<LooseRef> emptyList());
packedRefs.set(PackedRefList.NO_PACKED_REFS);
private final File gitDir;
+ private final FS fs;
+
private final FileBasedConfig userConfig;
private final RepositoryConfig config;
*/
public Repository(final File d, final File workTree, final File objectDir,
final File[] alternateObjectDir, final File indexFile) throws IOException {
+ this(d, workTree, objectDir, alternateObjectDir, indexFile, FS.DETECTED);
+ }
+
+ /**
+ * Construct a representation of a Git repository using the given parameters
+ * possibly overriding default conventions.
+ *
+ * @param d
+ * GIT_DIR (the location of the repository metadata). May be null
+ * for default value in which case it depends on GIT_WORK_TREE.
+ * @param workTree
+ * GIT_WORK_TREE (the root of the checkout). May be null for
+ * default value if GIT_DIR is
+ * @param objectDir
+ * GIT_OBJECT_DIRECTORY (where objects and are stored). May be
+ * null for default value. Relative names ares resolved against
+ * GIT_WORK_TREE
+ * @param alternateObjectDir
+ * GIT_ALTERNATE_OBJECT_DIRECTORIES (where more objects are read
+ * from). May be null for default value. Relative names ares
+ * resolved against GIT_WORK_TREE
+ * @param indexFile
+ * GIT_INDEX_FILE (the location of the index file). May be null
+ * for default value. Relative names ares resolved against
+ * GIT_WORK_TREE.
+ * @param fs
+ * the file system abstraction which will be necessary to
+ * perform certain file system operations.
+ * @throws IOException
+ * the repository appears to already exist but cannot be
+ * accessed.
+ */
+ public Repository(final File d, final File workTree, final File objectDir,
+ final File[] alternateObjectDir, final File indexFile,
+ FS fs) throws IOException {
if (workTree != null) {
workDir = workTree;
throw new IllegalArgumentException(JGitText.get().eitherGIT_DIRorGIT_WORK_TREEmustBePassed);
}
- userConfig = SystemReader.getInstance().openUserConfig();
- config = new RepositoryConfig(userConfig, FS.resolve(gitDir, "config"));
+ this.fs = fs;
+
+ userConfig = SystemReader.getInstance().openUserConfig(fs);
+ config = new RepositoryConfig(userConfig, fs.resolve(gitDir, "config"));
loadUserConfig();
loadConfig();
if (workDir == null) {
String workTreeConfig = getConfig().getString("core", null, "worktree");
if (workTreeConfig != null) {
- workDir = FS.resolve(d, workTreeConfig);
+ workDir = fs.resolve(d, workTreeConfig);
} else {
workDir = gitDir.getParentFile();
}
refs = new RefDirectory(this);
if (objectDir != null)
- objectDatabase = new ObjectDirectory(FS.resolve(objectDir, ""),
- alternateObjectDir);
+ objectDatabase = new ObjectDirectory(fs.resolve(objectDir, ""),
+ alternateObjectDir, fs);
else
- objectDatabase = new ObjectDirectory(FS.resolve(gitDir, "objects"),
- alternateObjectDir);
+ objectDatabase = new ObjectDirectory(fs.resolve(gitDir, "objects"),
+ alternateObjectDir, fs);
if (indexFile != null)
this.indexFile = indexFile;
return config;
}
+ /**
+ * @return the used file system abstraction
+ */
+ public FS getFS() {
+ return fs;
+ }
+
/**
* Construct a filename where the loose object having a specified SHA-1
* should be stored. If the object is stored in a shared repository the path
* repository to register.
*/
public static void register(final Repository db) {
- cache.registerRepository(FileKey.exact(db.getDirectory()), db);
+ cache.registerRepository(FileKey.exact(db.getDirectory(), db.getFS()), db);
}
/**
* repository to unregister.
*/
public static void close(final Repository db) {
- cache.unregisterRepository(FileKey.exact(db.getDirectory()));
+ cache.unregisterRepository(FileKey.exact(db.getDirectory(), db.getFS()));
}
/** Unregister all repositories from the cache. */
*
* @param directory
* location where the repository database is.
+ * @param fs
+ * the file system abstraction which will be necessary to
+ * perform certain file system operations.
* @return a key for the given directory.
- * @see #lenient(File)
+ * @see #lenient(File, FS)
*/
- public static FileKey exact(final File directory) {
- return new FileKey(directory);
+ public static FileKey exact(final File directory, FS fs) {
+ return new FileKey(directory, fs);
}
/**
*
* @param directory
* location where the repository database might be.
+ * @param fs
+ * the file system abstraction which will be necessary to
+ * perform certain file system operations.
* @return a key for the given directory.
- * @see #exact(File)
+ * @see #exact(File, FS)
*/
- public static FileKey lenient(final File directory) {
- final File gitdir = resolve(directory);
- return new FileKey(gitdir != null ? gitdir : directory);
+ public static FileKey lenient(final File directory, FS fs) {
+ final File gitdir = resolve(directory, fs);
+ return new FileKey(gitdir != null ? gitdir : directory, fs);
}
private final File path;
+ private final FS fs;
/**
* @param directory
* exact location of the repository.
+ * @param fs
+ * the file system abstraction which will be necessary to
+ * perform certain file system operations.
*/
- protected FileKey(final File directory) {
+ protected FileKey(final File directory, FS fs) {
path = canonical(directory);
+ this.fs = fs;
}
private static File canonical(final File path) {
}
public Repository open(final boolean mustExist) throws IOException {
- if (mustExist && !isGitRepository(path))
+ if (mustExist && !isGitRepository(path, fs))
throw new RepositoryNotFoundException(path);
return new Repository(path);
}
*
* @param dir
* the location of the directory to examine.
+ * @param fs
+ * the file system abstraction which will be necessary to
+ * perform certain file system operations.
* @return true if the directory "looks like" a Git repository; false if
* it doesn't look enough like a Git directory to really be a
* Git directory.
*/
- public static boolean isGitRepository(final File dir) {
- return FS.resolve(dir, "objects").exists()
- && FS.resolve(dir, "refs").exists()
+ public static boolean isGitRepository(final File dir, FS fs) {
+ return fs.resolve(dir, "objects").exists()
+ && fs.resolve(dir, "refs").exists()
&& isValidHead(new File(dir, Constants.HEAD));
}
*
* @param directory
* location to guess from. Several permutations are tried.
+ * @param fs
+ * the file system abstraction which will be necessary to
+ * perform certain file system operations.
* @return the actual directory location if a better match is found;
* null if there is no suitable match.
*/
- public static File resolve(final File directory) {
- if (isGitRepository(directory))
+ public static File resolve(final File directory, FS fs) {
+ if (isGitRepository(directory, fs))
return directory;
- if (isGitRepository(new File(directory, Constants.DOT_GIT)))
+ if (isGitRepository(new File(directory, Constants.DOT_GIT), fs))
return new File(directory, Constants.DOT_GIT);
final String name = directory.getName();
final File parent = directory.getParentFile();
- if (isGitRepository(new File(parent, name + Constants.DOT_GIT_EXT)))
+ if (isGitRepository(new File(parent, name + Constants.DOT_GIT_EXT), fs))
return new File(parent, name + Constants.DOT_GIT_EXT);
return null;
}
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.lib.RepositoryCache;
import org.eclipse.jgit.lib.RepositoryCache.FileKey;
+import org.eclipse.jgit.util.FS;
/** Basic daemon for the anonymous <code>git://</code> transport protocol. */
public class Daemon {
}
for (final File baseDir : exportBase) {
- final File gitdir = FileKey.resolve(new File(baseDir, name));
+ final File gitdir = FileKey.resolve(new File(baseDir, name), FS.DETECTED);
if (gitdir != null && canExport(gitdir))
return openRepository(gitdir);
}
private static Repository openRepository(final File gitdir) {
try {
- return RepositoryCache.open(FileKey.exact(gitdir));
+ return RepositoryCache.open(FileKey.exact(gitdir, FS.DETECTED));
} catch (IOException err) {
// null signals it "wasn't found", which is all that is suitable
// for the remote client to know.
* requests are cached and are automatically updated if the user modifies
* the configuration file since the last time it was cached.
*
+ * @param fs
+ * the file system abstraction which will be necessary to
+ * perform certain file system operations.
* @return a caching reader of the user's configuration file.
*/
- public static OpenSshConfig get() {
- File home = FS.userHome();
+ public static OpenSshConfig get(FS fs) {
+ File home = fs.userHome();
if (home == null)
home = new File(".").getAbsoluteFile();
@Override
public synchronized Session getSession(String user, String pass,
- String host, int port) throws JSchException {
- final OpenSshConfig.Host hc = getConfig().lookup(host);
+ String host, int port, FS fs) throws JSchException {
+ if (config == null)
+ config = OpenSshConfig.get(fs);
+
+ final OpenSshConfig.Host hc = config.lookup(host);
host = hc.getHostName();
if (port <= 0)
port = hc.getPort();
if (user == null)
user = hc.getUser();
- final Session session = createSession(hc, user, host, port);
+ final Session session = createSession(hc, user, host, port, fs);
if (pass != null)
session.setPassword(pass);
final String strictHostKeyCheckingPolicy = hc
* server name to connect to.
* @param port
* port number of the SSH daemon (typically 22).
+ * @param fs
+ * the file system abstraction which will be necessary to
+ * perform certain file system operations.
* @return new session instance, but otherwise unconfigured.
* @throws JSchException
* the session could not be created.
*/
protected Session createSession(final OpenSshConfig.Host hc,
- final String user, final String host, final int port)
+ final String user, final String host, final int port, FS fs)
throws JSchException {
- return getJSch(hc).getSession(user, host, port);
+ return getJSch(hc, fs).getSession(user, host, port);
}
/**
*
* @param hc
* host configuration
+ * @param fs
+ * the file system abstraction which will be necessary to
+ * perform certain file system operations.
* @return the JSch instance to use.
* @throws JSchException
* the user configuration could not be created.
*/
- protected JSch getJSch(final OpenSshConfig.Host hc) throws JSchException {
- final JSch def = getDefaultJSch();
+ protected JSch getJSch(final OpenSshConfig.Host hc, FS fs) throws JSchException {
+ if (defaultJSch == null) {
+ defaultJSch = createDefaultJSch(fs);
+ for (Object name : defaultJSch.getIdentityNames()) {
+ byIdentityFile.put((String) name, defaultJSch);
+ }
+ }
+
final File identityFile = hc.getIdentityFile();
if (identityFile == null) {
- return def;
+ return defaultJSch;
}
final String identityKey = identityFile.getAbsolutePath();
JSch jsch = byIdentityFile.get(identityKey);
if (jsch == null) {
jsch = new JSch();
- jsch.setHostKeyRepository(def.getHostKeyRepository());
+ jsch.setHostKeyRepository(defaultJSch.getHostKeyRepository());
jsch.addIdentity(identityKey);
byIdentityFile.put(identityKey, jsch);
}
return jsch;
}
- private JSch getDefaultJSch() throws JSchException {
- if (defaultJSch == null) {
- defaultJSch = createDefaultJSch();
- for (Object name : defaultJSch.getIdentityNames()) {
- byIdentityFile.put((String) name, defaultJSch);
- }
- }
- return defaultJSch;
- }
-
/**
+ * @param fs
+ * the file system abstraction which will be necessary to
+ * perform certain file system operations.
* @return the new default JSch implementation.
* @throws JSchException
* known host keys cannot be loaded.
*/
- protected JSch createDefaultJSch() throws JSchException {
+ protected JSch createDefaultJSch(FS fs) throws JSchException {
final JSch jsch = new JSch();
- knownHosts(jsch);
- identities(jsch);
+ knownHosts(jsch, fs);
+ identities(jsch, fs);
return jsch;
}
- private OpenSshConfig getConfig() {
- if (config == null)
- config = OpenSshConfig.get();
- return config;
- }
-
- private static void knownHosts(final JSch sch) throws JSchException {
- final File home = FS.userHome();
+ private static void knownHosts(final JSch sch, FS fs) throws JSchException {
+ final File home = fs.userHome();
if (home == null)
return;
final File known_hosts = new File(new File(home, ".ssh"), "known_hosts");
}
}
- private static void identities(final JSch sch) {
- final File home = FS.userHome();
+ private static void identities(final JSch sch, FS fs) {
+ final File home = fs.userHome();
if (home == null)
return;
final File sshdir = new File(home, ".ssh");
package org.eclipse.jgit.transport;
+import org.eclipse.jgit.util.FS;
+
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
* @param port
* port number the server is listening for connections on. May be <=
* 0 to indicate the IANA registered port of 22 should be used.
+ * @param fs
+ * the file system abstraction which will be necessary to
+ * perform certain file system operations.
* @return a session that can contact the remote host.
* @throws JSchException
* the session could not be created.
*/
public abstract Session getSession(String user, String pass, String host,
- int port) throws JSchException;
+ int port, FS fs) throws JSchException;
/**
* Close (or recycle) a session to a host.
*
* @param session
* a session previously obtained from this factory's
- * {@link #getSession(String,String, String, int)} method.s
+ * {@link #getSession(String,String, String, int, FS)} method.s
*/
public void releaseSession(final Session session) {
if (session.isConnected())
final String host = uri.getHost();
final int port = uri.getPort();
try {
- sock = sch.getSession(user, pass, host, port);
+ sock = sch.getSession(user, pass, host, port, local.getFS());
if (!sock.isConnected())
sock.connect(tms);
} catch (JSchException je) {
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.lib.TransferConfig;
+import org.eclipse.jgit.util.FS;
/**
* Connects two Git repositories together and copies objects between them.
*
* @param remote
* location of the remote repository.
+ * @param fs
+ * type of filesystem the local repository is stored on.
* @return true if the protocol is supported.
*/
- public static boolean canHandleProtocol(final URIish remote) {
+ public static boolean canHandleProtocol(final URIish remote, final FS fs) {
if (TransportGitSsh.canHandle(remote))
return true;
else if (TransportAmazonS3.canHandle(remote))
return true;
- else if (TransportBundleFile.canHandle(remote))
+ else if (TransportBundleFile.canHandle(remote, fs))
return true;
- else if (TransportLocal.canHandle(remote))
+ else if (TransportLocal.canHandle(remote, fs))
return true;
return false;
else if (TransportAmazonS3.canHandle(remote))
return new TransportAmazonS3(local, remote);
- else if (TransportBundleFile.canHandle(remote))
+ else if (TransportBundleFile.canHandle(remote, local.getFS()))
return new TransportBundleFile(local, remote);
- else if (TransportLocal.canHandle(remote))
+ else if (TransportLocal.canHandle(remote, local.getFS()))
return new TransportLocal(local, remote);
throw new NotSupportedException(MessageFormat.format(JGitText.get().URINotSupported, remote));
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.lib.SymbolicRef;
import org.eclipse.jgit.lib.Ref.Storage;
-import org.eclipse.jgit.util.FS;
/**
* Transport over the non-Git aware Amazon S3 protocol.
Properties props = null;
File propsFile = new File(local.getDirectory(), uri.getUser());
if (!propsFile.isFile())
- propsFile = new File(FS.userHome(), uri.getUser());
+ propsFile = new File(local.getFS().userHome(), uri.getUser());
if (propsFile.isFile()) {
try {
props = AmazonS3.properties(propsFile);
import org.eclipse.jgit.util.FS;
class TransportBundleFile extends Transport implements TransportBundle {
- static boolean canHandle(final URIish uri) {
+ static boolean canHandle(final URIish uri, FS fs) {
if (uri.getHost() != null || uri.getPort() > 0 || uri.getUser() != null
|| uri.getPass() != null || uri.getPath() == null)
return false;
if ("file".equals(uri.getScheme()) || uri.getScheme() == null) {
- final File f = FS.resolve(new File("."), uri.getPath());
+ final File f = fs.resolve(new File("."), uri.getPath());
return f.isFile() || f.getName().endsWith(".bundle");
}
TransportBundleFile(final Repository local, final URIish uri) {
super(local, uri);
- bundle = FS.resolve(new File("."), uri.getPath()).getAbsoluteFile();
+ bundle = local.getFS().resolve(new File("."), uri.getPath()).getAbsoluteFile();
}
@Override
class TransportLocal extends Transport implements PackTransport {
private static final String PWD = ".";
- static boolean canHandle(final URIish uri) {
+ static boolean canHandle(final URIish uri, FS fs) {
if (uri.getHost() != null || uri.getPort() > 0 || uri.getUser() != null
|| uri.getPass() != null || uri.getPath() == null)
return false;
if ("file".equals(uri.getScheme()) || uri.getScheme() == null)
- return FS.resolve(new File(PWD), uri.getPath()).isDirectory();
+ return fs.resolve(new File(PWD), uri.getPath()).isDirectory();
return false;
}
TransportLocal(final Repository local, final URIish uri) {
super(local, uri);
- File d = FS.resolve(new File(PWD), uri.getPath()).getAbsoluteFile();
+ File d = local.getFS().resolve(new File(PWD), uri.getPath()).getAbsoluteFile();
if (new File(d, Constants.DOT_GIT).isDirectory())
d = new File(d, Constants.DOT_GIT);
remoteGitDir = d;
*/
public class FileTreeIterator extends WorkingTreeIterator {
private final File directory;
+ private final FS fs;
/**
* Create a new iterator to traverse the given directory and its children.
* @param root
* the starting directory. This directory should correspond to
* the root of the repository.
+ * @param fs
+ * the file system abstraction which will be necessary to
+ * perform certain file system operations.
*/
- public FileTreeIterator(final File root) {
+ public FileTreeIterator(final File root, FS fs) {
directory = root;
+ this.fs = fs;
init(entries());
}
*
* @param p
* the parent iterator we were created from.
+ * @param fs
+ * the file system abstraction which will be necessary to
+ * perform certain file system operations.
* @param root
* the subdirectory. This should be a directory contained within
* the parent directory.
*/
- protected FileTreeIterator(final FileTreeIterator p, final File root) {
+ protected FileTreeIterator(final FileTreeIterator p, final File root, FS fs) {
super(p);
directory = root;
+ this.fs = fs;
init(entries());
}
@Override
public AbstractTreeIterator createSubtreeIterator(final Repository repo)
throws IncorrectObjectTypeException, IOException {
- return new FileTreeIterator(this, ((FileEntry) current()).file);
+ return new FileTreeIterator(this, ((FileEntry) current()).file, fs);
}
private Entry[] entries() {
return EOF;
final Entry[] r = new Entry[all.length];
for (int i = 0; i < r.length; i++)
- r[i] = new FileEntry(all[i]);
+ r[i] = new FileEntry(all[i], fs);
return r;
}
private long lastModified;
- FileEntry(final File f) {
+ FileEntry(final File f, FS fs) {
file = f;
if (f.isDirectory()) {
mode = FileMode.GITLINK;
else
mode = FileMode.TREE;
- } else if (FS.INSTANCE.canExecute(file))
+ } else if (fs.canExecute(file))
mode = FileMode.EXECUTABLE_FILE;
else
mode = FileMode.REGULAR_FILE;
/** Abstraction to support various file system operations not in Java. */
public abstract class FS {
- /** The implementation selected for this operating system and JRE. */
- public static final FS INSTANCE;
+ /** The auto-detected implementation selected for this operating system and JRE. */
+ public static final FS DETECTED;
static {
if (FS_Win32.detect()) {
if (FS_Win32_Cygwin.detect())
- INSTANCE = new FS_Win32_Cygwin();
+ DETECTED = new FS_Win32_Cygwin();
else
- INSTANCE = new FS_Win32();
+ DETECTED = new FS_Win32();
} else if (FS_POSIX_Java6.detect())
- INSTANCE = new FS_POSIX_Java6();
+ DETECTED = new FS_POSIX_Java6();
else
- INSTANCE = new FS_POSIX_Java5();
+ DETECTED = new FS_POSIX_Java5();
+ }
+
+ private final File userHome;
+
+ /**
+ * Constructs a file system abstraction.
+ */
+ protected FS() {
+ this.userHome = userHomeImpl();
}
/**
* @return the translated path. <code>new File(dir,name)</code> if this
* platform does not require path name translation.
*/
- public static File resolve(final File dir, final String name) {
- return INSTANCE.resolveImpl(dir, name);
- }
-
- /**
- * Resolve this file to its actual path name that the JRE can use.
- * <p>
- * This method can be relatively expensive. Computing a translation may
- * require forking an external process per path name translated. Callers
- * should try to minimize the number of translations necessary by caching
- * the results.
- * <p>
- * Not all platforms and JREs require path name translation. Currently only
- * Cygwin on Win32 require translation for Cygwin based paths.
- *
- * @param dir
- * directory relative to which the path name is.
- * @param name
- * path name to translate.
- * @return the translated path. <code>new File(dir,name)</code> if this
- * platform does not require path name translation.
- */
- protected File resolveImpl(final File dir, final String name) {
+ public File resolve(final File dir, final String name) {
final File abspn = new File(name);
if (abspn.isAbsolute())
return abspn;
*
* @return the user's home directory; null if the user does not have one.
*/
- public static File userHome() {
- return USER_HOME.home;
- }
-
- private static class USER_HOME {
- static final File home = INSTANCE.userHomeImpl();
+ public File userHome() {
+ return userHome;
}
/**
return false;
}
- protected File resolveImpl(final File dir, final String pn) {
+ public File resolve(final File dir, final String pn) {
try {
final Process p;
// Fall through and use the default return.
//
}
- return super.resolveImpl(dir, pn);
+ return super.resolve(dir, pn);
}
@Override
});
if (home == null || home.length() == 0)
return super.userHomeImpl();
- return resolveImpl(new File("."), home);
+ return resolve(new File("."), home);
}
}
return System.getProperty(key);
}
- public FileBasedConfig openUserConfig() {
- final File home = FS.userHome();
+ public FileBasedConfig openUserConfig(FS fs) {
+ final File home = fs.userHome();
return new FileBasedConfig(new File(home, ".gitconfig"));
}
public abstract String getProperty(String key);
/**
+ * @param fs
+ * the file system abstraction which will be necessary to
+ * perform certain file system operations.
* @return the git configuration found in the user home
*/
- public abstract FileBasedConfig openUserConfig();
+ public abstract FileBasedConfig openUserConfig(FS fs);
/**
* @return the current system time