From a31920555f075c028f087b2e174293e1f11d714d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Dietisheim?= Date: Fri, 1 Feb 2013 15:58:44 +0100 Subject: [PATCH] Allow users to show server messages while pushing Allow users to provide their OutputStream (via Transport# push(monitor, refUpdates, out)) so that server messages can be written to it (in SideBandInputStream) while they're coming in. CQ: 7065 Bug: 398404 Change-Id: I670782784b38702d52bca98203909aca0496d1c0 Signed-off-by: Andre Dietisheim Signed-off-by: Chris Aniszczyk Signed-off-by: Matthias Sohn --- .../jgit/http/test/HookMessageTest.java | 38 +++++++++++++ .../jgit/transport/PushProcessTest.java | 7 +++ .../src/org/eclipse/jgit/api/PushCommand.java | 17 +++++- .../jgit/transport/BaseFetchConnection.java | 7 +++ .../transport/BasePackFetchConnection.java | 29 +++++++--- .../transport/BasePackPushConnection.java | 31 ++++++++--- .../jgit/transport/FetchConnection.java | 42 ++++++++++++++ .../jgit/transport/PushConnection.java | 47 ++++++++++++++++ .../eclipse/jgit/transport/PushProcess.java | 28 +++++++++- .../jgit/transport/SideBandInputStream.java | 8 ++- .../org/eclipse/jgit/transport/Transport.java | 55 ++++++++++++++++++- .../eclipse/jgit/transport/TransportHttp.java | 12 ++-- .../jgit/transport/WalkPushConnection.java | 6 ++ 13 files changed, 300 insertions(+), 27 deletions(-) diff --git a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/HookMessageTest.java b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/HookMessageTest.java index c9045763c..155a43399 100644 --- a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/HookMessageTest.java +++ b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/HookMessageTest.java @@ -47,6 +47,8 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; +import java.io.ByteArrayOutputStream; +import java.io.OutputStream; import java.util.Collection; import java.util.Collections; import java.util.List; @@ -180,4 +182,40 @@ public class HookMessageTest extends HttpTestCase { + "come back next year!\n", // result.getMessages()); } + + @Test + public void testPush_HookMessagesToOutputStream() throws Exception { + final TestRepository src = createTestRepository(); + final RevBlob Q_txt = src.blob("new text"); + final RevCommit Q = src.commit().add("Q", Q_txt).create(); + final Repository db = src.getRepository(); + final String dstName = Constants.R_HEADS + "new.branch"; + Transport t; + PushResult result; + + t = Transport.open(db, remoteURI); + OutputStream out = new ByteArrayOutputStream(); + try { + final String srcExpr = Q.name(); + final boolean forceUpdate = false; + final String localName = null; + final ObjectId oldId = null; + + RemoteRefUpdate update = new RemoteRefUpdate(src.getRepository(), + srcExpr, dstName, forceUpdate, localName, oldId); + result = t.push(NullProgressMonitor.INSTANCE, + Collections.singleton(update), out); + } finally { + t.close(); + } + + String expectedMessage = "message line 1\n" // + + "error: no soup for you!\n" // + + "come back next year!\n"; + assertEquals(expectedMessage, // + result.getMessages()); + + assertEquals(expectedMessage, out.toString()); + } + } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PushProcessTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PushProcessTest.java index 69824b213..e523db981 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PushProcessTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PushProcessTest.java @@ -48,6 +48,7 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import java.io.IOException; +import java.io.OutputStream; import java.util.HashMap; import java.util.HashSet; import java.util.Map; @@ -431,6 +432,12 @@ public class PushProcessTest extends SampleDataRepositoryTestCase { // nothing here } + public void push(ProgressMonitor monitor, + Map refsToUpdate, OutputStream out) + throws TransportException { + push(monitor, refsToUpdate); + } + public void push(ProgressMonitor monitor, Map refsToUpdate) throws TransportException { 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 1a4058e12..c719f0a54 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/PushCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/PushCommand.java @@ -43,6 +43,7 @@ package org.eclipse.jgit.api; import java.io.IOException; +import java.io.OutputStream; import java.net.URISyntaxException; import java.text.MessageFormat; import java.util.ArrayList; @@ -92,6 +93,8 @@ public class PushCommand extends private boolean thin = Transport.DEFAULT_PUSH_THIN; + private OutputStream out; + /** * @param repo */ @@ -150,7 +153,7 @@ public class PushCommand extends .findRemoteRefUpdatesFor(refSpecs); try { - PushResult result = transport.push(monitor, toPush); + PushResult result = transport.push(monitor, toPush, out); pushResults.add(result); } catch (TransportException e) { @@ -404,4 +407,16 @@ public class PushCommand extends this.force = force; return this; } + + /** + * Sets the output stream to write sideband messages to + * + * @param out + * @return {@code this} + * @since 3.0 + */ + public PushCommand setOutputStream(OutputStream out) { + this.out = out; + return this; + } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BaseFetchConnection.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BaseFetchConnection.java index b77e644a2..cc2770771 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BaseFetchConnection.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BaseFetchConnection.java @@ -45,6 +45,7 @@ package org.eclipse.jgit.transport; +import java.io.OutputStream; import java.util.Collection; import java.util.Set; @@ -66,6 +67,12 @@ abstract class BaseFetchConnection extends BaseConnection implements public final void fetch(final ProgressMonitor monitor, final Collection want, final Set have) throws TransportException { + fetch(monitor, want, have, null); + } + + public final void fetch(final ProgressMonitor monitor, + final Collection want, final Set have, + OutputStream out) throws TransportException { markStartedOperation(); doFetch(monitor, want, have); } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackFetchConnection.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackFetchConnection.java index 4b1411ab6..c82a0cde8 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackFetchConnection.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackFetchConnection.java @@ -47,6 +47,7 @@ package org.eclipse.jgit.transport; import java.io.IOException; import java.io.InputStream; +import java.io.OutputStream; import java.text.MessageFormat; import java.util.Collection; import java.util.Collections; @@ -59,13 +60,13 @@ import org.eclipse.jgit.internal.JGitText; import org.eclipse.jgit.internal.storage.file.PackLock; import org.eclipse.jgit.lib.AnyObjectId; import org.eclipse.jgit.lib.Config; +import org.eclipse.jgit.lib.Config.SectionParser; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.MutableObjectId; import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.ObjectInserter; import org.eclipse.jgit.lib.ProgressMonitor; import org.eclipse.jgit.lib.Ref; -import org.eclipse.jgit.lib.Config.SectionParser; import org.eclipse.jgit.revwalk.RevCommit; import org.eclipse.jgit.revwalk.RevCommitList; import org.eclipse.jgit.revwalk.RevFlag; @@ -265,8 +266,17 @@ public abstract class BasePackFetchConnection extends BasePackConnection public final void fetch(final ProgressMonitor monitor, final Collection want, final Set have) throws TransportException { + fetch(monitor, want, have, null); + } + + /** + * @since 3.0 + */ + public final void fetch(final ProgressMonitor monitor, + final Collection want, final Set have, + OutputStream outputStream) throws TransportException { markStartedOperation(); - doFetch(monitor, want, have); + doFetch(monitor, want, have, outputStream); } public boolean didFetchIncludeTags() { @@ -298,12 +308,15 @@ public abstract class BasePackFetchConnection extends BasePackConnection * additional objects to assume that already exist locally. This * will be added to the set of objects reachable from the * destination repository's references. + * @param outputStream + * ouputStream to write sideband messages to * @throws TransportException * if any exception occurs. + * @since 3.0 */ protected void doFetch(final ProgressMonitor monitor, - final Collection want, final Set have) - throws TransportException { + final Collection want, final Set have, + OutputStream outputStream) throws TransportException { try { markRefsAdvertised(); markReachable(have, maxTimeWanted(want)); @@ -321,7 +334,7 @@ public abstract class BasePackFetchConnection extends BasePackConnection state = null; pckState = null; - receivePack(monitor); + receivePack(monitor, outputStream); } } catch (CancelledException ce) { close(); @@ -702,11 +715,13 @@ public abstract class BasePackFetchConnection extends BasePackConnection ((RevCommit) obj).carry(COMMON); } - private void receivePack(final ProgressMonitor monitor) throws IOException { + private void receivePack(final ProgressMonitor monitor, + OutputStream outputStream) throws IOException { onReceivePack(); InputStream input = in; if (sideband) - input = new SideBandInputStream(input, monitor, getMessageWriter()); + input = new SideBandInputStream(input, monitor, getMessageWriter(), + outputStream); ObjectInserter ins = local.newObjectInserter(); try { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackPushConnection.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackPushConnection.java index b748d00a7..60985e7c2 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackPushConnection.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackPushConnection.java @@ -45,6 +45,7 @@ package org.eclipse.jgit.transport; import java.io.IOException; +import java.io.OutputStream; import java.text.MessageFormat; import java.util.Collection; import java.util.HashSet; @@ -138,8 +139,17 @@ public abstract class BasePackPushConnection extends BasePackConnection implemen public void push(final ProgressMonitor monitor, final Map refUpdates) throws TransportException { + push(monitor, refUpdates, null); + } + + /** + * @since 3.0 + */ + public void push(final ProgressMonitor monitor, + final Map refUpdates, OutputStream outputStream) + throws TransportException { markStartedOperation(); - doPush(monitor, refUpdates); + doPush(monitor, refUpdates, outputStream); } @Override @@ -172,14 +182,17 @@ public abstract class BasePackPushConnection extends BasePackConnection implemen * progress monitor to receive status updates. * @param refUpdates * update commands to be applied to the remote repository. + * @param outputStream + * output stream to write sideband messages to * @throws TransportException * if any exception occurs. + * @since 3.0 */ protected void doPush(final ProgressMonitor monitor, - final Map refUpdates) - throws TransportException { + final Map refUpdates, + OutputStream outputStream) throws TransportException { try { - writeCommands(refUpdates.values(), monitor); + writeCommands(refUpdates.values(), monitor, outputStream); if (writePack) writePack(refUpdates, monitor); if (sentCommand) { @@ -208,8 +221,8 @@ public abstract class BasePackPushConnection extends BasePackConnection implemen } private void writeCommands(final Collection refUpdates, - final ProgressMonitor monitor) throws IOException { - final String capabilities = enableCapabilities(monitor); + final ProgressMonitor monitor, OutputStream outputStream) throws IOException { + final String capabilities = enableCapabilities(monitor, outputStream); for (final RemoteRefUpdate rru : refUpdates) { if (!capableDeleteRefs && rru.isDelete()) { rru.setStatus(Status.REJECTED_NODELETE); @@ -242,7 +255,8 @@ public abstract class BasePackPushConnection extends BasePackConnection implemen outNeedsEnd = false; } - private String enableCapabilities(final ProgressMonitor monitor) { + private String enableCapabilities(final ProgressMonitor monitor, + OutputStream outputStream) { final StringBuilder line = new StringBuilder(); capableReport = wantCapability(line, CAPABILITY_REPORT_STATUS); capableDeleteRefs = wantCapability(line, CAPABILITY_DELETE_REFS); @@ -250,7 +264,8 @@ public abstract class BasePackPushConnection extends BasePackConnection implemen capableSideBand = wantCapability(line, CAPABILITY_SIDE_BAND_64K); if (capableSideBand) { - in = new SideBandInputStream(in, monitor, getMessageWriter()); + in = new SideBandInputStream(in, monitor, getMessageWriter(), + outputStream); pckIn = new PacketLineIn(in); } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchConnection.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchConnection.java index ef8e7d74d..2d042400f 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchConnection.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchConnection.java @@ -46,6 +46,7 @@ package org.eclipse.jgit.transport; +import java.io.OutputStream; import java.util.Collection; import java.util.Set; @@ -111,6 +112,47 @@ public interface FetchConnection extends Connection { final Collection want, final Set have) throws TransportException; + /** + * Fetch objects we don't have but that are reachable from advertised refs. + *

+ * Only one call per connection is allowed. Subsequent calls will result in + * {@link TransportException}. + *

+ *

+ * Implementations are free to use network connections as necessary to + * efficiently (for both client and server) transfer objects from the remote + * repository into this repository. When possible implementations should + * avoid replacing/overwriting/duplicating an object already available in + * the local destination repository. Locally available objects and packs + * should always be preferred over remotely available objects and packs. + * {@link Transport#isFetchThin()} should be honored if applicable. + *

+ * + * @param monitor + * progress monitor to inform the end-user about the amount of + * work completed, or to indicate cancellation. Implementations + * should poll the monitor at regular intervals to look for + * cancellation requests from the user. + * @param want + * one or more refs advertised by this connection that the caller + * wants to store locally. + * @param have + * additional objects known to exist in the destination + * repository, especially if they aren't yet reachable by the ref + * database. Connections should take this set as an addition to + * what is reachable through all Refs, not in replace of it. + * @param out + * OutputStream to write sideband messages to + * @throws TransportException + * objects could not be copied due to a network failure, + * protocol error, or error on remote side, or connection was + * already used for fetch. + * @since 3.0 + */ + public void fetch(final ProgressMonitor monitor, + final Collection want, final Set have, + OutputStream out) throws TransportException; + /** * Did the last {@link #fetch(ProgressMonitor, Collection, Set)} get tags? *

diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PushConnection.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PushConnection.java index 489ac7887..c2a885f62 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PushConnection.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PushConnection.java @@ -44,6 +44,7 @@ package org.eclipse.jgit.transport; +import java.io.OutputStream; import java.util.Map; import org.eclipse.jgit.errors.TransportException; @@ -111,4 +112,50 @@ public interface PushConnection extends Connection { public void push(final ProgressMonitor monitor, final Map refUpdates) throws TransportException; + + /** + * Pushes to the remote repository basing on provided specification. This + * possibly result in update/creation/deletion of refs on remote repository + * and sending objects that remote repository need to have a consistent + * objects graph from new refs. + *

+ *

+ * Only one call per connection is allowed. Subsequent calls will result in + * {@link TransportException}. + *

+ *

+ * Implementation may use local repository to send a minimum set of objects + * needed by remote repository in efficient way. + * {@link Transport#isPushThin()} should be honored if applicable. + * refUpdates should be filled with information about status of each update. + *

+ * + * @param monitor + * progress monitor to update the end-user about the amount of + * work completed, or to indicate cancellation. Implementors + * should poll the monitor at regular intervals to look for + * cancellation requests from the user. + * @param refUpdates + * map of remote refnames to remote refs update + * specifications/statuses. Can't be empty. This indicate what + * refs caller want to update on remote side. Only refs updates + * with {@link Status#NOT_ATTEMPTED} should passed. + * Implementation must ensure that and appropriate status with + * optional message should be set during call. No refUpdate with + * {@link Status#AWAITING_REPORT} or {@link Status#NOT_ATTEMPTED} + * can be leaved by implementation after return from this call. + * @param out + * output stream to write sideband messages to + * @throws TransportException + * objects could not be copied due to a network failure, + * critical protocol error, or error on remote side, or + * connection was already used for push - new connection must be + * created. Non-critical errors concerning only isolated refs + * should be placed in refUpdates. + * @since 3.0 + */ + public void push(final ProgressMonitor monitor, + final Map refUpdates, OutputStream out) + throws TransportException; + } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PushProcess.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PushProcess.java index 3169bfc23..53fba5557 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PushProcess.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PushProcess.java @@ -44,6 +44,7 @@ package org.eclipse.jgit.transport; import java.io.IOException; +import java.io.OutputStream; import java.text.MessageFormat; import java.util.Collection; import java.util.HashMap; @@ -64,7 +65,7 @@ import org.eclipse.jgit.transport.RemoteRefUpdate.Status; /** * Class performing push operation on remote repository. * - * @see Transport#push(ProgressMonitor, Collection) + * @see Transport#push(ProgressMonitor, Collection, OutputStream) */ class PushProcess { /** Task name for {@link ProgressMonitor} used during opening connection. */ @@ -82,6 +83,9 @@ class PushProcess { /** Revision walker for checking some updates properties. */ private final RevWalk walker; + /** an outputstream to write messages to */ + private final OutputStream out; + /** * Create process for specified transport and refs updates specification. * @@ -90,13 +94,33 @@ class PushProcess { * connection. * @param toPush * specification of refs updates (and local tracking branches). + * * @throws TransportException */ PushProcess(final Transport transport, final Collection toPush) throws TransportException { + this(transport, toPush, null); + } + + /** + * Create process for specified transport and refs updates specification. + * + * @param transport + * transport between remote and local repository, used to create + * connection. + * @param toPush + * specification of refs updates (and local tracking branches). + * @param out + * OutputStream to write messages to + * @throws TransportException + */ + PushProcess(final Transport transport, + final Collection toPush, OutputStream out) + throws TransportException { this.walker = new RevWalk(transport.local); this.transport = transport; this.toPush = new HashMap(); + this.out = out; for (final RemoteRefUpdate rru : toPush) { if (this.toPush.put(rru.getRemoteName(), rru) != null) throw new TransportException(MessageFormat.format( @@ -138,7 +162,7 @@ class PushProcess { if (transport.isDryRun()) modifyUpdatesForDryRun(); else if (!preprocessed.isEmpty()) - connection.push(monitor, preprocessed); + connection.push(monitor, preprocessed, out); } finally { connection.close(); res.addMessages(connection.getMessages()); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/SideBandInputStream.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/SideBandInputStream.java index b48a8a5f0..cf388e271 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/SideBandInputStream.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/SideBandInputStream.java @@ -48,6 +48,7 @@ import static org.eclipse.jgit.transport.SideBandOutputStream.HDR_SIZE; import java.io.IOException; import java.io.InputStream; +import java.io.OutputStream; import java.io.Writer; import java.text.MessageFormat; import java.util.regex.Matcher; @@ -99,6 +100,8 @@ class SideBandInputStream extends InputStream { private final Writer messages; + private final OutputStream out; + private String progressBuffer = ""; //$NON-NLS-1$ private String currentTask; @@ -112,12 +115,13 @@ class SideBandInputStream extends InputStream { private int available; SideBandInputStream(final InputStream in, final ProgressMonitor progress, - final Writer messageStream) { + final Writer messageStream, OutputStream outputStream) { rawIn = in; pckIn = new PacketLineIn(rawIn); monitor = progress; messages = messageStream; currentTask = ""; //$NON-NLS-1$ + out = outputStream; } @Override @@ -232,6 +236,8 @@ class SideBandInputStream extends InputStream { } messages.write(msg); + if (out != null) + out.write(msg.getBytes()); } private void beginTask(final int totalWorkUnits) { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/Transport.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/Transport.java index 5a7c0a194..3c196109d 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/Transport.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/Transport.java @@ -50,6 +50,7 @@ import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; +import java.io.OutputStream; import java.lang.ref.WeakReference; import java.lang.reflect.Field; import java.lang.reflect.Modifier; @@ -1134,6 +1135,8 @@ public abstract class Transport { * converted by {@link #findRemoteRefUpdatesFor(Collection)}. No * more than 1 RemoteRefUpdate with the same remoteName is * allowed. These objects are modified during this call. + * @param out + * output stream to write messages to * @return information about results of remote refs updates, tracking refs * updates and refs advertised by remote repository. * @throws NotSupportedException @@ -1143,9 +1146,11 @@ public abstract class Transport { * the remote connection could not be established or object * copying (if necessary) failed at I/O or protocol level or * update specification was incorrect. + * @since 3.0 */ public PushResult push(final ProgressMonitor monitor, - Collection toPush) throws NotSupportedException, + Collection toPush, OutputStream out) + throws NotSupportedException, TransportException { if (toPush == null || toPush.isEmpty()) { // If the caller did not ask for anything use the defaults. @@ -1158,10 +1163,56 @@ public abstract class Transport { if (toPush.isEmpty()) throw new TransportException(JGitText.get().nothingToPush); } - final PushProcess pushProcess = new PushProcess(this, toPush); + final PushProcess pushProcess = new PushProcess(this, toPush, out); return pushProcess.execute(monitor); } + /** + * Push objects and refs from the local repository to the remote one. + *

+ * This is a utility function providing standard push behavior. It updates + * remote refs and sends necessary objects according to remote ref update + * specification. After successful remote ref update, associated locally + * stored tracking branch is updated if set up accordingly. Detailed + * operation result is provided after execution. + *

+ * For setting up remote ref update specification from ref spec, see helper + * method {@link #findRemoteRefUpdatesFor(Collection)}, predefined refspecs + * ({@link #REFSPEC_TAGS}, {@link #REFSPEC_PUSH_ALL}) or consider using + * directly {@link RemoteRefUpdate} for more possibilities. + *

+ * When {@link #isDryRun()} is true, result of this operation is just + * estimation of real operation result, no real action is performed. + * + * @see RemoteRefUpdate + * + * @param monitor + * progress monitor to inform the user about our processing + * activity. Must not be null. Use {@link NullProgressMonitor} if + * progress updates are not interesting or necessary. + * @param toPush + * specification of refs to push. May be null or the empty + * collection to use the specifications from the RemoteConfig + * converted by {@link #findRemoteRefUpdatesFor(Collection)}. No + * more than 1 RemoteRefUpdate with the same remoteName is + * allowed. These objects are modified during this call. + * + * @return information about results of remote refs updates, tracking refs + * updates and refs advertised by remote repository. + * @throws NotSupportedException + * this transport implementation does not support pushing + * objects. + * @throws TransportException + * the remote connection could not be established or object + * copying (if necessary) failed at I/O or protocol level or + * update specification was incorrect. + */ + public PushResult push(final ProgressMonitor monitor, + Collection toPush) throws NotSupportedException, + TransportException { + return push(monitor, toPush, null); + } + /** * Convert push remote refs update specification from {@link RefSpec} form * to {@link RemoteRefUpdate}. Conversion expands wildcards by matching diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportHttp.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportHttp.java index 9816d9780..baaf8867e 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportHttp.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportHttp.java @@ -739,12 +739,12 @@ public class TransportHttp extends HttpTransport implements WalkTransport, @Override protected void doFetch(final ProgressMonitor monitor, - final Collection want, final Set have) - throws TransportException { + final Collection want, final Set have, + final OutputStream outputStream) throws TransportException { try { svc = new MultiRequestService(SVC_UPLOAD_PACK); init(svc.getInputStream(), svc.getOutputStream()); - super.doFetch(monitor, want, have); + super.doFetch(monitor, want, have, outputStream); } finally { svc = null; } @@ -768,11 +768,11 @@ public class TransportHttp extends HttpTransport implements WalkTransport, } protected void doPush(final ProgressMonitor monitor, - final Map refUpdates) - throws TransportException { + final Map refUpdates, + OutputStream outputStream) throws TransportException { final Service svc = new MultiRequestService(SVC_RECEIVE_PACK); init(svc.getInputStream(), svc.getOutputStream()); - super.doPush(monitor, refUpdates); + super.doPush(monitor, refUpdates, outputStream); } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkPushConnection.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkPushConnection.java index 5f8efe47c..02960bf29 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkPushConnection.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkPushConnection.java @@ -137,6 +137,12 @@ class WalkPushConnection extends BaseConnection implements PushConnection { public void push(final ProgressMonitor monitor, final Map refUpdates) throws TransportException { + push(monitor, refUpdates, null); + } + + public void push(final ProgressMonitor monitor, + final Map refUpdates, OutputStream out) + throws TransportException { markStartedOperation(); packNames = null; newRefs = new TreeMap(getRefsMap());