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) {