summaryrefslogtreecommitdiffstats
path: root/org.eclipse.jgit/src
diff options
context:
space:
mode:
authorKevin Sawicki <kevin@github.com>2011-11-08 12:49:16 -0800
committerChris Aniszczyk <zx@twitter.com>2011-11-10 10:57:47 -0800
commitda901c49688ef72858cd2b6904e0f8e478fa0ec3 (patch)
tree563d2d1bcd2ae7996200e07edd8bd98d3085e03a /org.eclipse.jgit/src
parentc0392381ee915c8ddd08a5fe8b94548fd86b8fcd (diff)
downloadjgit-da901c49688ef72858cd2b6904e0f8e478fa0ec3.tar.gz
jgit-da901c49688ef72858cd2b6904e0f8e478fa0ec3.zip
Support a configured credentials provider in LsRemoteCommand
Refactored the three common transport configuration options: credentials provider, timeout, and transport config callback into a new TransportCommand base class which is now extended by all commands that use a Transport object during execution. Bug: 349188 Change-Id: I90c2c14fb4e3cc4712905158f9047153a0c235c2 Signed-off-by: Kevin Sawicki <kevin@github.com> Signed-off-by: Chris Aniszczyk <zx@twitter.com>
Diffstat (limited to 'org.eclipse.jgit/src')
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/api/CloneCommand.java92
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/api/FetchCommand.java53
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/api/LsRemoteCommand.java4
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/api/PullCommand.java49
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/api/PushCommand.java55
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/api/TransportCommand.java155
6 files changed, 192 insertions, 216 deletions
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/CloneCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/CloneCommand.java
index 281704fadf..5c98e6a28d 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/CloneCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/CloneCommand.java
@@ -49,7 +49,6 @@ import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
-import java.util.concurrent.Callable;
import org.eclipse.jgit.JGitText;
import org.eclipse.jgit.api.errors.InvalidRemoteException;
@@ -67,7 +66,6 @@ import org.eclipse.jgit.lib.RefUpdate;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevWalk;
-import org.eclipse.jgit.transport.CredentialsProvider;
import org.eclipse.jgit.transport.FetchResult;
import org.eclipse.jgit.transport.RefSpec;
import org.eclipse.jgit.transport.RemoteConfig;
@@ -80,7 +78,7 @@ import org.eclipse.jgit.transport.URIish;
* @see <a href="http://www.kernel.org/pub/software/scm/git/docs/git-clone.html"
* >Git documentation about Clone</a>
*/
-public class CloneCommand implements Callable<Git> {
+public class CloneCommand extends TransportCommand<CloneCommand, Git> {
private String uri;
@@ -94,17 +92,18 @@ public class CloneCommand implements Callable<Git> {
private ProgressMonitor monitor = NullProgressMonitor.INSTANCE;
- private CredentialsProvider credentialsProvider;
-
- private int timeout;
-
private boolean cloneAllBranches;
private boolean noCheckout;
private Collection<String> branchesToClone;
- private TransportConfigCallback transportConfigCallback;
+ /**
+ * Create clone command with no repository set
+ */
+ public CloneCommand() {
+ super(null);
+ }
/**
* Executes the {@code Clone} command.
@@ -142,12 +141,12 @@ public class CloneCommand implements Callable<Git> {
return command.call().getRepository();
}
- private FetchResult fetch(Repository repo, URIish u)
+ private FetchResult fetch(Repository clonedRepo, URIish u)
throws URISyntaxException,
JGitInternalException,
InvalidRemoteException, IOException {
// create the remote config and save it
- RemoteConfig config = new RemoteConfig(repo.getConfig(), remote);
+ RemoteConfig config = new RemoteConfig(clonedRepo.getConfig(), remote);
config.addURI(u);
final String dst = bare ? Constants.R_HEADS : Constants.R_REMOTES
@@ -157,19 +156,16 @@ public class CloneCommand implements Callable<Git> {
refSpec = refSpec.setSourceDestination(Constants.R_HEADS + "*", dst + "/*"); //$NON-NLS-1$ //$NON-NLS-2$
config.addFetchRefSpec(refSpec);
- config.update(repo.getConfig());
+ config.update(clonedRepo.getConfig());
- repo.getConfig().save();
+ clonedRepo.getConfig().save();
// run the fetch command
- FetchCommand command = new FetchCommand(repo);
+ FetchCommand command = new FetchCommand(clonedRepo);
command.setRemote(remote);
command.setProgressMonitor(monitor);
command.setTagOpt(TagOpt.FETCH_TAGS);
- command.setTimeout(timeout);
- if (credentialsProvider != null)
- command.setCredentialsProvider(credentialsProvider);
- command.setTransportConfigCallback(transportConfigCallback);
+ configure(command);
List<RefSpec> specs = calculateRefSpecs(dst);
command.setRefSpecs(specs);
@@ -193,7 +189,7 @@ public class CloneCommand implements Callable<Git> {
return specs;
}
- private void checkout(Repository repo, FetchResult result)
+ private void checkout(Repository clonedRepo, FetchResult result)
throws JGitInternalException,
MissingObjectException, IncorrectObjectTypeException, IOException {
@@ -208,22 +204,22 @@ public class CloneCommand implements Callable<Git> {
return; // throw exception?
if (head.getName().startsWith(Constants.R_HEADS)) {
- final RefUpdate newHead = repo.updateRef(Constants.HEAD);
+ final RefUpdate newHead = clonedRepo.updateRef(Constants.HEAD);
newHead.disableRefLog();
newHead.link(head.getName());
- addMergeConfig(repo, head);
+ addMergeConfig(clonedRepo, head);
}
- final RevCommit commit = parseCommit(repo, head);
+ final RevCommit commit = parseCommit(clonedRepo, head);
boolean detached = !head.getName().startsWith(Constants.R_HEADS);
- RefUpdate u = repo.updateRef(Constants.HEAD, detached);
+ RefUpdate u = clonedRepo.updateRef(Constants.HEAD, detached);
u.setNewObjectId(commit.getId());
u.forceUpdate();
if (!bare) {
- DirCache dc = repo.lockDirCache();
- DirCacheCheckout co = new DirCacheCheckout(repo, dc,
+ DirCache dc = clonedRepo.lockDirCache();
+ DirCacheCheckout co = new DirCacheCheckout(clonedRepo, dc,
commit.getTree());
co.checkout();
}
@@ -246,19 +242,20 @@ public class CloneCommand implements Callable<Git> {
return foundBranch;
}
- private void addMergeConfig(Repository repo, Ref head) throws IOException {
+ private void addMergeConfig(Repository clonedRepo, Ref head)
+ throws IOException {
String branchName = Repository.shortenRefName(head.getName());
- repo.getConfig().setString(ConfigConstants.CONFIG_BRANCH_SECTION,
+ clonedRepo.getConfig().setString(ConfigConstants.CONFIG_BRANCH_SECTION,
branchName, ConfigConstants.CONFIG_KEY_REMOTE, remote);
- repo.getConfig().setString(ConfigConstants.CONFIG_BRANCH_SECTION,
+ clonedRepo.getConfig().setString(ConfigConstants.CONFIG_BRANCH_SECTION,
branchName, ConfigConstants.CONFIG_KEY_MERGE, head.getName());
- repo.getConfig().save();
+ clonedRepo.getConfig().save();
}
- private RevCommit parseCommit(final Repository repo, final Ref ref)
+ private RevCommit parseCommit(final Repository clonedRepo, final Ref ref)
throws MissingObjectException, IncorrectObjectTypeException,
IOException {
- final RevWalk rw = new RevWalk(repo);
+ final RevWalk rw = new RevWalk(clonedRepo);
final RevCommit commit;
try {
commit = rw.parseCommit(ref.getObjectId());
@@ -343,27 +340,6 @@ public class CloneCommand implements Callable<Git> {
}
/**
- * @param credentialsProvider
- * the {@link CredentialsProvider} to use
- * @return {@code this}
- */
- public CloneCommand setCredentialsProvider(
- CredentialsProvider credentialsProvider) {
- this.credentialsProvider = credentialsProvider;
- return this;
- }
-
- /**
- * @param timeout
- * the timeout used for the fetch step
- * @return {@code this}
- */
- public CloneCommand setTimeout(int timeout) {
- this.timeout = timeout;
- return this;
- }
-
- /**
* @param cloneAllBranches
* true when all branches have to be fetched (indicates wildcard
* in created fetch refspec), false otherwise.
@@ -396,18 +372,4 @@ public class CloneCommand implements Callable<Git> {
this.noCheckout = noCheckout;
return this;
}
-
- /**
- * @param transportConfigCallback
- * if set, the callback will be invoked after the Transport has
- * created, but before the Transport is used. The callback can
- * use this opportunity to set additional type-specific
- * configuration on the Transport instance.
- * @return {@code this}
- */
- public CloneCommand setTransportConfigCallback(
- TransportConfigCallback transportConfigCallback) {
- this.transportConfigCallback = transportConfigCallback;
- return this;
- }
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/FetchCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/FetchCommand.java
index 8fe9d59a2f..3ed78ee232 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/FetchCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/FetchCommand.java
@@ -57,7 +57,6 @@ import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.NullProgressMonitor;
import org.eclipse.jgit.lib.ProgressMonitor;
import org.eclipse.jgit.lib.Repository;
-import org.eclipse.jgit.transport.CredentialsProvider;
import org.eclipse.jgit.transport.FetchResult;
import org.eclipse.jgit.transport.RefSpec;
import org.eclipse.jgit.transport.TagOpt;
@@ -71,7 +70,7 @@ import org.eclipse.jgit.transport.Transport;
* @see <a href="http://www.kernel.org/pub/software/scm/git/docs/git-fetch.html"
* >Git documentation about Fetch</a>
*/
-public class FetchCommand extends GitCommand<FetchResult> {
+public class FetchCommand extends TransportCommand<FetchCommand, FetchResult> {
private String remote = Constants.DEFAULT_REMOTE_NAME;
@@ -87,14 +86,8 @@ public class FetchCommand extends GitCommand<FetchResult> {
private boolean thin = Transport.DEFAULT_FETCH_THIN;
- private int timeout;
-
- private CredentialsProvider credentialsProvider;
-
private TagOpt tagOption;
- private TransportConfigCallback transportConfigCallback;
-
/**
* @param repo
*/
@@ -127,15 +120,11 @@ public class FetchCommand extends GitCommand<FetchResult> {
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);
- if (transportConfigCallback != null)
- transportConfigCallback.configure(transport);
+ configure(transport);
FetchResult result = transport.fetch(monitor, refSpecs);
return result;
@@ -183,17 +172,6 @@ public class FetchCommand extends GitCommand<FetchResult> {
}
/**
- * @param timeout
- * the timeout used for the fetch operation
- * @return {@code this}
- */
- public FetchCommand setTimeout(int timeout) {
- checkCallable();
- this.timeout = timeout;
- return this;
- }
-
- /**
* @return the timeout used for the fetch operation
*/
public int getTimeout() {
@@ -335,18 +313,6 @@ public class FetchCommand extends GitCommand<FetchResult> {
}
/**
- * @param credentialsProvider
- * the {@link CredentialsProvider} to use
- * @return {@code this}
- */
- public FetchCommand setCredentialsProvider(
- CredentialsProvider credentialsProvider) {
- checkCallable();
- this.credentialsProvider = credentialsProvider;
- return this;
- }
-
- /**
* Sets the specification of annotated tag behavior during fetch
*
* @param tagOpt
@@ -357,19 +323,4 @@ public class FetchCommand extends GitCommand<FetchResult> {
this.tagOption = tagOpt;
return this;
}
-
- /**
- * @param transportConfigCallback
- * if set, the callback will be invoked after the Transport has
- * created, but before the Transport is used. The callback can
- * use this opportunity to set additional type-specific
- * configuration on the Transport instance.
- * @return {@code this}
- */
- public FetchCommand setTransportConfigCallback(
- TransportConfigCallback transportConfigCallback) {
- checkCallable();
- this.transportConfigCallback = transportConfigCallback;
- return this;
- }
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/LsRemoteCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/LsRemoteCommand.java
index 093d6cc1b2..f158596143 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/LsRemoteCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/LsRemoteCommand.java
@@ -68,7 +68,8 @@ import org.eclipse.jgit.transport.Transport;
* href="http://www.kernel.org/pub/software/scm/git/docs/git-ls-remote.html"
* >Git documentation about ls-remote</a>
*/
-public class LsRemoteCommand extends GitCommand<Collection<Ref>> {
+public class LsRemoteCommand extends
+ TransportCommand<LsRemoteCommand, Collection<Ref>> {
private String remote = Constants.DEFAULT_REMOTE_NAME;
@@ -133,6 +134,7 @@ public class LsRemoteCommand extends GitCommand<Collection<Ref>> {
try {
Transport transport = Transport.open(repo, remote);
transport.setOptionUploadPack(uploadPack);
+ configure(transport);
try {
Collection<RefSpec> refSpecs = new ArrayList<RefSpec>(1);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/PullCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/PullCommand.java
index 3e42da5677..67f9832fb6 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/PullCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/PullCommand.java
@@ -70,7 +70,6 @@ import org.eclipse.jgit.lib.ProgressMonitor;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.lib.RepositoryState;
-import org.eclipse.jgit.transport.CredentialsProvider;
import org.eclipse.jgit.transport.FetchResult;
/**
@@ -79,17 +78,12 @@ import org.eclipse.jgit.transport.FetchResult;
* @see <a href="http://www.kernel.org/pub/software/scm/git/docs/git-pull.html"
* >Git documentation about Pull</a>
*/
-public class PullCommand extends GitCommand<PullResult> {
- private int timeout = 0;
+public class PullCommand extends TransportCommand<PullCommand, PullResult> {
private final static String DOT = ".";
private ProgressMonitor monitor = NullProgressMonitor.INSTANCE;
- private CredentialsProvider credentialsProvider;
-
- private TransportConfigCallback transportConfigCallback;
-
/**
* @param repo
*/
@@ -98,16 +92,6 @@ public class PullCommand extends GitCommand<PullResult> {
}
/**
- * @param timeout
- * in seconds
- * @return this instance
- */
- public PullCommand setTimeout(int timeout) {
- this.timeout = timeout;
- return this;
- }
-
- /**
* @param monitor
* a progress monitor
* @return this instance
@@ -118,33 +102,6 @@ public class PullCommand extends GitCommand<PullResult> {
}
/**
- * @param credentialsProvider
- * the {@link CredentialsProvider} to use
- * @return this instance
- */
- public PullCommand setCredentialsProvider(
- CredentialsProvider credentialsProvider) {
- checkCallable();
- this.credentialsProvider = credentialsProvider;
- return this;
- }
-
- /**
- * @param transportConfigCallback
- * if set, the callback will be invoked after the Transport has
- * created, but before the Transport is used. The callback can
- * use this opportunity to set additional type-specific
- * configuration on the Transport instance.
- * @return {@code this}
- */
- public PullCommand setTransportConfigCallback(
- TransportConfigCallback transportConfigCallback) {
- checkCallable();
- this.transportConfigCallback = transportConfigCallback;
- return this;
- }
-
- /**
* Executes the {@code Pull} command with all the options and parameters
* collected by the setter methods (e.g.
* {@link #setProgressMonitor(ProgressMonitor)}) of this class. Each
@@ -229,9 +186,7 @@ public class PullCommand extends GitCommand<PullResult> {
FetchCommand fetch = new FetchCommand(repo);
fetch.setRemote(remote);
fetch.setProgressMonitor(monitor);
- fetch.setTimeout(this.timeout);
- fetch.setCredentialsProvider(credentialsProvider);
- fetch.setTransportConfigCallback(transportConfigCallback);
+ configure(fetch);
fetchRes = fetch.call();
} else {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/PushCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/PushCommand.java
index a89e131bae..a7a0577158 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/PushCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/PushCommand.java
@@ -60,7 +60,6 @@ import org.eclipse.jgit.lib.NullProgressMonitor;
import org.eclipse.jgit.lib.ProgressMonitor;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
-import org.eclipse.jgit.transport.CredentialsProvider;
import org.eclipse.jgit.transport.PushResult;
import org.eclipse.jgit.transport.RefSpec;
import org.eclipse.jgit.transport.RemoteConfig;
@@ -75,7 +74,8 @@ import org.eclipse.jgit.transport.Transport;
* @see <a href="http://www.kernel.org/pub/software/scm/git/docs/git-push.html"
* >Git documentation about Push</a>
*/
-public class PushCommand extends GitCommand<Iterable<PushResult>> {
+public class PushCommand extends
+ TransportCommand<PushCommand, Iterable<PushResult>> {
private String remote = Constants.DEFAULT_REMOTE_NAME;
@@ -91,12 +91,6 @@ public class PushCommand extends GitCommand<Iterable<PushResult>> {
private boolean thin = Transport.DEFAULT_PUSH_THIN;
- private int timeout;
-
- private CredentialsProvider credentialsProvider;
-
- private TransportConfigCallback transportConfigCallback;
-
/**
* @param repo
*/
@@ -145,16 +139,11 @@ public class PushCommand extends GitCommand<Iterable<PushResult>> {
final List<Transport> transports;
transports = Transport.openAll(repo, remote, Transport.Operation.PUSH);
for (final Transport transport : transports) {
- if (0 <= timeout)
- transport.setTimeout(timeout);
transport.setPushThin(thin);
if (receivePack != null)
transport.setOptionReceivePack(receivePack);
transport.setDryRun(dryRun);
- if (credentialsProvider != null)
- transport.setCredentialsProvider(credentialsProvider);
- if (transportConfigCallback != null)
- transportConfigCallback.configure(transport);
+ configure(transport);
final Collection<RemoteRefUpdate> toPush = transport
.findRemoteRefUpdatesFor(refSpecs);
@@ -234,17 +223,6 @@ public class PushCommand extends GitCommand<Iterable<PushResult>> {
}
/**
- * @param timeout
- * the timeout used for the push operation
- * @return {@code this}
- */
- public PushCommand setTimeout(int timeout) {
- checkCallable();
- this.timeout = timeout;
- return this;
- }
-
- /**
* @return the timeout used for the push operation
*/
public int getTimeout() {
@@ -423,31 +401,4 @@ public class PushCommand extends GitCommand<Iterable<PushResult>> {
this.force = force;
return this;
}
-
- /**
- * @param credentialsProvider
- * the {@link CredentialsProvider} to use
- * @return {@code this}
- */
- public PushCommand setCredentialsProvider(
- CredentialsProvider credentialsProvider) {
- checkCallable();
- this.credentialsProvider = credentialsProvider;
- return this;
- }
-
- /**
- * @param transportConfigCallback
- * if set, the callback will be invoked after the Transport has
- * created, but before the Transport is used. The callback can
- * use this opportunity to set additional type-specific
- * configuration on the Transport instance.
- * @return {@code this}
- */
- public PushCommand setTransportConfigCallback(
- TransportConfigCallback transportConfigCallback) {
- checkCallable();
- this.transportConfigCallback = transportConfigCallback;
- return this;
- }
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/TransportCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/TransportCommand.java
new file mode 100644
index 0000000000..1aeb6109ec
--- /dev/null
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/TransportCommand.java
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2011, GitHub 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.api;
+
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.transport.CredentialsProvider;
+import org.eclipse.jgit.transport.Transport;
+
+/**
+ * Base class for commands that use a {@link Transport} during execution.
+ * <p>
+ * This class provides standard configuration of a transport for options such as
+ * a {@link CredentialsProvider}, a timeout, and a
+ * {@link TransportConfigCallback}.
+ *
+ * @param <C>
+ * @param <T>
+ */
+public abstract class TransportCommand<C extends GitCommand, T> extends
+ GitCommand<T> {
+
+ /**
+ * Configured credentials provider
+ */
+ protected CredentialsProvider credentialsProvider;
+
+ /**
+ * Configured transport timeout
+ */
+ protected int timeout;
+
+ /**
+ * Configured callback for transport configuration
+ */
+ protected TransportConfigCallback transportConfigCallback;
+
+ /**
+ * @param repo
+ */
+ protected TransportCommand(final Repository repo) {
+ super(repo);
+ }
+
+ /**
+ * @param credentialsProvider
+ * the {@link CredentialsProvider} to use
+ * @return {@code this}
+ */
+ public C setCredentialsProvider(
+ final CredentialsProvider credentialsProvider) {
+ this.credentialsProvider = credentialsProvider;
+ return self();
+ }
+
+ /**
+ * @param timeout
+ * the timeout used for the transport step
+ * @return {@code this}
+ */
+ public C setTimeout(int timeout) {
+ this.timeout = timeout;
+ return self();
+ }
+
+ /**
+ * @param transportConfigCallback
+ * if set, the callback will be invoked after the
+ * {@link Transport} has created, but before the
+ * {@link Transport} is used. The callback can use this
+ * opportunity to set additional type-specific configuration on
+ * the {@link Transport} instance.
+ * @return {@code this}
+ */
+ public C setTransportConfigCallback(
+ final TransportConfigCallback transportConfigCallback) {
+ this.transportConfigCallback = transportConfigCallback;
+ return self();
+ }
+
+ /** @return {@code this} */
+ @SuppressWarnings("unchecked")
+ protected final C self() {
+ return (C) this;
+ }
+
+ /**
+ * Configure transport with credentials provider, timeout, and config
+ * callback
+ *
+ * @param transport
+ * @return {@code this}
+ */
+ protected C configure(final Transport transport) {
+ if (credentialsProvider != null)
+ transport.setCredentialsProvider(credentialsProvider);
+ transport.setTimeout(timeout);
+ if (transportConfigCallback != null)
+ transportConfigCallback.configure(transport);
+ return self();
+ }
+
+ /**
+ * Configure a child command with the current configuration set in
+ * {@code this} command
+ *
+ * @param childCommand
+ * @return {@code this}
+ */
+ protected C configure(final TransportCommand childCommand) {
+ childCommand.setCredentialsProvider(credentialsProvider);
+ childCommand.setTimeout(timeout);
+ childCommand.setTransportConfigCallback(transportConfigCallback);
+ return self();
+ }
+}