Make the supported Transports extensible and discoverable
The new TransportProtocol type describes what a particular Transport implementation wants in order to support a connection. 3rd parties can now plug into the Transport.open() logic by implementing their own TransportProtocol and Transport classes, and registering with Transport.register(). GUI applications can help the user configure a connection by looking at the supported fields of a particular TransportProtocol type, which makes the GUI more dynamic and may better support new Transports. Change-Id: Iafd8e3a6285261412aac6cba8e2c333f8b7b76a5 Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
This commit is contained in:
parent
2a137d8dea
commit
305a8ac45f
|
@ -143,7 +143,7 @@ public void tearDown() throws Exception {
|
|||
@Test
|
||||
public void testFilterHidesPrivate() throws Exception {
|
||||
Map<String, Ref> refs;
|
||||
TransportLocal t = new TransportLocal(src, uriOf(dst)) {
|
||||
TransportLocal t = new TransportLocal(src, uriOf(dst), dst.getDirectory()) {
|
||||
@Override
|
||||
ReceivePack createReceivePack(final Repository db) {
|
||||
db.close();
|
||||
|
@ -206,7 +206,7 @@ public void testSuccess() throws Exception {
|
|||
|
||||
// Push this new content to the remote, doing strict validation.
|
||||
//
|
||||
TransportLocal t = new TransportLocal(src, uriOf(dst)) {
|
||||
TransportLocal t = new TransportLocal(src, uriOf(dst), dst.getDirectory()) {
|
||||
@Override
|
||||
ReceivePack createReceivePack(final Repository db) {
|
||||
db.close();
|
||||
|
|
|
@ -549,6 +549,6 @@ public void testFileProtocol() throws IllegalArgumentException,
|
|||
public void testMissingPort() throws URISyntaxException {
|
||||
final String incorrectSshUrl = "ssh://some-host:/path/to/repository.git";
|
||||
URIish u = new URIish(incorrectSshUrl);
|
||||
assertFalse(TransportGitSsh.canHandle(u));
|
||||
assertFalse(TransportGitSsh.PROTO_SSH.canHandle(null, u, null));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -419,6 +419,14 @@ transportExceptionEmptyRef=Empty ref: {0}
|
|||
transportExceptionInvalid=Invalid {0} {1}:{2}
|
||||
transportExceptionMissingAssumed=Missing assumed {0}
|
||||
transportExceptionReadRef=read {0}
|
||||
transportProtoAmazonS3=Amazon S3
|
||||
transportProtoBundleFile=Git Bundle File
|
||||
transportProtoGitAnon=Anonymous Git
|
||||
transportProtoFTP=FTP
|
||||
transportProtoHTTP=HTTP
|
||||
transportProtoLocal=Local Git Repository
|
||||
transportProtoSFTP=SFTP
|
||||
transportProtoSSH=SSH
|
||||
treeEntryAlreadyExists=Tree entry "{0}" already exists.
|
||||
treeIteratorDoesNotSupportRemove=TreeIterator does not support remove()
|
||||
truncatedHunkLinesMissingForAncestor=Truncated hunk, at least {0} lines missing for ancestor {1}
|
||||
|
|
|
@ -479,6 +479,14 @@ public static JGitText get() {
|
|||
/***/ public String transportExceptionInvalid;
|
||||
/***/ public String transportExceptionMissingAssumed;
|
||||
/***/ public String transportExceptionReadRef;
|
||||
/***/ public String transportProtoAmazonS3;
|
||||
/***/ public String transportProtoBundleFile;
|
||||
/***/ public String transportProtoFTP;
|
||||
/***/ public String transportProtoGitAnon;
|
||||
/***/ public String transportProtoHTTP;
|
||||
/***/ public String transportProtoLocal;
|
||||
/***/ public String transportProtoSFTP;
|
||||
/***/ public String transportProtoSSH;
|
||||
/***/ public String treeEntryAlreadyExists;
|
||||
/***/ public String treeIteratorDoesNotSupportRemove;
|
||||
/***/ public String truncatedHunkLinesMissingForAncestor;
|
||||
|
|
|
@ -50,6 +50,7 @@
|
|||
import org.eclipse.jgit.JGitText;
|
||||
import org.eclipse.jgit.api.errors.InvalidRemoteException;
|
||||
import org.eclipse.jgit.api.errors.JGitInternalException;
|
||||
import org.eclipse.jgit.errors.NoRemoteRepositoryException;
|
||||
import org.eclipse.jgit.errors.NotSupportedException;
|
||||
import org.eclipse.jgit.errors.TransportException;
|
||||
import org.eclipse.jgit.lib.Constants;
|
||||
|
@ -121,27 +122,29 @@ public FetchResult call() throws JGitInternalException,
|
|||
|
||||
try {
|
||||
Transport transport = Transport.open(repo, remote);
|
||||
transport.setCheckFetchedObjects(checkFetchedObjects);
|
||||
transport.setRemoveDeletedRefs(removeDeletedRefs);
|
||||
transport.setTimeout(timeout);
|
||||
transport.setDryRun(dryRun);
|
||||
if (tagOption != null)
|
||||
transport.setTagOpt(tagOption);
|
||||
transport.setFetchThin(thin);
|
||||
if (credentialsProvider != null)
|
||||
transport.setCredentialsProvider(credentialsProvider);
|
||||
|
||||
try {
|
||||
transport.setCheckFetchedObjects(checkFetchedObjects);
|
||||
transport.setRemoveDeletedRefs(removeDeletedRefs);
|
||||
transport.setTimeout(timeout);
|
||||
transport.setDryRun(dryRun);
|
||||
if (tagOption != null)
|
||||
transport.setTagOpt(tagOption);
|
||||
transport.setFetchThin(thin);
|
||||
if (credentialsProvider != null)
|
||||
transport.setCredentialsProvider(credentialsProvider);
|
||||
|
||||
FetchResult result = transport.fetch(monitor, refSpecs);
|
||||
return result;
|
||||
|
||||
} catch (TransportException e) {
|
||||
throw new JGitInternalException(
|
||||
JGitText.get().exceptionCaughtDuringExecutionOfFetchCommand,
|
||||
e);
|
||||
} finally {
|
||||
transport.close();
|
||||
}
|
||||
} catch (NoRemoteRepositoryException e) {
|
||||
throw new InvalidRemoteException(MessageFormat.format(
|
||||
JGitText.get().invalidRemote, remote), e);
|
||||
} catch (TransportException e) {
|
||||
throw new JGitInternalException(
|
||||
JGitText.get().exceptionCaughtDuringExecutionOfFetchCommand,
|
||||
e);
|
||||
} catch (URISyntaxException e) {
|
||||
throw new InvalidRemoteException(MessageFormat.format(
|
||||
JGitText.get().invalidRemote, remote));
|
||||
|
|
|
@ -44,9 +44,17 @@ public class InvalidRemoteException extends GitAPIException {
|
|||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* @param msg
|
||||
* @param msg message describing the invalid remote.
|
||||
*/
|
||||
public InvalidRemoteException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param msg message describing the invalid remote.
|
||||
* @param cause why the remote is invalid.
|
||||
*/
|
||||
public InvalidRemoteException(String msg, Throwable cause) {
|
||||
super(msg, cause);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,6 +47,7 @@
|
|||
package org.eclipse.jgit.transport;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.net.URISyntaxException;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.ArrayList;
|
||||
|
@ -56,6 +57,7 @@
|
|||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
import org.eclipse.jgit.JGitText;
|
||||
import org.eclipse.jgit.errors.NotSupportedException;
|
||||
|
@ -66,7 +68,6 @@
|
|||
import org.eclipse.jgit.lib.Ref;
|
||||
import org.eclipse.jgit.lib.Repository;
|
||||
import org.eclipse.jgit.storage.pack.PackConfig;
|
||||
import org.eclipse.jgit.util.FS;
|
||||
|
||||
/**
|
||||
* Connects two Git repositories together and copies objects between them.
|
||||
|
@ -90,6 +91,79 @@ public enum Operation {
|
|||
PUSH;
|
||||
}
|
||||
|
||||
private static final List<WeakReference<TransportProtocol>> protocols =
|
||||
new CopyOnWriteArrayList<WeakReference<TransportProtocol>>();
|
||||
|
||||
static {
|
||||
// Registration goes backwards in order of priority.
|
||||
register(TransportLocal.PROTO_LOCAL);
|
||||
register(TransportBundleFile.PROTO_BUNDLE);
|
||||
register(TransportAmazonS3.PROTO_S3);
|
||||
register(TransportGitAnon.PROTO_GIT);
|
||||
register(TransportSftp.PROTO_SFTP);
|
||||
register(TransportHttp.PROTO_FTP);
|
||||
register(TransportHttp.PROTO_HTTP);
|
||||
register(TransportGitSsh.PROTO_SSH);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a TransportProtocol instance for use during open.
|
||||
* <p>
|
||||
* Protocol definitions are held by WeakReference, allowing them to be
|
||||
* garbage collected when the calling application drops all strongly held
|
||||
* references to the TransportProtocol. Therefore applications should use a
|
||||
* singleton pattern as described in {@link TransportProtocol}'s class
|
||||
* documentation to ensure their protocol does not get disabled by garbage
|
||||
* collection earlier than expected.
|
||||
* <p>
|
||||
* The new protocol is registered in front of all earlier protocols, giving
|
||||
* it higher priority than the built-in protocol definitions.
|
||||
*
|
||||
* @param proto
|
||||
* the protocol definition. Must not be null.
|
||||
*/
|
||||
public static void register(TransportProtocol proto) {
|
||||
protocols.add(0, new WeakReference<TransportProtocol>(proto));
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister a TransportProtocol instance.
|
||||
* <p>
|
||||
* Unregistering a protocol usually isn't necessary, as protocols are held
|
||||
* by weak references and will automatically clear when they are garbage
|
||||
* collected by the JVM. Matching is handled by reference equality, so the
|
||||
* exact reference given to {@link #register(TransportProtocol)} must be
|
||||
* used.
|
||||
*
|
||||
* @param proto
|
||||
* the exact object previously given to register.
|
||||
*/
|
||||
public static void unregister(TransportProtocol proto) {
|
||||
for (WeakReference<TransportProtocol> ref : protocols) {
|
||||
TransportProtocol refProto = ref.get();
|
||||
if (refProto == null || refProto == proto)
|
||||
protocols.remove(ref);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtain a copy of the registered protocols.
|
||||
*
|
||||
* @return an immutable copy of the currently registered protocols.
|
||||
*/
|
||||
public static List<TransportProtocol> getTransportProtocols() {
|
||||
int cnt = protocols.size();
|
||||
List<TransportProtocol> res = new ArrayList<TransportProtocol>(cnt);
|
||||
for (WeakReference<TransportProtocol> ref : protocols) {
|
||||
TransportProtocol proto = ref.get();
|
||||
if (proto != null)
|
||||
res.add(proto);
|
||||
else
|
||||
protocols.remove(ref);
|
||||
}
|
||||
return Collections.unmodifiableList(res);
|
||||
}
|
||||
|
||||
/**
|
||||
* Open a new transport instance to connect two repositories.
|
||||
* <p>
|
||||
|
@ -107,9 +181,12 @@ public enum Operation {
|
|||
* file and is not a well-formed URL.
|
||||
* @throws NotSupportedException
|
||||
* the protocol specified is not supported.
|
||||
* @throws TransportException
|
||||
* the transport cannot open this URI.
|
||||
*/
|
||||
public static Transport open(final Repository local, final String remote)
|
||||
throws NotSupportedException, URISyntaxException {
|
||||
throws NotSupportedException, URISyntaxException,
|
||||
TransportException {
|
||||
return open(local, remote, Operation.FETCH);
|
||||
}
|
||||
|
||||
|
@ -131,13 +208,15 @@ public static Transport open(final Repository local, final String remote)
|
|||
* file and is not a well-formed URL.
|
||||
* @throws NotSupportedException
|
||||
* the protocol specified is not supported.
|
||||
* @throws TransportException
|
||||
* the transport cannot open this URI.
|
||||
*/
|
||||
public static Transport open(final Repository local, final String remote,
|
||||
final Operation op) throws NotSupportedException,
|
||||
URISyntaxException {
|
||||
URISyntaxException, TransportException {
|
||||
final RemoteConfig cfg = new RemoteConfig(local.getConfig(), remote);
|
||||
if (doesNotExist(cfg))
|
||||
return open(local, new URIish(remote));
|
||||
return open(local, new URIish(remote), null);
|
||||
return open(local, cfg, op);
|
||||
}
|
||||
|
||||
|
@ -158,10 +237,12 @@ public static Transport open(final Repository local, final String remote,
|
|||
* file and is not a well-formed URL.
|
||||
* @throws NotSupportedException
|
||||
* the protocol specified is not supported.
|
||||
* @throws TransportException
|
||||
* the transport cannot open this URI.
|
||||
*/
|
||||
public static List<Transport> openAll(final Repository local,
|
||||
final String remote) throws NotSupportedException,
|
||||
URISyntaxException {
|
||||
URISyntaxException, TransportException {
|
||||
return openAll(local, remote, Operation.FETCH);
|
||||
}
|
||||
|
||||
|
@ -183,14 +264,17 @@ public static List<Transport> openAll(final Repository local,
|
|||
* file and is not a well-formed URL.
|
||||
* @throws NotSupportedException
|
||||
* the protocol specified is not supported.
|
||||
* @throws TransportException
|
||||
* the transport cannot open this URI.
|
||||
*/
|
||||
public static List<Transport> openAll(final Repository local,
|
||||
final String remote, final Operation op)
|
||||
throws NotSupportedException, URISyntaxException {
|
||||
throws NotSupportedException, URISyntaxException,
|
||||
TransportException {
|
||||
final RemoteConfig cfg = new RemoteConfig(local.getConfig(), remote);
|
||||
if (doesNotExist(cfg)) {
|
||||
final ArrayList<Transport> transports = new ArrayList<Transport>(1);
|
||||
transports.add(open(local, new URIish(remote)));
|
||||
transports.add(open(local, new URIish(remote), null));
|
||||
return transports;
|
||||
}
|
||||
return openAll(local, cfg, op);
|
||||
|
@ -210,12 +294,14 @@ public static List<Transport> openAll(final Repository local,
|
|||
* in remote configuration, only the first is chosen.
|
||||
* @throws NotSupportedException
|
||||
* the protocol specified is not supported.
|
||||
* @throws TransportException
|
||||
* the transport cannot open this URI.
|
||||
* @throws IllegalArgumentException
|
||||
* if provided remote configuration doesn't have any URI
|
||||
* associated.
|
||||
*/
|
||||
public static Transport open(final Repository local, final RemoteConfig cfg)
|
||||
throws NotSupportedException {
|
||||
throws NotSupportedException, TransportException {
|
||||
return open(local, cfg, Operation.FETCH);
|
||||
}
|
||||
|
||||
|
@ -234,18 +320,20 @@ public static Transport open(final Repository local, final RemoteConfig cfg)
|
|||
* in remote configuration, only the first is chosen.
|
||||
* @throws NotSupportedException
|
||||
* the protocol specified is not supported.
|
||||
* @throws TransportException
|
||||
* the transport cannot open this URI.
|
||||
* @throws IllegalArgumentException
|
||||
* if provided remote configuration doesn't have any URI
|
||||
* associated.
|
||||
*/
|
||||
public static Transport open(final Repository local,
|
||||
final RemoteConfig cfg, final Operation op)
|
||||
throws NotSupportedException {
|
||||
throws NotSupportedException, TransportException {
|
||||
final List<URIish> uris = getURIs(cfg, op);
|
||||
if (uris.isEmpty())
|
||||
throw new IllegalArgumentException(MessageFormat.format(
|
||||
JGitText.get().remoteConfigHasNoURIAssociated, cfg.getName()));
|
||||
final Transport tn = open(local, uris.get(0));
|
||||
final Transport tn = open(local, uris.get(0), cfg.getName());
|
||||
tn.applyConfig(cfg);
|
||||
return tn;
|
||||
}
|
||||
|
@ -264,9 +352,12 @@ public static Transport open(final Repository local,
|
|||
* configuration.
|
||||
* @throws NotSupportedException
|
||||
* the protocol specified is not supported.
|
||||
* @throws TransportException
|
||||
* the transport cannot open this URI.
|
||||
*/
|
||||
public static List<Transport> openAll(final Repository local,
|
||||
final RemoteConfig cfg) throws NotSupportedException {
|
||||
final RemoteConfig cfg) throws NotSupportedException,
|
||||
TransportException {
|
||||
return openAll(local, cfg, Operation.FETCH);
|
||||
}
|
||||
|
||||
|
@ -285,14 +376,16 @@ public static List<Transport> openAll(final Repository local,
|
|||
* configuration.
|
||||
* @throws NotSupportedException
|
||||
* the protocol specified is not supported.
|
||||
* @throws TransportException
|
||||
* the transport cannot open this URI.
|
||||
*/
|
||||
public static List<Transport> openAll(final Repository local,
|
||||
final RemoteConfig cfg, final Operation op)
|
||||
throws NotSupportedException {
|
||||
throws NotSupportedException, TransportException {
|
||||
final List<URIish> uris = getURIs(cfg, op);
|
||||
final List<Transport> transports = new ArrayList<Transport>(uris.size());
|
||||
for (final URIish uri : uris) {
|
||||
final Transport tn = open(local, uri);
|
||||
final Transport tn = open(local, uri, cfg.getName());
|
||||
tn.applyConfig(cfg);
|
||||
transports.add(tn);
|
||||
}
|
||||
|
@ -320,37 +413,21 @@ private static boolean doesNotExist(final RemoteConfig cfg) {
|
|||
}
|
||||
|
||||
/**
|
||||
* Determines whether the transport can handle the given URIish.
|
||||
* Open a new transport instance to connect two repositories.
|
||||
*
|
||||
* @param remote
|
||||
* @param local
|
||||
* existing local repository.
|
||||
* @param uri
|
||||
* location of the remote repository.
|
||||
* @param fs
|
||||
* type of filesystem the local repository is stored on.
|
||||
* @return true if the protocol is supported.
|
||||
* @return the new transport instance. Never null.
|
||||
* @throws NotSupportedException
|
||||
* the protocol specified is not supported.
|
||||
* @throws TransportException
|
||||
* the transport cannot open this URI.
|
||||
*/
|
||||
public static boolean canHandleProtocol(final URIish remote, final FS fs) {
|
||||
if (TransportGitSsh.canHandle(remote))
|
||||
return true;
|
||||
|
||||
else if (TransportHttp.canHandle(remote))
|
||||
return true;
|
||||
|
||||
else if (TransportSftp.canHandle(remote))
|
||||
return true;
|
||||
|
||||
else if (TransportGitAnon.canHandle(remote))
|
||||
return true;
|
||||
|
||||
else if (TransportAmazonS3.canHandle(remote))
|
||||
return true;
|
||||
|
||||
else if (TransportBundleFile.canHandle(remote, fs))
|
||||
return true;
|
||||
|
||||
else if (TransportLocal.canHandle(remote, fs))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
public static Transport open(final Repository local, final URIish uri)
|
||||
throws NotSupportedException, TransportException {
|
||||
return open(local, uri, null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -358,36 +435,31 @@ else if (TransportLocal.canHandle(remote, fs))
|
|||
*
|
||||
* @param local
|
||||
* existing local repository.
|
||||
* @param remote
|
||||
* @param uri
|
||||
* location of the remote repository.
|
||||
* @param remoteName
|
||||
* name of the remote, if the remote as configured in
|
||||
* {@code local}; otherwise null.
|
||||
* @return the new transport instance. Never null.
|
||||
* @throws NotSupportedException
|
||||
* the protocol specified is not supported.
|
||||
* @throws TransportException
|
||||
* the transport cannot open this URI.
|
||||
*/
|
||||
public static Transport open(final Repository local, final URIish remote)
|
||||
throws NotSupportedException {
|
||||
if (TransportGitSsh.canHandle(remote))
|
||||
return new TransportGitSsh(local, remote);
|
||||
public static Transport open(Repository local, URIish uri, String remoteName)
|
||||
throws NotSupportedException, TransportException {
|
||||
for (WeakReference<TransportProtocol> ref : protocols) {
|
||||
TransportProtocol proto = ref.get();
|
||||
if (proto == null) {
|
||||
protocols.remove(ref);
|
||||
continue;
|
||||
}
|
||||
|
||||
else if (TransportHttp.canHandle(remote))
|
||||
return new TransportHttp(local, remote);
|
||||
if (proto.canHandle(local, uri, remoteName))
|
||||
return proto.open(local, uri, remoteName);
|
||||
}
|
||||
|
||||
else if (TransportSftp.canHandle(remote))
|
||||
return new TransportSftp(local, remote);
|
||||
|
||||
else if (TransportGitAnon.canHandle(remote))
|
||||
return new TransportGitAnon(local, remote);
|
||||
|
||||
else if (TransportAmazonS3.canHandle(remote))
|
||||
return new TransportAmazonS3(local, remote);
|
||||
|
||||
else if (TransportBundleFile.canHandle(remote, local.getFS()))
|
||||
return new TransportBundleFile(local, remote);
|
||||
|
||||
else if (TransportLocal.canHandle(remote, local.getFS()))
|
||||
return new TransportLocal(local, remote);
|
||||
|
||||
throw new NotSupportedException(MessageFormat.format(JGitText.get().URINotSupported, remote));
|
||||
throw new NotSupportedException(MessageFormat.format(JGitText.get().URINotSupported, uri));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -53,9 +53,12 @@
|
|||
import java.text.MessageFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import org.eclipse.jgit.JGitText;
|
||||
|
@ -66,9 +69,9 @@
|
|||
import org.eclipse.jgit.lib.ObjectIdRef;
|
||||
import org.eclipse.jgit.lib.ProgressMonitor;
|
||||
import org.eclipse.jgit.lib.Ref;
|
||||
import org.eclipse.jgit.lib.Ref.Storage;
|
||||
import org.eclipse.jgit.lib.Repository;
|
||||
import org.eclipse.jgit.lib.SymbolicRef;
|
||||
import org.eclipse.jgit.lib.Ref.Storage;
|
||||
|
||||
/**
|
||||
* Transport over the non-Git aware Amazon S3 protocol.
|
||||
|
@ -97,11 +100,29 @@
|
|||
public class TransportAmazonS3 extends HttpTransport implements WalkTransport {
|
||||
static final String S3_SCHEME = "amazon-s3";
|
||||
|
||||
static boolean canHandle(final URIish uri) {
|
||||
if (!uri.isRemote())
|
||||
return false;
|
||||
return S3_SCHEME.equals(uri.getScheme());
|
||||
}
|
||||
static final TransportProtocol PROTO_S3 = new TransportProtocol() {
|
||||
public String getName() {
|
||||
return "Amazon S3";
|
||||
}
|
||||
|
||||
public Set<String> getSchemes() {
|
||||
return Collections.singleton(S3_SCHEME);
|
||||
}
|
||||
|
||||
public Set<URIishField> getRequiredFields() {
|
||||
return Collections.unmodifiableSet(EnumSet.of(URIishField.USER,
|
||||
URIishField.HOST, URIishField.PATH));
|
||||
}
|
||||
|
||||
public Set<URIishField> getOptionalFields() {
|
||||
return Collections.unmodifiableSet(EnumSet.of(URIishField.PASS));
|
||||
}
|
||||
|
||||
public Transport open(Repository local, URIish uri, String remoteName)
|
||||
throws NotSupportedException {
|
||||
return new TransportAmazonS3(local, uri);
|
||||
}
|
||||
};
|
||||
|
||||
/** User information necessary to connect to S3. */
|
||||
private final AmazonS3 s3;
|
||||
|
|
|
@ -50,32 +50,67 @@
|
|||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.jgit.JGitText;
|
||||
import org.eclipse.jgit.errors.NotSupportedException;
|
||||
import org.eclipse.jgit.errors.TransportException;
|
||||
import org.eclipse.jgit.lib.Repository;
|
||||
import org.eclipse.jgit.util.FS;
|
||||
|
||||
class TransportBundleFile extends Transport implements TransportBundle {
|
||||
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;
|
||||
static final TransportProtocol PROTO_BUNDLE = new TransportProtocol() {
|
||||
private final String[] schemeNames = { "bundle", "file" }; //$NON-NLS-1$ //$NON-NLS-2$
|
||||
|
||||
if ("file".equals(uri.getScheme()) || uri.getScheme() == null) {
|
||||
final File f = fs.resolve(new File("."), uri.getPath());
|
||||
return f.isFile() || f.getName().endsWith(".bundle");
|
||||
private final Set<String> schemeSet = Collections
|
||||
.unmodifiableSet(new LinkedHashSet<String>(Arrays
|
||||
.asList(schemeNames)));
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return JGitText.get().transportProtoBundleFile;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
public Set<String> getSchemes() {
|
||||
return schemeSet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canHandle(Repository local, URIish uri, String remoteName) {
|
||||
if (uri.getPath() == null
|
||||
|| uri.getPort() > 0
|
||||
|| uri.getUser() != null
|
||||
|| uri.getPass() != null
|
||||
|| uri.getHost() != null
|
||||
|| (uri.getScheme() != null && !getSchemes().contains(uri.getScheme())))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Transport open(Repository local, URIish uri, String remoteName)
|
||||
throws NotSupportedException, TransportException {
|
||||
if ("bundle".equals(uri.getScheme())) {
|
||||
File path = local.getFS().resolve(new File("."), uri.getPath());
|
||||
return new TransportBundleFile(local, uri, path);
|
||||
}
|
||||
|
||||
// This is an ambiguous reference, it could be a bundle file
|
||||
// or it could be a Git repository. Allow TransportLocal to
|
||||
// resolve the path and figure out which type it is by testing
|
||||
// the target.
|
||||
//
|
||||
return TransportLocal.PROTO_LOCAL.open(local, uri, remoteName);
|
||||
}
|
||||
};
|
||||
|
||||
private final File bundle;
|
||||
|
||||
TransportBundleFile(final Repository local, final URIish uri) {
|
||||
TransportBundleFile(Repository local, URIish uri, File bundlePath) {
|
||||
super(local, uri);
|
||||
bundle = local.getFS().resolve(new File("."), uri.getPath()).getAbsoluteFile();
|
||||
bundle = bundlePath;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -55,8 +55,12 @@
|
|||
import java.net.InetSocketAddress;
|
||||
import java.net.Socket;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.jgit.JGitText;
|
||||
import org.eclipse.jgit.errors.NotSupportedException;
|
||||
import org.eclipse.jgit.errors.TransportException;
|
||||
import org.eclipse.jgit.lib.Repository;
|
||||
|
||||
|
@ -70,9 +74,33 @@
|
|||
class TransportGitAnon extends TcpTransport implements PackTransport {
|
||||
static final int GIT_PORT = Daemon.DEFAULT_PORT;
|
||||
|
||||
static boolean canHandle(final URIish uri) {
|
||||
return "git".equals(uri.getScheme());
|
||||
}
|
||||
static final TransportProtocol PROTO_GIT = new TransportProtocol() {
|
||||
public String getName() {
|
||||
return JGitText.get().transportProtoGitAnon;
|
||||
}
|
||||
|
||||
public Set<String> getSchemes() {
|
||||
return Collections.singleton("git"); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
public Set<URIishField> getRequiredFields() {
|
||||
return Collections.unmodifiableSet(EnumSet.of(URIishField.HOST,
|
||||
URIishField.PATH));
|
||||
}
|
||||
|
||||
public Set<URIishField> getOptionalFields() {
|
||||
return Collections.unmodifiableSet(EnumSet.of(URIishField.PORT));
|
||||
}
|
||||
|
||||
public int getDefaultPort() {
|
||||
return GIT_PORT;
|
||||
}
|
||||
|
||||
public Transport open(Repository local, URIish uri, String remoteName)
|
||||
throws NotSupportedException {
|
||||
return new TransportGitAnon(local, uri);
|
||||
}
|
||||
};
|
||||
|
||||
TransportGitAnon(final Repository local, final URIish uri) {
|
||||
super(local, uri);
|
||||
|
|
|
@ -53,10 +53,16 @@
|
|||
import java.io.PipedOutputStream;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumSet;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.jgit.JGitText;
|
||||
import org.eclipse.jgit.errors.NoRemoteRepositoryException;
|
||||
import org.eclipse.jgit.errors.NotSupportedException;
|
||||
import org.eclipse.jgit.errors.TransportException;
|
||||
import org.eclipse.jgit.lib.Constants;
|
||||
import org.eclipse.jgit.lib.Repository;
|
||||
|
@ -80,20 +86,52 @@
|
|||
* enumeration, save file modification and hook execution.
|
||||
*/
|
||||
public class TransportGitSsh extends SshTransport implements PackTransport {
|
||||
static boolean canHandle(final URIish uri) {
|
||||
if (!uri.isRemote())
|
||||
return false;
|
||||
final String scheme = uri.getScheme();
|
||||
if ("ssh".equals(scheme))
|
||||
return true;
|
||||
if ("ssh+git".equals(scheme))
|
||||
return true;
|
||||
if ("git+ssh".equals(scheme))
|
||||
return true;
|
||||
if (scheme == null && uri.getHost() != null && uri.getPath() != null)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
static final TransportProtocol PROTO_SSH = new TransportProtocol() {
|
||||
private final String[] schemeNames = { "ssh", "ssh+git", "git+ssh" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
||||
|
||||
private final Set<String> schemeSet = Collections
|
||||
.unmodifiableSet(new LinkedHashSet<String>(Arrays
|
||||
.asList(schemeNames)));
|
||||
|
||||
public String getName() {
|
||||
return JGitText.get().transportProtoSSH;
|
||||
}
|
||||
|
||||
public Set<String> getSchemes() {
|
||||
return schemeSet;
|
||||
}
|
||||
|
||||
public Set<URIishField> getRequiredFields() {
|
||||
return Collections.unmodifiableSet(EnumSet.of(URIishField.HOST,
|
||||
URIishField.PATH));
|
||||
}
|
||||
|
||||
public Set<URIishField> getOptionalFields() {
|
||||
return Collections.unmodifiableSet(EnumSet.of(URIishField.USER,
|
||||
URIishField.PASS, URIishField.PORT));
|
||||
}
|
||||
|
||||
public int getDefaultPort() {
|
||||
return 22;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canHandle(Repository local, URIish uri, String remoteName) {
|
||||
if (uri.getScheme() == null) {
|
||||
// scp-style URI "host:path" does not have scheme.
|
||||
return uri.getHost() != null
|
||||
&& uri.getPath() != null
|
||||
&& uri.getHost().length() != 0
|
||||
&& uri.getPath().length() != 0;
|
||||
}
|
||||
return super.canHandle(local, uri, remoteName);
|
||||
}
|
||||
|
||||
public Transport open(Repository local, URIish uri, String remoteName)
|
||||
throws NotSupportedException {
|
||||
return new TransportGitSsh(local, uri);
|
||||
}
|
||||
};
|
||||
|
||||
TransportGitSsh(final Repository local, final URIish uri) {
|
||||
super(local, uri);
|
||||
|
|
|
@ -72,7 +72,11 @@
|
|||
import java.security.cert.X509Certificate;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumSet;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
|
@ -130,12 +134,69 @@ public class TransportHttp extends HttpTransport implements WalkTransport,
|
|||
|
||||
private static final String userAgent = computeUserAgent();
|
||||
|
||||
static boolean canHandle(final URIish uri) {
|
||||
if (!uri.isRemote())
|
||||
return false;
|
||||
final String s = uri.getScheme();
|
||||
return "http".equals(s) || "https".equals(s) || "ftp".equals(s); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
||||
}
|
||||
static final TransportProtocol PROTO_HTTP = new TransportProtocol() {
|
||||
private final String[] schemeNames = { "http", "https" }; //$NON-NLS-1$ //$NON-NLS-2$
|
||||
|
||||
private final Set<String> schemeSet = Collections
|
||||
.unmodifiableSet(new LinkedHashSet<String>(Arrays
|
||||
.asList(schemeNames)));
|
||||
|
||||
public String getName() {
|
||||
return JGitText.get().transportProtoHTTP;
|
||||
}
|
||||
|
||||
public Set<String> getSchemes() {
|
||||
return schemeSet;
|
||||
}
|
||||
|
||||
public Set<URIishField> getRequiredFields() {
|
||||
return Collections.unmodifiableSet(EnumSet.of(URIishField.HOST,
|
||||
URIishField.PATH));
|
||||
}
|
||||
|
||||
public Set<URIishField> getOptionalFields() {
|
||||
return Collections.unmodifiableSet(EnumSet.of(URIishField.USER,
|
||||
URIishField.PASS, URIishField.PORT));
|
||||
}
|
||||
|
||||
public int getDefaultPort() {
|
||||
return 80;
|
||||
}
|
||||
|
||||
public Transport open(Repository local, URIish uri, String remoteName)
|
||||
throws NotSupportedException {
|
||||
return new TransportHttp(local, uri);
|
||||
}
|
||||
};
|
||||
|
||||
static final TransportProtocol PROTO_FTP = new TransportProtocol() {
|
||||
public String getName() {
|
||||
return JGitText.get().transportProtoFTP;
|
||||
}
|
||||
|
||||
public Set<String> getSchemes() {
|
||||
return Collections.singleton("ftp"); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
public Set<URIishField> getRequiredFields() {
|
||||
return Collections.unmodifiableSet(EnumSet.of(URIishField.HOST,
|
||||
URIishField.PATH));
|
||||
}
|
||||
|
||||
public Set<URIishField> getOptionalFields() {
|
||||
return Collections.unmodifiableSet(EnumSet.of(URIishField.USER,
|
||||
URIishField.PASS, URIishField.PORT));
|
||||
}
|
||||
|
||||
public int getDefaultPort() {
|
||||
return 21;
|
||||
}
|
||||
|
||||
public Transport open(Repository local, URIish uri, String remoteName)
|
||||
throws NotSupportedException {
|
||||
return new TransportHttp(local, uri);
|
||||
}
|
||||
};
|
||||
|
||||
private static String computeUserAgent() {
|
||||
String version;
|
||||
|
|
|
@ -55,15 +55,17 @@
|
|||
import java.io.OutputStream;
|
||||
import java.io.PipedInputStream;
|
||||
import java.io.PipedOutputStream;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.jgit.JGitText;
|
||||
import org.eclipse.jgit.errors.NoRemoteRepositoryException;
|
||||
import org.eclipse.jgit.errors.NotSupportedException;
|
||||
import org.eclipse.jgit.errors.TransportException;
|
||||
import org.eclipse.jgit.lib.Constants;
|
||||
import org.eclipse.jgit.lib.Repository;
|
||||
import org.eclipse.jgit.lib.RepositoryCache;
|
||||
import org.eclipse.jgit.storage.file.FileRepository;
|
||||
import org.eclipse.jgit.util.FS;
|
||||
import org.eclipse.jgit.util.io.MessageWriter;
|
||||
import org.eclipse.jgit.util.io.StreamCopyThread;
|
||||
|
||||
|
@ -91,27 +93,50 @@
|
|||
* system pipe to transfer data.
|
||||
*/
|
||||
class TransportLocal extends Transport implements PackTransport {
|
||||
private static final String PWD = ".";
|
||||
static final TransportProtocol PROTO_LOCAL = new TransportProtocol() {
|
||||
@Override
|
||||
public String getName() {
|
||||
return JGitText.get().transportProtoLocal;
|
||||
}
|
||||
|
||||
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;
|
||||
public Set<String> getSchemes() {
|
||||
return Collections.singleton("file"); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
if ("file".equals(uri.getScheme()) || uri.getScheme() == null)
|
||||
return fs.resolve(new File(PWD), uri.getPath()).isDirectory();
|
||||
return false;
|
||||
}
|
||||
@Override
|
||||
public boolean canHandle(Repository local, URIish uri, String remoteName) {
|
||||
if (uri.getPath() == null
|
||||
|| uri.getPort() > 0
|
||||
|| uri.getUser() != null
|
||||
|| uri.getPass() != null
|
||||
|| uri.getHost() != null
|
||||
|| (uri.getScheme() != null && !getSchemes().contains(uri.getScheme())))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Transport open(Repository local, URIish uri, String remoteName)
|
||||
throws NoRemoteRepositoryException {
|
||||
// If the reference is to a local file, C Git behavior says
|
||||
// assume this is a bundle, since repositories are directories.
|
||||
//
|
||||
File path = local.getFS().resolve(new File("."), uri.getPath());
|
||||
if (path.isFile())
|
||||
return new TransportBundleFile(local, uri, path);
|
||||
|
||||
File gitDir = RepositoryCache.FileKey.resolve(path, local.getFS());
|
||||
if (gitDir == null)
|
||||
throw new NoRemoteRepositoryException(uri, JGitText.get().notFound);
|
||||
return new TransportLocal(local, uri, gitDir);
|
||||
}
|
||||
};
|
||||
|
||||
private final File remoteGitDir;
|
||||
|
||||
TransportLocal(final Repository local, final URIish uri) {
|
||||
TransportLocal(Repository local, URIish uri, File gitDir) {
|
||||
super(local, uri);
|
||||
|
||||
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;
|
||||
remoteGitDir = gitDir;
|
||||
}
|
||||
|
||||
UploadPack createUploadPack(final Repository dst) {
|
||||
|
|
|
@ -0,0 +1,221 @@
|
|||
/*
|
||||
* Copyright (C) 2011, Google Inc.
|
||||
* and other copyright owners as documented in the project's IP log.
|
||||
*
|
||||
* This program and the accompanying materials are made available
|
||||
* under the terms of the Eclipse Distribution License v1.0 which
|
||||
* accompanies this distribution, is reproduced below, and is
|
||||
* available at http://www.eclipse.org/org/documents/edl-v10.php
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or
|
||||
* without modification, are permitted provided that the following
|
||||
* conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
* - Neither the name of the Eclipse Foundation, Inc. nor the
|
||||
* names of its contributors may be used to endorse or promote
|
||||
* products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package org.eclipse.jgit.transport;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.EnumSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.jgit.errors.NotSupportedException;
|
||||
import org.eclipse.jgit.errors.TransportException;
|
||||
import org.eclipse.jgit.lib.Repository;
|
||||
|
||||
/**
|
||||
* Describes a way to connect to another Git repository.
|
||||
* <p>
|
||||
* Implementations of this class are typically immutable singletons held by
|
||||
* static class members, for example:
|
||||
*
|
||||
* <pre>
|
||||
* class MyTransport extends Transport {
|
||||
* static final TransportProtocol PROTO = new TransportProtocol() {
|
||||
* public String getName() {
|
||||
* return "My Protocol";
|
||||
* }
|
||||
* };
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* Applications may register additional protocols for use by JGit by calling
|
||||
* {@link Transport#register(TransportProtocol)}. Because that API holds onto
|
||||
* the protocol object by a WeakReference, applications must ensure their own
|
||||
* ClassLoader retains the TransportProtocol for the life of the application.
|
||||
* Using a static singleton pattern as above will ensure the protocol is valid
|
||||
* so long as the ClassLoader that defines it remains valid.
|
||||
*/
|
||||
public abstract class TransportProtocol {
|
||||
/** Fields within a {@link URIish} that a transport uses. */
|
||||
public static enum URIishField {
|
||||
/** the user field */
|
||||
USER,
|
||||
/** the pass (aka password) field */
|
||||
PASS,
|
||||
/** the host field */
|
||||
HOST,
|
||||
/** the port field */
|
||||
PORT,
|
||||
/** the path field */
|
||||
PATH,
|
||||
}
|
||||
|
||||
/** @return text name of the protocol suitable for display to a user. */
|
||||
public abstract String getName();
|
||||
|
||||
/** @return immutable set of schemes supported by this protocol. */
|
||||
public Set<String> getSchemes() {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
/** @return immutable set of URIishFields that must be filled in. */
|
||||
public Set<URIishField> getRequiredFields() {
|
||||
return Collections.unmodifiableSet(EnumSet.of(URIishField.PATH));
|
||||
}
|
||||
|
||||
/** @return immutable set of URIishFields that may be filled in. */
|
||||
public Set<URIishField> getOptionalFields() {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
/** @return if a port is supported, the default port, else -1. */
|
||||
public int getDefaultPort() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if this protocol can handle a particular URI.
|
||||
* <p>
|
||||
* Implementations should try to avoid looking at the local filesystem, but
|
||||
* may look at implementation specific configuration options in the remote
|
||||
* block of {@code local.getConfig()} using {@code remoteName} if the name
|
||||
* is non-null.
|
||||
* <p>
|
||||
* The default implementation of this method matches the scheme against
|
||||
* {@link #getSchemes()}, required fields against
|
||||
* {@link #getRequiredFields()}, and optional fields against
|
||||
* {@link #getOptionalFields()}, returning true only if all of the fields
|
||||
* match the specification.
|
||||
*
|
||||
* @param local
|
||||
* the local repository that will communicate with the other Git
|
||||
* repository.
|
||||
* @param uri
|
||||
* address of the Git repository; never null.
|
||||
* @param remoteName
|
||||
* name of the remote, if the remote as configured in
|
||||
* {@code local}; otherwise null.
|
||||
* @return true if this protocol can handle this URI; false otherwise.
|
||||
*/
|
||||
public boolean canHandle(Repository local, URIish uri, String remoteName) {
|
||||
if (!getSchemes().isEmpty() && !getSchemes().contains(uri.getScheme()))
|
||||
return false;
|
||||
|
||||
for (URIishField field : getRequiredFields()) {
|
||||
switch (field) {
|
||||
case USER:
|
||||
if (uri.getUser() == null || uri.getUser().length() == 0)
|
||||
return false;
|
||||
break;
|
||||
|
||||
case PASS:
|
||||
if (uri.getPass() == null || uri.getPass().length() == 0)
|
||||
return false;
|
||||
break;
|
||||
|
||||
case HOST:
|
||||
if (uri.getHost() == null || uri.getHost().length() == 0)
|
||||
return false;
|
||||
break;
|
||||
|
||||
case PORT:
|
||||
if (uri.getPort() <= 0)
|
||||
return false;
|
||||
break;
|
||||
|
||||
case PATH:
|
||||
if (uri.getPath() == null || uri.getPath().length() == 0)
|
||||
return false;
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Set<URIishField> canHave = EnumSet.copyOf(getRequiredFields());
|
||||
canHave.addAll(getOptionalFields());
|
||||
|
||||
if (uri.getUser() != null && !canHave.contains(URIishField.USER))
|
||||
return false;
|
||||
if (uri.getPass() != null && !canHave.contains(URIishField.PASS))
|
||||
return false;
|
||||
if (uri.getHost() != null && !canHave.contains(URIishField.HOST))
|
||||
return false;
|
||||
if (uri.getPort() > 0 && !canHave.contains(URIishField.PORT))
|
||||
return false;
|
||||
if (uri.getPath() != null && !canHave.contains(URIishField.PATH))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Open a Transport instance to the other repository.
|
||||
* <p>
|
||||
* Implementations should avoid making remote connections until an operation
|
||||
* on the returned Transport is invoked, however they may fail fast here if
|
||||
* they know a connection is impossible, such as when using the local
|
||||
* filesystem and the target path does not exist.
|
||||
* <p>
|
||||
* Implementations may access implementation-specific configuration options
|
||||
* within {@code local.getConfig()} using the remote block named by the
|
||||
* {@code remoteName}, if the name is non-null.
|
||||
*
|
||||
* @param local
|
||||
* the local repository that will communicate with the other Git
|
||||
* repository.
|
||||
* @param uri
|
||||
* address of the Git repository.
|
||||
* @param remoteName
|
||||
* name of the remote, if the remote as configured in
|
||||
* {@code local}; otherwise null.
|
||||
* @return the transport.
|
||||
* @throws NotSupportedException
|
||||
* this protocol does not support the URI.
|
||||
* @throws TransportException
|
||||
* the transport cannot open this URI.
|
||||
*/
|
||||
public abstract Transport open(Repository local, URIish uri,
|
||||
String remoteName)
|
||||
throws NotSupportedException, TransportException;
|
||||
}
|
|
@ -51,20 +51,24 @@
|
|||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import org.eclipse.jgit.JGitText;
|
||||
import org.eclipse.jgit.errors.NotSupportedException;
|
||||
import org.eclipse.jgit.errors.TransportException;
|
||||
import org.eclipse.jgit.lib.Constants;
|
||||
import org.eclipse.jgit.lib.ObjectId;
|
||||
import org.eclipse.jgit.lib.ObjectIdRef;
|
||||
import org.eclipse.jgit.lib.ProgressMonitor;
|
||||
import org.eclipse.jgit.lib.Ref;
|
||||
import org.eclipse.jgit.lib.Ref.Storage;
|
||||
import org.eclipse.jgit.lib.Repository;
|
||||
import org.eclipse.jgit.lib.SymbolicRef;
|
||||
import org.eclipse.jgit.lib.Ref.Storage;
|
||||
|
||||
import com.jcraft.jsch.Channel;
|
||||
import com.jcraft.jsch.ChannelSftp;
|
||||
|
@ -93,9 +97,34 @@
|
|||
* @see WalkFetchConnection
|
||||
*/
|
||||
public class TransportSftp extends SshTransport implements WalkTransport {
|
||||
static boolean canHandle(final URIish uri) {
|
||||
return uri.isRemote() && "sftp".equals(uri.getScheme());
|
||||
}
|
||||
static final TransportProtocol PROTO_SFTP = new TransportProtocol() {
|
||||
public String getName() {
|
||||
return JGitText.get().transportProtoSFTP;
|
||||
}
|
||||
|
||||
public Set<String> getSchemes() {
|
||||
return Collections.singleton("sftp"); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
public Set<URIishField> getRequiredFields() {
|
||||
return Collections.unmodifiableSet(EnumSet.of(URIishField.HOST,
|
||||
URIishField.PATH));
|
||||
}
|
||||
|
||||
public Set<URIishField> getOptionalFields() {
|
||||
return Collections.unmodifiableSet(EnumSet.of(URIishField.USER,
|
||||
URIishField.PASS, URIishField.PORT));
|
||||
}
|
||||
|
||||
public int getDefaultPort() {
|
||||
return 22;
|
||||
}
|
||||
|
||||
public Transport open(Repository local, URIish uri, String remoteName)
|
||||
throws NotSupportedException {
|
||||
return new TransportSftp(local, uri);
|
||||
}
|
||||
};
|
||||
|
||||
TransportSftp(final Repository local, final URIish uri) {
|
||||
super(local, uri);
|
||||
|
|
Loading…
Reference in New Issue