Merge changes If98b0b97,I7c9c09b4 * changes: Add convenience factory method for most used builder pattern Don't use internal type FileRepository in public API
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 c904576..155a433 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.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 void testPush_CreateBranch() throws Exception { + "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.packaging/org.eclipse.jgit.feature/.settings/org.eclipse.core.resources.prefs b/org.eclipse.jgit.packaging/org.eclipse.jgit.feature/.settings/org.eclipse.core.resources.prefs index 6f96ce8..14bdc2c 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.feature/.settings/org.eclipse.core.resources.prefs +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.feature/.settings/org.eclipse.core.resources.prefs
@@ -1,3 +1,3 @@ -#Fri Jun 18 23:33:45 CEST 2010 -eclipse.preferences.version=1 -encoding/<project>=UTF-8 +#Fri Jun 18 23:33:45 CEST 2010 +eclipse.preferences.version=1 +encoding/<project>=UTF-8
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.feature/.settings/org.eclipse.core.runtime.prefs b/org.eclipse.jgit.packaging/org.eclipse.jgit.feature/.settings/org.eclipse.core.runtime.prefs index 1a32dba..898252b 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.feature/.settings/org.eclipse.core.runtime.prefs +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.feature/.settings/org.eclipse.core.runtime.prefs
@@ -1,3 +1,3 @@ -#Fri Jun 18 23:33:45 CEST 2010 -eclipse.preferences.version=1 -line.separator=\n +#Fri Jun 18 23:33:45 CEST 2010 +eclipse.preferences.version=1 +line.separator=\n
diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.feature/edl-v10.html b/org.eclipse.jgit.packaging/org.eclipse.jgit.feature/edl-v10.html index 01a2671..1826b47 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.feature/edl-v10.html +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.feature/edl-v10.html
@@ -11,13 +11,13 @@ margin: 0.25in 0.5in 0.25in 0.5in; tab-interval: 0.5in; } - p { + p { margin-left: auto; margin-top: 0.5em; margin-bottom: 0.5em; } p.list { - margin-left: 0.5in; + margin-left: 0.5in; margin-top: 0.05em; margin-bottom: 0.05em; } @@ -32,26 +32,26 @@ <p>Copyright (c) 2007, Eclipse Foundation, Inc. and its licensors. </p> <p>All rights reserved.</p> -<p>Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: -<ul><li>Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. </li> -<li>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. </li> -<li>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. </li></ul> +<p>Redistribution and use in source and binary forms, with or without modification, + are permitted provided that the following conditions are met: +<ul><li>Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer.</li> +<li>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.</li> +<li>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.</li></ul> </p> -<p>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 +<p>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.</p> </body>
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 69824b2..e523db9 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.assertTrue; import java.io.IOException; +import java.io.OutputStream; import java.util.HashMap; import java.util.HashSet; import java.util.Map; @@ -432,6 +433,12 @@ public void close() { } 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 { for (final RemoteRefUpdate rru : refsToUpdate.values()) {
diff --git a/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties b/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties index 677f735..b64617b 100644 --- a/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties +++ b/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties
@@ -124,6 +124,7 @@ couldNotDeleteLockFileShouldNotHappen=Could not delete lock file. Should not happen couldNotDeleteTemporaryIndexFileShouldNotHappen=Could not delete temporary index file. Should not happen couldNotGetAdvertisedRef=Could not get advertised Ref for branch {0} +couldNotGetRepoStatistics=Could not get repository statistics couldNotLockHEAD=Could not lock HEAD couldNotReadIndexInOneGo=Could not read index in one go, only {0} out of {1} read couldNotReadObjectWhileParsingCommit=Could not read an object while parsing commit {0}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/GarbageCollectCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/GarbageCollectCommand.java index 7fda6cc..77b84d3 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/GarbageCollectCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/GarbageCollectCommand.java
@@ -129,6 +129,24 @@ public Properties call() throws GitAPIException { } } + /** + * Computes and returns the repository statistics. + * + * @return the repository statistics + * @throws GitAPIException + * thrown if the repository statistics cannot be computed + * @since 3.0 + */ + public Properties getStatistics() throws GitAPIException { + try { + GC gc = new GC((FileRepository) repo); + return toProperties(gc.getStatistics()); + } catch (IOException e) { + throw new JGitInternalException( + JGitText.get().couldNotGetRepoStatistics, e); + } + } + @SuppressWarnings("boxing") private static Properties toProperties(RepoStatistics stats) { Properties p = new Properties();
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 1a4058e..c719f0a 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 Iterable<PushResult> call() throws GitAPIException, .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 PushCommand setForce(boolean force) { 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/internal/JGitText.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java index 7a1efe8..d7eb8af 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java
@@ -186,6 +186,7 @@ public static JGitText get() { /***/ public String couldNotDeleteLockFileShouldNotHappen; /***/ public String couldNotDeleteTemporaryIndexFileShouldNotHappen; /***/ public String couldNotGetAdvertisedRef; + /***/ public String couldNotGetRepoStatistics; /***/ public String couldNotLockHEAD; /***/ public String couldNotReadIndexInOneGo; /***/ public String couldNotReadObjectWhileParsingCommit;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/GC.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/GC.java index bc14d88..9950819 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/GC.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/GC.java
@@ -842,7 +842,7 @@ public class RepoStatistics { public String toString() { final StringBuilder b = new StringBuilder(); b.append("numberOfPackedObjects=").append(numberOfPackedObjects); //$NON-NLS-1$ - b.append(",numberOfPackFiles=").append(numberOfPackFiles); //$NON-NLS-1$ + b.append(", numberOfPackFiles=").append(numberOfPackFiles); //$NON-NLS-1$ b.append(", numberOfLooseObjects=").append(numberOfLooseObjects); //$NON-NLS-1$ b.append(", numberOfLooseRefs=").append(numberOfLooseRefs); //$NON-NLS-1$ b.append(", numberOfPackedRefs=").append(numberOfPackedRefs); //$NON-NLS-1$
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/PackConfig.java b/org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/PackConfig.java index 5180742..7559e90 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/PackConfig.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/PackConfig.java
@@ -689,18 +689,18 @@ public void fromConfig(final Config rc) { public String toString() { final StringBuilder b = new StringBuilder(); b.append("maxDeltaDepth=").append(getMaxDeltaDepth()); //$NON-NLS-1$ - b.append("deltaSearchWindowSize=").append(getDeltaSearchWindowSize()); //$NON-NLS-1$ - b.append("deltaSearchMemoryLimit=").append(getDeltaSearchMemoryLimit()); //$NON-NLS-1$ - b.append("deltaCacheSize=").append(getDeltaCacheSize()); //$NON-NLS-1$ - b.append("deltaCacheLimit=").append(getDeltaCacheLimit()); //$NON-NLS-1$ - b.append("compressionLevel=").append(getCompressionLevel()); //$NON-NLS-1$ - b.append("indexVersion=").append(getIndexVersion()); //$NON-NLS-1$ - b.append("bigFileThreshold=").append(getBigFileThreshold()); //$NON-NLS-1$ - b.append("threads=").append(getThreads()); //$NON-NLS-1$ - b.append("reuseDeltas=").append(isReuseDeltas()); //$NON-NLS-1$ - b.append("reuseObjects=").append(isReuseObjects()); //$NON-NLS-1$ - b.append("deltaCompress=").append(isDeltaCompress()); //$NON-NLS-1$ - b.append("buildBitmaps=").append(isBuildBitmaps()); //$NON-NLS-1$ + b.append(", deltaSearchWindowSize=").append(getDeltaSearchWindowSize()); //$NON-NLS-1$ + b.append(", deltaSearchMemoryLimit=").append(getDeltaSearchMemoryLimit()); //$NON-NLS-1$ + b.append(", deltaCacheSize=").append(getDeltaCacheSize()); //$NON-NLS-1$ + b.append(", deltaCacheLimit=").append(getDeltaCacheLimit()); //$NON-NLS-1$ + b.append(", compressionLevel=").append(getCompressionLevel()); //$NON-NLS-1$ + b.append(", indexVersion=").append(getIndexVersion()); //$NON-NLS-1$ + b.append(", bigFileThreshold=").append(getBigFileThreshold()); //$NON-NLS-1$ + b.append(", threads=").append(getThreads()); //$NON-NLS-1$ + b.append(", reuseDeltas=").append(isReuseDeltas()); //$NON-NLS-1$ + b.append(", reuseObjects=").append(isReuseObjects()); //$NON-NLS-1$ + b.append(", deltaCompress=").append(isDeltaCompress()); //$NON-NLS-1$ + b.append(", buildBitmaps=").append(isBuildBitmaps()); //$NON-NLS-1$ return b.toString(); } }
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 b77e644..cc27707 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<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); }
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 4b1411a..c82a0cd 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 @@ 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.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 FetchConfig parse(final Config cfg) { 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 Collection<PackLock> getPackLocks() { * 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 @@ protected void doFetch(final ProgressMonitor monitor, state = null; pckState = null; - receivePack(monitor); + receivePack(monitor, outputStream); } } catch (CancelledException ce) { close(); @@ -702,11 +715,13 @@ private void markCommon(final RevObject obj, final AckNackResult anr) ((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 b748d00..60985e7 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 BasePackPushConnection(final PackTransport packTransport) { 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 @@ protected TransportException noRepository() { * 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 @@ protected void doPush(final ProgressMonitor monitor, } 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 @@ private void writeCommands(final Collection<RemoteRefUpdate> refUpdates, 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 @@ private String enableCapabilities(final ProgressMonitor monitor) { 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 ef8e7d7..2d04240 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; @@ -112,6 +113,47 @@ public void fetch(final ProgressMonitor monitor, 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> * Some Git aware transports are able to implicitly grab an annotated tag if
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 489ac78..c2a885f 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<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; + }
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 3169bfc..53fba55 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 @@ /** * 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 @@ PushResult execute(final ProgressMonitor monitor) 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 b48a8a5..cf388e2 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 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 @@ private void doProgressLine(final String msg) throws IOException { } 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 5a7c0a1..3c19610 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.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,68 @@ public FetchResult fetch(final ProgressMonitor monitor, * 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 + * 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. + * @since 3.0 + */ + public PushResult push(final ProgressMonitor monitor, + Collection<RemoteRefUpdate> toPush, OutputStream out) + throws NotSupportedException, + TransportException { + if (toPush == null || toPush.isEmpty()) { + // If the caller did not ask for anything use the defaults. + try { + toPush = findRemoteRefUpdatesFor(push); + } catch (final IOException e) { + throw new TransportException(MessageFormat.format( + JGitText.get().problemWithResolvingPushRefSpecsLocally, e.getMessage()), e); + } + if (toPush.isEmpty()) + throw new TransportException(JGitText.get().nothingToPush); + } + 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 @@ -1147,19 +1210,7 @@ public FetchResult fetch(final ProgressMonitor monitor, public PushResult push(final ProgressMonitor monitor, Collection<RemoteRefUpdate> toPush) throws NotSupportedException, TransportException { - if (toPush == null || toPush.isEmpty()) { - // If the caller did not ask for anything use the defaults. - try { - toPush = findRemoteRefUpdatesFor(push); - } catch (final IOException e) { - throw new TransportException(MessageFormat.format( - JGitText.get().problemWithResolvingPushRefSpecsLocally, e.getMessage()), e); - } - if (toPush.isEmpty()) - throw new TransportException(JGitText.get().nothingToPush); - } - final PushProcess pushProcess = new PushProcess(this, toPush); - return pushProcess.execute(monitor); + return push(monitor, toPush, null); } /**
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 12a94fa..baaf886 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportHttp.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportHttp.java
@@ -1,6 +1,7 @@ /* * Copyright (C) 2008-2010, Google Inc. * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org> + * Copyright (C) 2013, Matthias Sohn <matthias.sohn@sap.com> * and other copyright owners as documented in the project's IP log. * * This program and the accompanying materials are made available @@ -83,8 +84,10 @@ import java.util.zip.GZIPInputStream; import java.util.zip.GZIPOutputStream; +import javax.net.ssl.HostnameVerifier; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSession; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; @@ -532,6 +535,7 @@ private void disableSslVerify(URLConnection conn) ctx.init(null, trustAllCerts, null); final HttpsURLConnection sslConn = (HttpsURLConnection) conn; sslConn.setSSLSocketFactory(ctx.getSocketFactory()); + sslConn.setHostnameVerifier(new DummyHostnameVerifier()); } catch (KeyManagementException e) { throw new IOException(e.getMessage()); } catch (NoSuchAlgorithmException e) { @@ -735,12 +739,12 @@ class SmartHttpFetchConnection extends BasePackFetchConnection { @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; } @@ -764,11 +768,11 @@ class SmartHttpPushConnection extends BasePackPushConnection { } 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); } } @@ -980,4 +984,11 @@ public void checkServerTrusted(X509Certificate[] certs, String authType) { // no check } } + + private static class DummyHostnameVerifier implements HostnameVerifier { + public boolean verify(String hostname, SSLSession session) { + // always accept + return true; + } + } }
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 5f8efe4..02960bf 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<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());