]> source.dussan.org Git - jgit.git/commitdiff
Allow users to show server messages while pushing 32/9732/10
authorAndré Dietisheim <adietish@redhat.com>
Fri, 1 Feb 2013 14:58:44 +0000 (15:58 +0100)
committerMatthias Sohn <matthias.sohn@sap.com>
Wed, 20 Mar 2013 23:30:30 +0000 (00:30 +0100)
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 <andre.dietisheim@gmail.com>
Signed-off-by: Chris Aniszczyk <zx@twitter.com>
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
13 files changed:
org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/test/HookMessageTest.java
org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/PushProcessTest.java
org.eclipse.jgit/src/org/eclipse/jgit/api/PushCommand.java
org.eclipse.jgit/src/org/eclipse/jgit/transport/BaseFetchConnection.java
org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackFetchConnection.java
org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackPushConnection.java
org.eclipse.jgit/src/org/eclipse/jgit/transport/FetchConnection.java
org.eclipse.jgit/src/org/eclipse/jgit/transport/PushConnection.java
org.eclipse.jgit/src/org/eclipse/jgit/transport/PushProcess.java
org.eclipse.jgit/src/org/eclipse/jgit/transport/SideBandInputStream.java
org.eclipse.jgit/src/org/eclipse/jgit/transport/Transport.java
org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportHttp.java
org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkPushConnection.java

index c9045763c6325325d3fab7f6465faead7f6324a7..155a43399c2c9a43a2b169c34406c71c0280714b 100644 (file)
@@ -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());
+       }
+
 }
index 69824b21385ebe5b69326e40249d9cb7fcd90ca6..e523db981a9dc73be4e2b051b02f59cd7e99f5bd 100644 (file)
@@ -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<String, RemoteRefUpdate> refsToUpdate, OutputStream out)
+                               throws TransportException {
+                       push(monitor, refsToUpdate);
+               }
+
                public void push(ProgressMonitor monitor,
                                Map<String, RemoteRefUpdate> refsToUpdate)
                                throws TransportException {
index 1a4058e12d6156aa72bc773992827e6b87698cb4..c719f0a546fd9c46fed5f80ef4b3fd13361c4b7a 100644 (file)
@@ -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;
+       }
 }
index b77e644a2557fe8750cbdc0f000a4443ffe7a7a3..cc2770771e03c325be9c0be1ebda01280dccc9f2 100644 (file)
@@ -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<Ref> want, final Set<ObjectId> have)
                        throws TransportException {
+               fetch(monitor, want, have, null);
+       }
+
+       public final void fetch(final ProgressMonitor monitor,
+                       final Collection<Ref> want, final Set<ObjectId> have,
+                       OutputStream out) throws TransportException {
                markStartedOperation();
                doFetch(monitor, want, have);
        }
index 4b1411ab6678cfbd5caf2159a6e1f41e34018bc5..c82a0cde815bdb0d023f36020b93306a460fb83c 100644 (file)
@@ -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<Ref> want, final Set<ObjectId> have)
                        throws TransportException {
+               fetch(monitor, want, have, null);
+       }
+
+       /**
+        * @since 3.0
+        */
+       public final void fetch(final ProgressMonitor monitor,
+                       final Collection<Ref> want, final Set<ObjectId> 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<Ref> want, final Set<ObjectId> have)
-                       throws TransportException {
+                       final Collection<Ref> want, final Set<ObjectId> 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 {
index b748d00a773e2a69b52ce351c15e71055d8f7dcf..60985e7c28cef40d2d90efec2cdbdaeecb18bef7 100644 (file)
@@ -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<String, RemoteRefUpdate> refUpdates)
                        throws TransportException {
+               push(monitor, refUpdates, null);
+       }
+
+       /**
+        * @since 3.0
+        */
+       public void push(final ProgressMonitor monitor,
+                       final Map<String, RemoteRefUpdate> 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<String, RemoteRefUpdate> refUpdates)
-                       throws TransportException {
+                       final Map<String, RemoteRefUpdate> 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<RemoteRefUpdate> 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);
                }
 
index ef8e7d74d5fa171296874db191599b0439d0a31f..2d042400f6c6ebf81727393fdea431489ccf33c0 100644 (file)
@@ -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<Ref> want, final Set<ObjectId> have)
                        throws TransportException;
 
+       /**
+        * Fetch objects we don't have but that are reachable from advertised refs.
+        * <p>
+        * Only one call per connection is allowed. Subsequent calls will result in
+        * {@link TransportException}.
+        * </p>
+        * <p>
+        * 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.
+        * </p>
+        *
+        * @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<Ref> want, final Set<ObjectId> have,
+                       OutputStream out) throws TransportException;
+
        /**
         * Did the last {@link #fetch(ProgressMonitor, Collection, Set)} get tags?
         * <p>
index 489ac7887466d456855d2fa33ce56583c03e4593..c2a885f6225f22ca5a25e82ff0395c0384572d04 100644 (file)
@@ -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<String, RemoteRefUpdate> 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.
+        * <p>
+        * <p>
+        * Only one call per connection is allowed. Subsequent calls will result in
+        * {@link TransportException}.
+        * </p>
+        * <p>
+        * 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.
+        * </p>
+        *
+        * @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<String, RemoteRefUpdate> refUpdates, OutputStream out)
+                       throws TransportException;
+
 }
index 3169bfc230215f8d80ee7ebfae93bdeb2c551cf2..53fba555726f9bfb9dc40989ff946e60c4fbad03 100644 (file)
@@ -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<RemoteRefUpdate> 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<RemoteRefUpdate> toPush, OutputStream out)
+                       throws TransportException {
                this.walker = new RevWalk(transport.local);
                this.transport = transport;
                this.toPush = new HashMap<String, RemoteRefUpdate>();
+               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());
index b48a8a5f096d7cd07dbda3a1fd74c70154319bc9..cf388e2718e3cbc188c1b4bd5fe3498192128423 100644 (file)
@@ -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) {
index 5a7c0a194ee002ca2725a31d2f2e984c685aff55..3c196109d747a6bd8d3923922c26361c467ed34b 100644 (file)
@@ -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<RemoteRefUpdate> toPush) throws NotSupportedException,
+                       Collection<RemoteRefUpdate> 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.
+        * <p>
+        * 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.
+        * <p>
+        * 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.
+        * <p>
+        * 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<RemoteRefUpdate> 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
index 9816d97808a2ea406f0c2571fe694f48322e4184..baaf8867e4b74b4b822ec4cea0dd15b23400ff29 100644 (file)
@@ -739,12 +739,12 @@ public class TransportHttp extends HttpTransport implements WalkTransport,
 
                @Override
                protected void doFetch(final ProgressMonitor monitor,
-                               final Collection<Ref> want, final Set<ObjectId> have)
-                               throws TransportException {
+                               final Collection<Ref> want, final Set<ObjectId> 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<String, RemoteRefUpdate> refUpdates)
-                               throws TransportException {
+                               final Map<String, RemoteRefUpdate> 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);
                }
        }
 
index 5f8efe47c342f1ad765b2e3f0e7530f0b7477cf7..02960bf293b8ad785d136a4ba0ec540d77d84e27 100644 (file)
@@ -137,6 +137,12 @@ class WalkPushConnection extends BaseConnection implements PushConnection {
        public void push(final ProgressMonitor monitor,
                        final Map<String, RemoteRefUpdate> refUpdates)
                        throws TransportException {
+               push(monitor, refUpdates, null);
+       }
+
+       public void push(final ProgressMonitor monitor,
+                       final Map<String, RemoteRefUpdate> refUpdates, OutputStream out)
+                       throws TransportException {
                markStartedOperation();
                packNames = null;
                newRefs = new TreeMap<String, Ref>(getRefsMap());