openAll() method honours many URIs in remote configuration when opening transports. Old open() calls remained, they still open only 1 transport at time. openAll() is used during push operation - pgm.Push implementation was fixed to use it. applyConfig() is used internally here, but could be interesting for clients and it's safe to call it. Signed-off-by: Marek Zawirski <marek.zawirski@xxxxxxxxx> --- .../src/org/spearce/jgit/pgm/Push.java | 44 ++++++----- .../src/org/spearce/jgit/transport/Transport.java | 83 ++++++++++++++++++-- 2 files changed, 99 insertions(+), 28 deletions(-) diff --git a/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/Push.java b/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/Push.java index 6b35ab8..a952309 100644 --- a/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/Push.java +++ b/org.spearce.jgit.pgm/src/org/spearce/jgit/pgm/Push.java @@ -86,7 +86,7 @@ class Push extends TextBuiltin { @Option(name = "--receive-pack", metaVar = "path") private String receivePack; - private boolean first = true; + private boolean shownURI; @Override protected void run() throws Exception { @@ -97,27 +97,31 @@ class Push extends TextBuiltin { refSpecs.add(spec.setForceUpdate(true)); } - final Transport transport = Transport.open(db, remote); - transport.setPushThin(thin); - if (receivePack != null) - transport.setOptionReceivePack(receivePack); - final Collection<RemoteRefUpdate> toPush = transport - .findRemoteRefUpdatesFor(refSpecs); + final List<Transport> transports = Transport.openAll(db, remote); + for (final Transport transport : transports) { + transport.setPushThin(thin); + if (receivePack != null) + transport.setOptionReceivePack(receivePack); - final PushResult result = transport.push(new TextProgressMonitor(), - toPush); - transport.close(); + final Collection<RemoteRefUpdate> toPush = transport + .findRemoteRefUpdatesFor(refSpecs); - printPushResult(result); + final PushResult result = transport.push(new TextProgressMonitor(), + toPush); + printPushResult(transport, result); + } } - private void printPushResult(final PushResult result) { + private void printPushResult(final Transport transport, + final PushResult result) { + shownURI = false; boolean everythingUpToDate = true; + // at first, print up-to-date ones... for (final RemoteRefUpdate rru : result.getRemoteUpdates()) { if (rru.getStatus() == Status.UP_TO_DATE) { if (verbose) - printRefUpdateResult(result, rru); + printRefUpdateResult(transport, result, rru); } else everythingUpToDate = false; } @@ -125,25 +129,25 @@ class Push extends TextBuiltin { for (final RemoteRefUpdate rru : result.getRemoteUpdates()) { // ...then successful updates... if (rru.getStatus() == Status.OK) - printRefUpdateResult(result, rru); + printRefUpdateResult(transport, result, rru); } for (final RemoteRefUpdate rru : result.getRemoteUpdates()) { // ...finally, others (problematic) if (rru.getStatus() != Status.OK && rru.getStatus() != Status.UP_TO_DATE) - printRefUpdateResult(result, rru); + printRefUpdateResult(transport, result, rru); } if (everythingUpToDate) out.println("Everything up-to-date"); } - private void printRefUpdateResult(final PushResult result, - final RemoteRefUpdate rru) { - if (first) { - first = false; - out.format("To %s\n", result.getURI()); + private void printRefUpdateResult(final Transport transport, + final PushResult result, final RemoteRefUpdate rru) { + if (!shownURI) { + shownURI = true; + out.format("To %s\n", transport.getURI()); } final String remoteName = rru.getRemoteName(); diff --git a/org.spearce.jgit/src/org/spearce/jgit/transport/Transport.java b/org.spearce.jgit/src/org/spearce/jgit/transport/Transport.java index 30175e3..73aa771 100644 --- a/org.spearce.jgit/src/org/spearce/jgit/transport/Transport.java +++ b/org.spearce.jgit/src/org/spearce/jgit/transport/Transport.java @@ -75,8 +75,10 @@ public abstract class Transport { * @param local * existing local repository. * @param remote - * location of the remote repository. - * @return the new transport instance. Never null. + * location of the remote repository - may be URI or remote + * configuration name. + * @return the new transport instance. Never null. In case of multiple URIs + * in remote configuration, only the first is chosen. * @throws URISyntaxException * the location is not a remote defined in the configuration * file and is not a well-formed URL. @@ -93,6 +95,35 @@ public abstract class Transport { } /** + * Open new transport instances to connect two repositories. + * + * @param local + * existing local repository. + * @param remote + * location of the remote repository - may be URI or remote + * configuration name. + * @return the list of new transport instances for every URI in remote + * configuration. + * @throws URISyntaxException + * the location is not a remote defined in the configuration + * file and is not a well-formed URL. + * @throws NotSupportedException + * the protocol specified is not supported. + */ + public static List<Transport> openAll(final Repository local, + final String remote) throws NotSupportedException, + URISyntaxException { + final RemoteConfig cfg = new RemoteConfig(local.getConfig(), remote); + final List<URIish> uris = cfg.getURIs(); + if (uris.size() == 0) { + final ArrayList<Transport> transports = new ArrayList<Transport>(1); + transports.add(open(local, new URIish(remote))); + return transports; + } + return openAll(local, cfg); + } + + /** * Open a new transport instance to connect two repositories. * * @param local @@ -100,7 +131,8 @@ public abstract class Transport { * @param cfg * configuration describing how to connect to the remote * repository. - * @return the new transport instance. Never null. + * @return the new transport instance. Never null. In case of multiple URIs + * in remote configuration, only the first is chosen. * @throws NotSupportedException * the protocol specified is not supported. * @throws IllegalArgumentException @@ -114,15 +146,36 @@ public abstract class Transport { "Remote config \"" + cfg.getName() + "\" has no URIs associated"); final Transport tn = open(local, cfg.getURIs().get(0)); - tn.setOptionUploadPack(cfg.getUploadPack()); - tn.fetch = cfg.getFetchRefSpecs(); - tn.tagopt = cfg.getTagOpt(); - tn.setOptionReceivePack(cfg.getReceivePack()); - tn.push = cfg.getPushRefSpecs(); + tn.applyConfig(cfg); return tn; } /** + * Open new transport instances to connect two repositories. + * + * @param local + * existing local repository. + * @param cfg + * configuration describing how to connect to the remote + * repository. + * @return the list of new transport instances for every URI in remote + * configuration. + * @throws NotSupportedException + * the protocol specified is not supported. + */ + public static List<Transport> openAll(final Repository local, + final RemoteConfig cfg) throws NotSupportedException { + final List<URIish> uris = cfg.getURIs(); + final List<Transport> transports = new ArrayList<Transport>(uris.size()); + for (final URIish uri : uris) { + final Transport tn = open(local, uri); + tn.applyConfig(cfg); + transports.add(tn); + } + return transports; + } + + /** * Open a new transport instance to connect two repositories. * * @param local @@ -357,6 +410,20 @@ public abstract class Transport { public void setPushThin(final boolean pushThin) { this.pushThin = pushThin; } + + /** + * Apply provided remote configuration on this transport. + * + * @param cfg + * configuration to apply on this transport. + */ + public void applyConfig(final RemoteConfig cfg) { + setOptionUploadPack(cfg.getUploadPack()); + fetch = cfg.getFetchRefSpecs(); + setTagOpt(cfg.getTagOpt()); + optionReceivePack = cfg.getReceivePack(); + push = cfg.getPushRefSpecs(); + } /** * Fetch objects and refs from the remote repository to the local one. -- 1.5.6.3 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html