Mercurial > jhg
comparison src/org/tmatesoft/hg/repo/HgRemoteRepository.java @ 650:3b275cc2d2aa
Push: phase4 - settle local and remote phases, push updated phases regardless of server publishing state, do not push secret changesets
author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
---|---|
date | Fri, 28 Jun 2013 19:27:26 +0200 |
parents | e79cf9a8130b |
children | 6e98d34eaca8 |
comparison
equal
deleted
inserted
replaced
649:e79cf9a8130b | 650:3b275cc2d2aa |
---|---|
15 * contact TMate Software at support@hg4j.com | 15 * contact TMate Software at support@hg4j.com |
16 */ | 16 */ |
17 package org.tmatesoft.hg.repo; | 17 package org.tmatesoft.hg.repo; |
18 | 18 |
19 import static org.tmatesoft.hg.util.LogFacility.Severity.Info; | 19 import static org.tmatesoft.hg.util.LogFacility.Severity.Info; |
20 import static org.tmatesoft.hg.util.Outcome.Kind.Failure; | |
21 import static org.tmatesoft.hg.util.Outcome.Kind.Success; | |
20 | 22 |
21 import java.io.BufferedReader; | 23 import java.io.BufferedReader; |
22 import java.io.ByteArrayOutputStream; | 24 import java.io.ByteArrayOutputStream; |
23 import java.io.File; | 25 import java.io.File; |
24 import java.io.FileOutputStream; | 26 import java.io.FileOutputStream; |
60 import org.tmatesoft.hg.core.HgRemoteConnectionException; | 62 import org.tmatesoft.hg.core.HgRemoteConnectionException; |
61 import org.tmatesoft.hg.core.HgRepositoryNotFoundException; | 63 import org.tmatesoft.hg.core.HgRepositoryNotFoundException; |
62 import org.tmatesoft.hg.core.Nodeid; | 64 import org.tmatesoft.hg.core.Nodeid; |
63 import org.tmatesoft.hg.core.SessionContext; | 65 import org.tmatesoft.hg.core.SessionContext; |
64 import org.tmatesoft.hg.internal.DataSerializer; | 66 import org.tmatesoft.hg.internal.DataSerializer; |
67 import org.tmatesoft.hg.internal.DataSerializer.OutputStreamSerializer; | |
65 import org.tmatesoft.hg.internal.EncodingHelper; | 68 import org.tmatesoft.hg.internal.EncodingHelper; |
66 import org.tmatesoft.hg.internal.Internals; | 69 import org.tmatesoft.hg.internal.Internals; |
67 import org.tmatesoft.hg.internal.DataSerializer.OutputStreamSerializer; | |
68 import org.tmatesoft.hg.internal.PropertyMarshal; | 70 import org.tmatesoft.hg.internal.PropertyMarshal; |
71 import org.tmatesoft.hg.util.LogFacility.Severity; | |
69 import org.tmatesoft.hg.util.Outcome; | 72 import org.tmatesoft.hg.util.Outcome; |
70 import org.tmatesoft.hg.util.Pair; | 73 import org.tmatesoft.hg.util.Pair; |
71 import org.tmatesoft.hg.util.LogFacility.Severity; | |
72 import org.tmatesoft.hg.util.Outcome.Kind; | |
73 | 74 |
74 /** | 75 /** |
75 * WORK IN PROGRESS, DO NOT USE | 76 * WORK IN PROGRESS, DO NOT USE |
76 * | 77 * |
77 * @see http://mercurial.selenic.com/wiki/WireProtocol | 78 * @see http://mercurial.selenic.com/wiki/WireProtocol |
495 if (!remoteCapabilities.contains("pushkey")) { | 496 if (!remoteCapabilities.contains("pushkey")) { |
496 // old server defaults to publishing | 497 // old server defaults to publishing |
497 return new Phases(true, Collections.<Nodeid>emptyList()); | 498 return new Phases(true, Collections.<Nodeid>emptyList()); |
498 } | 499 } |
499 final List<Pair<String, String>> values = listkeys("phases", "Get remote phases"); | 500 final List<Pair<String, String>> values = listkeys("phases", "Get remote phases"); |
500 boolean publishing = true; | 501 boolean publishing = false; |
501 ArrayList<Nodeid> draftRoots = new ArrayList<Nodeid>(); | 502 ArrayList<Nodeid> draftRoots = new ArrayList<Nodeid>(); |
502 for (Pair<String, String> l : values) { | 503 for (Pair<String, String> l : values) { |
503 if ("publishing".equalsIgnoreCase(l.first())) { | 504 if ("publishing".equalsIgnoreCase(l.first())) { |
504 publishing = Boolean.parseBoolean(l.second()); | 505 publishing = Boolean.parseBoolean(l.second()); |
505 continue; | 506 continue; |
515 } | 516 } |
516 return new Phases(publishing, draftRoots); | 517 return new Phases(publishing, draftRoots); |
517 } | 518 } |
518 | 519 |
519 public Outcome updatePhase(HgPhase from, HgPhase to, Nodeid n) throws HgRemoteConnectionException, HgRuntimeException { | 520 public Outcome updatePhase(HgPhase from, HgPhase to, Nodeid n) throws HgRemoteConnectionException, HgRuntimeException { |
521 initCapabilities(); | |
522 if (!remoteCapabilities.contains("pushkey")) { | |
523 return new Outcome(Failure, "Server doesn't support pushkey protocol"); | |
524 } | |
520 if (pushkey("phases", n.toString(), String.valueOf(from.mercurialOrdinal()), String.valueOf(to.mercurialOrdinal()))) { | 525 if (pushkey("phases", n.toString(), String.valueOf(from.mercurialOrdinal()), String.valueOf(to.mercurialOrdinal()))) { |
521 return new Outcome(Kind.Success, String.format("Phase of %s updated to %s", n.shortNotation(), to.name())); | 526 return new Outcome(Success, String.format("Phase of %s updated to %s", n.shortNotation(), to.name())); |
522 } | 527 } |
523 return new Outcome(Kind.Failure, String.format("Phase update (%s: %s -> %s) failed", n.shortNotation(), from.name(), to.name())); | 528 return new Outcome(Failure, String.format("Phase update (%s: %s -> %s) failed", n.shortNotation(), from.name(), to.name())); |
524 } | 529 } |
525 | 530 |
526 | 531 |
527 public static void main(String[] args) throws Exception { | 532 public static void main(String[] args) throws Exception { |
528 final HgRemoteRepository r = new HgLookup().detectRemote("http://selenic.com/hg", null); | 533 final HgRemoteRepository r = new HgLookup().detectRemote("http://selenic.com/hg", null); |
630 } | 635 } |
631 | 636 |
632 private boolean pushkey(String namespace, String key, String oldValue, String newValue) throws HgRemoteConnectionException, HgRuntimeException { | 637 private boolean pushkey(String namespace, String key, String oldValue, String newValue) throws HgRemoteConnectionException, HgRuntimeException { |
633 HttpURLConnection c = null; | 638 HttpURLConnection c = null; |
634 try { | 639 try { |
635 final String p = String.format("%s?cmd=pushkey&namespace=%s&key=%s&old=%s&new=&s", url.getPath(), namespace, key, oldValue, newValue); | 640 final String p = String.format("%s?cmd=pushkey&namespace=%s&key=%s&old=%s&new=%s", url.getPath(), namespace, key, oldValue, newValue); |
636 URL u = new URL(url, p); | 641 URL u = new URL(url, p); |
637 c = setupConnection(u.openConnection()); | 642 c = setupConnection(u.openConnection()); |
643 c.setRequestMethod("POST"); | |
638 c.connect(); | 644 c.connect(); |
639 if (debug) { | 645 if (debug) { |
640 dumpResponseHeader(u, c); | 646 dumpResponseHeader(u, c); |
641 } | 647 } |
642 checkResponseOk(c, key, "pushkey"); | 648 checkResponseOk(c, key, "pushkey"); |
643 final InputStream is = c.getInputStream(); | 649 final InputStream is = c.getInputStream(); |
644 int rv = is.read(); | 650 int rv = is.read(); |
645 if (is.read() != -1) { | |
646 sessionContext.getLog().dump(getClass(), Severity.Error, "Unexpected data in response to pushkey"); | |
647 } | |
648 is.close(); | 651 is.close(); |
649 return rv == '1'; | 652 return rv == '1'; |
650 } catch (MalformedURLException ex) { | 653 } catch (MalformedURLException ex) { |
651 throw new HgRemoteConnectionException("Bad URL", ex).setRemoteCommand("pushkey").setServerInfo(getLocation()); | 654 throw new HgRemoteConnectionException("Bad URL", ex).setRemoteCommand("pushkey").setServerInfo(getLocation()); |
652 } catch (IOException ex) { | 655 } catch (IOException ex) { |