diff src/org/tmatesoft/hg/core/HgPullCommand.java @ 660:4fd317a2fecf

Pull: phase1 get remote changes and add local revisions
author Artem Tikhomirov <tikhomirov.artem@gmail.com>
date Tue, 09 Jul 2013 21:46:45 +0200
parents
children 46b56864b483
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/org/tmatesoft/hg/core/HgPullCommand.java	Tue Jul 09 21:46:45 2013 +0200
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2013 TMate Software Ltd
+ *  
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * For information on how to redistribute this software under
+ * the terms of a license other than GNU General Public License
+ * contact TMate Software at support@hg4j.com
+ */
+package org.tmatesoft.hg.core;
+
+import java.util.List;
+
+import org.tmatesoft.hg.internal.AddRevInspector;
+import org.tmatesoft.hg.internal.COWTransaction;
+import org.tmatesoft.hg.internal.Internals;
+import org.tmatesoft.hg.internal.PhasesHelper;
+import org.tmatesoft.hg.internal.RepositoryComparator;
+import org.tmatesoft.hg.internal.RevisionSet;
+import org.tmatesoft.hg.internal.Transaction;
+import org.tmatesoft.hg.repo.HgBundle;
+import org.tmatesoft.hg.repo.HgChangelog;
+import org.tmatesoft.hg.repo.HgInternals;
+import org.tmatesoft.hg.repo.HgParentChildMap;
+import org.tmatesoft.hg.repo.HgRemoteRepository;
+import org.tmatesoft.hg.repo.HgRepository;
+import org.tmatesoft.hg.repo.HgRuntimeException;
+import org.tmatesoft.hg.util.CancelledException;
+import org.tmatesoft.hg.util.ProgressSupport;
+
+/**
+ * 
+ * @author Artem Tikhomirov
+ * @author TMate Software Ltd.
+ */
+public class HgPullCommand extends HgAbstractCommand<HgPullCommand> {
+
+	private final HgRepository repo;
+	private HgRemoteRepository remote;
+
+	public HgPullCommand(HgRepository hgRepo) {
+		repo = hgRepo;
+	}
+
+	public HgPullCommand source(HgRemoteRepository hgRemote) {
+		remote = hgRemote;
+		return this;
+	}
+
+	public void execute() throws HgRemoteConnectionException, HgIOException, HgLibraryFailureException, CancelledException {
+		final ProgressSupport progress = getProgressSupport(null);
+		try {
+			progress.start(100);
+			// TODO refactor same code in HgIncomingCommand #getComparator and #getParentHelper
+			final HgChangelog clog = repo.getChangelog();
+			final HgParentChildMap<HgChangelog> parentHelper = new HgParentChildMap<HgChangelog>(clog);
+			parentHelper.init();
+			final RepositoryComparator comparator = new RepositoryComparator(parentHelper, remote);
+			// get incoming revisions
+			comparator.compare(new ProgressSupport.Sub(progress, 50), getCancelSupport(null, true));
+			final List<Nodeid> common = comparator.getCommon();
+			// get bundle with changes from remote
+			HgBundle incoming = remote.getChanges(common);
+			//
+			// add revisions to changelog, manifest, files
+			final Internals implRepo = HgInternals.getImplementationRepo(repo);
+			final AddRevInspector insp;
+			Transaction.Factory trFactory = new COWTransaction.Factory();
+			Transaction tr = trFactory.create(repo);
+			try {
+				incoming.inspectAll(insp = new AddRevInspector(implRepo, tr));
+				tr.commit();
+			} catch (HgRuntimeException ex) {
+				tr.rollback();
+				throw ex;
+			} catch (RuntimeException ex) {
+				tr.rollback();
+				throw ex;
+			}
+			progress.worked(45);
+			RevisionSet added = insp.addedChangesets();
+			
+			// get remote phases, update local phases to match that of remote
+			final PhasesHelper phaseHelper = new PhasesHelper(implRepo, parentHelper);
+			if (phaseHelper.isCapableOfPhases()) {
+				RevisionSet rsCommon = new RevisionSet(common);
+				HgRemoteRepository.Phases remotePhases = remote.getPhases();
+				if (remotePhases.isPublishingServer()) {
+					final RevisionSet knownPublic = rsCommon.union(added);
+					RevisionSet newDraft = phaseHelper.allDraft().subtract(knownPublic);
+					RevisionSet newSecret = phaseHelper.allSecret().subtract(knownPublic);
+					phaseHelper.updateRoots(newDraft.asList(), newSecret.asList());
+				} else {
+					// FIXME refactor reuse from HgPushCommand
+				}
+			}
+			progress.worked(5);
+		} catch (HgRuntimeException ex) {
+			throw new HgLibraryFailureException(ex);
+		} finally {
+			progress.done();
+		}
+	}
+}