changeset 654:12a4f60ea972

1) Console push tool. 2) Pass class to blame into FileUtils
author Artem Tikhomirov <tikhomirov.artem@gmail.com>
date Wed, 03 Jul 2013 15:11:40 +0200
parents 629a7370554c
children bcbcc318f250
files cmdline/org/tmatesoft/hg/console/Push.java src/org/tmatesoft/hg/core/HgPushCommand.java src/org/tmatesoft/hg/core/HgRepoFacade.java src/org/tmatesoft/hg/internal/COWTransaction.java src/org/tmatesoft/hg/internal/CommitFacility.java src/org/tmatesoft/hg/internal/DataAccessProvider.java src/org/tmatesoft/hg/internal/FileContentSupplier.java src/org/tmatesoft/hg/internal/FileUtils.java src/org/tmatesoft/hg/internal/LineReader.java src/org/tmatesoft/hg/internal/PhasesHelper.java src/org/tmatesoft/hg/internal/RepositoryComparator.java src/org/tmatesoft/hg/repo/HgBranches.java src/org/tmatesoft/hg/repo/HgBundle.java src/org/tmatesoft/hg/repo/HgDataFile.java src/org/tmatesoft/hg/repo/HgRepository.java src/org/tmatesoft/hg/repo/HgWorkingCopyStatusCollector.java test/org/tmatesoft/hg/test/RepoUtils.java
diffstat 17 files changed, 91 insertions(+), 20 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cmdline/org/tmatesoft/hg/console/Push.java	Wed Jul 03 15:11:40 2013 +0200
@@ -0,0 +1,51 @@
+/*
+ * 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.console;
+
+import java.util.Collections;
+
+import org.tmatesoft.hg.core.HgPushCommand;
+import org.tmatesoft.hg.core.HgRepoFacade;
+import org.tmatesoft.hg.repo.HgLookup;
+import org.tmatesoft.hg.repo.HgRemoteRepository;
+
+/**
+ * 
+ * @author Artem Tikhomirov
+ * @author TMate Software Ltd.
+ */
+public class Push {
+
+	public static void main(String[] args) throws Exception {
+		Options cmdLineOpts = Options.parse(args, Collections.<String>emptySet());
+		HgRepoFacade hgRepo = new HgRepoFacade();
+		if (!hgRepo.init(cmdLineOpts.findRepository())) {
+			System.err.printf("Can't find repository in: %s\n", hgRepo.getRepository().getLocation());
+			return;
+		}
+		// XXX perhaps, HgRepoFacade shall get detectRemote() analog (to get remote server with respect of facade's repo)
+		HgRemoteRepository hgRemote = new HgLookup().detectRemote(cmdLineOpts.getSingle(""), hgRepo.getRepository());
+		if (hgRemote.isInvalid()) {
+			System.err.printf("Remote repository %s is not valid", hgRemote.getLocation());
+			return;
+		}
+		HgPushCommand cmd = hgRepo.createPushCommand();
+		cmd.destination(hgRemote);
+		cmd.execute();
+		System.out.printf("Added %d changesets\n", cmd.getPushedRevisions().size());
+	}
+}
--- a/src/org/tmatesoft/hg/core/HgPushCommand.java	Wed Jul 03 14:38:30 2013 +0200
+++ b/src/org/tmatesoft/hg/core/HgPushCommand.java	Wed Jul 03 15:11:40 2013 +0200
@@ -19,6 +19,8 @@
 import java.io.File;
 import java.io.IOException;
 import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
 import java.util.List;
 
 import org.tmatesoft.hg.internal.BundleGenerator;
@@ -52,6 +54,7 @@
 	
 	private final HgRepository repo;
 	private HgRemoteRepository remoteRepo;
+	private RevisionSet outgoing;
 
 	public HgPushCommand(HgRepository hgRepo) {
 		repo = hgRepo;
@@ -77,7 +80,6 @@
 			final RepositoryComparator comparator = new RepositoryComparator(parentHelper, remoteRepo);
 			comparator.compare(new ProgressSupport.Sub(progress, 50), getCancelSupport(null, true));
 			List<Nodeid> l = comparator.getLocalOnlyRevisions();
-			final RevisionSet outgoing;
 			if (phaseHelper.isCapableOfPhases() && phaseHelper.withSecretRoots()) {
 				RevisionSet secret = phaseHelper.allSecret();
 				outgoing = new RevisionSet(l).subtract(secret);
@@ -197,6 +199,10 @@
 		}
 	}
 	
+	public Collection<Nodeid> getPushedRevisions() {
+		return outgoing == null ? Collections.<Nodeid>emptyList() : outgoing.asList();
+	}
+	
 	private RevisionSet knownRemoteDrafts(HgRemoteRepository.Phases remotePhases, HgParentChildMap<HgChangelog> parentHelper, RevisionSet outgoing, RevisionSet localSecret) {
 		ArrayList<Nodeid> knownRemoteDraftRoots = new ArrayList<Nodeid>();
 		for (Nodeid rdr : remotePhases.draftRoots()) {
--- a/src/org/tmatesoft/hg/core/HgRepoFacade.java	Wed Jul 03 14:38:30 2013 +0200
+++ b/src/org/tmatesoft/hg/core/HgRepoFacade.java	Wed Jul 03 15:11:40 2013 +0200
@@ -165,4 +165,8 @@
 	public HgDiffCommand createDiffCommand() {
 		return new HgDiffCommand(repo);
 	}
+
+	public HgPushCommand createPushCommand() {
+		return new HgPushCommand(repo);
+	}
 }
--- a/src/org/tmatesoft/hg/internal/COWTransaction.java	Wed Jul 03 14:38:30 2013 +0200
+++ b/src/org/tmatesoft/hg/internal/COWTransaction.java	Wed Jul 03 15:11:40 2013 +0200
@@ -41,7 +41,7 @@
 	private final List<RollbackEntry> entries = new LinkedList<RollbackEntry>();
 	
 	public COWTransaction(SessionContext.Source ctxSource) {
-		fileHelper = new FileUtils(ctxSource.getSessionContext().getLog());
+		fileHelper = new FileUtils(ctxSource.getSessionContext().getLog(), this);
 	}
 
 	@Override
--- a/src/org/tmatesoft/hg/internal/CommitFacility.java	Wed Jul 03 14:38:30 2013 +0200
+++ b/src/org/tmatesoft/hg/internal/CommitFacility.java	Wed Jul 03 15:11:40 2013 +0200
@@ -258,7 +258,7 @@
 		} catch (IOException ex) {
 			throw new HgIOException("Failed to save last commit message", ex, lastMessage);
 		} finally {
-			new FileUtils(repo.getLog()).closeQuietly(w, lastMessage);
+			new FileUtils(repo.getLog(), this).closeQuietly(w, lastMessage);
 		}
 	}
 /*
--- a/src/org/tmatesoft/hg/internal/DataAccessProvider.java	Wed Jul 03 14:38:30 2013 +0200
+++ b/src/org/tmatesoft/hg/internal/DataAccessProvider.java	Wed Jul 03 15:11:40 2013 +0200
@@ -244,7 +244,7 @@
 		public void done() {
 			buffer = null;
 			if (fileStream != null) {
-				new FileUtils(logFacility).closeQuietly(fileStream);
+				new FileUtils(logFacility, this).closeQuietly(fileStream);
 				fileStream = null;
 				fileChannel = null; // channel is closed together with stream
 			}
@@ -375,7 +375,7 @@
 		public void done() {
 			buffer = null;
 			if (fileStream != null) {
-				new FileUtils(logFacility).closeQuietly(fileStream);
+				new FileUtils(logFacility, this).closeQuietly(fileStream);
 				fileStream = null;
 				fileChannel = null;
 			}
--- a/src/org/tmatesoft/hg/internal/FileContentSupplier.java	Wed Jul 03 14:38:30 2013 +0200
+++ b/src/org/tmatesoft/hg/internal/FileContentSupplier.java	Wed Jul 03 15:11:40 2013 +0200
@@ -62,7 +62,7 @@
 		} catch (IOException ex) {
 			throw new HgIOException("Failed to get content of the file", ex, file);
 		} finally {
-			new FileUtils(ctx.getLog()).closeQuietly(fis);
+			new FileUtils(ctx.getLog(), this).closeQuietly(fis);
 		}
 	}
 	
--- a/src/org/tmatesoft/hg/internal/FileUtils.java	Wed Jul 03 14:38:30 2013 +0200
+++ b/src/org/tmatesoft/hg/internal/FileUtils.java	Wed Jul 03 15:11:40 2013 +0200
@@ -37,13 +37,19 @@
 public final class FileUtils {
 	
 	private final LogFacility log;
+	private final Class<?> troublemaker;
 	
 	public static void copyFile(File from, File to) throws HgIOException {
-		new FileUtils(new StreamLogFacility(Debug, true, System.err)).copy(from, to);
+		new FileUtils(new StreamLogFacility(Debug, true, System.err), FileUtils.class).copy(from, to);
 	}
 
-	public FileUtils(LogFacility logFacility) {
+	public FileUtils(LogFacility logFacility, Object troubleSource) {
 		log = logFacility;
+		if (troubleSource == null) {
+			troublemaker = null;
+		} else {
+			troublemaker = troubleSource instanceof Class ? (Class<?>) troubleSource : troubleSource.getClass();
+		}
 	}
 
 	public void copy(File from, File to) throws HgIOException {
@@ -104,7 +110,7 @@
 				} else {
 					msg = String.format("Failed to close %s", f);
 				}
-				log.dump(getClass(), Severity.Warn, ex, msg);
+				log.dump(troublemaker == null ? getClass() : troublemaker, Severity.Warn, ex, msg);
 			}
 		}
 	}
--- a/src/org/tmatesoft/hg/internal/LineReader.java	Wed Jul 03 14:38:30 2013 +0200
+++ b/src/org/tmatesoft/hg/internal/LineReader.java	Wed Jul 03 15:11:40 2013 +0200
@@ -130,7 +130,7 @@
 			} catch (IOException ex) {
 				throw new HgIOException(ex.getMessage(), ex, file);
 			} finally {
-				new FileUtils(log).closeQuietly(statusFileReader);
+				new FileUtils(log, this).closeQuietly(statusFileReader);
 //				try {
 //					consumer.end(file, paramObj);
 //				} catch (IOException ex) {
--- a/src/org/tmatesoft/hg/internal/PhasesHelper.java	Wed Jul 03 14:38:30 2013 +0200
+++ b/src/org/tmatesoft/hg/internal/PhasesHelper.java	Wed Jul 03 15:11:40 2013 +0200
@@ -171,7 +171,7 @@
 		} catch (IOException ex) {
 			throw new HgInvalidControlFileException(ex.getMessage(), ex, phaseroots);
 		} finally {
-			new FileUtils(repo.getLog()).closeQuietly(fw);
+			new FileUtils(repo.getLog(), this).closeQuietly(fw);
 		}
 	}
 
--- a/src/org/tmatesoft/hg/internal/RepositoryComparator.java	Wed Jul 03 14:38:30 2013 +0200
+++ b/src/org/tmatesoft/hg/internal/RepositoryComparator.java	Wed Jul 03 15:11:40 2013 +0200
@@ -94,20 +94,24 @@
 		if (c.isEmpty()) {
 			return localRepo.all();
 		} else {
-			RevisionSet localHeads = new RevisionSet(localRepo.heads());
+			final RevisionSet rsCommon = new RevisionSet(c);
+			final RevisionSet localHeads = new RevisionSet(localRepo.heads());
 			final List<Nodeid> commonChildren = localRepo.childrenOf(c);
 			final RevisionSet rsCommonChildren = new RevisionSet(commonChildren);
-			RevisionSet headsNotFromCommon = localHeads.subtract(rsCommonChildren);
+			// check if there's any revision in the repository that doesn't trace to common
+			// e.g. branches from one of common ancestors
+			RevisionSet headsNotFromCommon = localHeads.subtract(rsCommonChildren).subtract(rsCommon);
 			if (headsNotFromCommon.isEmpty()) {
 				return commonChildren;
 			}
 			RevisionSet all = new RevisionSet(localRepo.all());
-			final RevisionSet rsCommon = new RevisionSet(c);
+			// need outgoing := ancestors(missing) - ancestors(common):
 			RevisionSet rsAncestors = all.ancestors(headsNotFromCommon, localRepo);
 			// #ancestors gives only parents, we need terminating children as well
 			rsAncestors = rsAncestors.union(headsNotFromCommon);
 			final RevisionSet rsAncestorsCommon = all.ancestors(rsCommon, localRepo);
 			RevisionSet outgoing = rsAncestors.subtract(rsAncestorsCommon).subtract(rsCommon);
+			// outgoing keeps children that spined off prior to common revisions
 			return outgoing.union(rsCommonChildren).asList();
 		}
 	}
--- a/src/org/tmatesoft/hg/repo/HgBranches.java	Wed Jul 03 14:38:30 2013 +0200
+++ b/src/org/tmatesoft/hg/repo/HgBranches.java	Wed Jul 03 15:11:40 2013 +0200
@@ -117,7 +117,7 @@
 			repo.getSessionContext().getLog().dump(getClass(), Error, ex, null);
 			// FALL THROUGH
 		} finally {
-			new FileUtils(repo.getSessionContext().getLog()).closeQuietly(br);
+			new FileUtils(repo.getSessionContext().getLog(), this).closeQuietly(br);
 		}
 		return -1; // deliberately not lastInCache, to avoid anything but -1 when 1st line was read and there's error is in lines 2..end
 	}
--- a/src/org/tmatesoft/hg/repo/HgBundle.java	Wed Jul 03 14:38:30 2013 +0200
+++ b/src/org/tmatesoft/hg/repo/HgBundle.java	Wed Jul 03 15:11:40 2013 +0200
@@ -554,7 +554,7 @@
 			} catch (IOException ex) {
 				throw new HgIOException("Failed to serialize bundle", HgBundle.this.bundleFile);
 			} finally {
-				new FileUtils(HgBundle.this.ctx.getLog()).closeQuietly(fis, HgBundle.this.bundleFile);
+				new FileUtils(HgBundle.this.ctx.getLog(), this).closeQuietly(fis, HgBundle.this.bundleFile);
 			}
 		}
 
--- a/src/org/tmatesoft/hg/repo/HgDataFile.java	Wed Jul 03 14:38:30 2013 +0200
+++ b/src/org/tmatesoft/hg/repo/HgDataFile.java	Wed Jul 03 15:11:40 2013 +0200
@@ -172,7 +172,7 @@
 			} finally {
 				progress.done();
 				if (fis != null) {
-					new FileUtils(getRepo().getSessionContext().getLog()).closeQuietly(fis);
+					new FileUtils(getRepo().getSessionContext().getLog(), this).closeQuietly(fis);
 				}
 			}
 		} else {
--- a/src/org/tmatesoft/hg/repo/HgRepository.java	Wed Jul 03 14:38:30 2013 +0200
+++ b/src/org/tmatesoft/hg/repo/HgRepository.java	Wed Jul 03 15:11:40 2013 +0200
@@ -373,7 +373,7 @@
 		} catch (IOException ex) {
 			throw new HgInvalidControlFileException("Can't retrieve message of last commit attempt", ex, lastMessage);
 		} finally {
-			new FileUtils(getSessionContext().getLog()).closeQuietly(fr, lastMessage);
+			new FileUtils(getSessionContext().getLog(), this).closeQuietly(fr, lastMessage);
 		}
 	}
 
--- a/src/org/tmatesoft/hg/repo/HgWorkingCopyStatusCollector.java	Wed Jul 03 14:38:30 2013 +0200
+++ b/src/org/tmatesoft/hg/repo/HgWorkingCopyStatusCollector.java	Wed Jul 03 15:11:40 2013 +0200
@@ -589,7 +589,7 @@
 		} catch (IOException ex) {
 			throw new HgInvalidFileException("File comparison failed", ex).setFileName(p);
 		} finally {
-			new FileUtils(repo.getSessionContext().getLog()).closeQuietly(is);
+			new FileUtils(repo.getSessionContext().getLog(), this).closeQuietly(is);
 		}
 	}
 
--- a/test/org/tmatesoft/hg/test/RepoUtils.java	Wed Jul 03 14:38:30 2013 +0200
+++ b/test/org/tmatesoft/hg/test/RepoUtils.java	Wed Jul 03 15:11:40 2013 +0200
@@ -115,7 +115,7 @@
 				throw new UnsupportedOperationException();
 			}
 		};
-		FileUtils fu = new FileUtils(new StreamLogFacility(Debug, true, System.err));
+		FileUtils fu = new FileUtils(new StreamLogFacility(Debug, true, System.err), RepoUtils.class);
 		String srcPrefix = srcDir.getAbsolutePath();
 		while (it.hasNext()) {
 			File next = it.next();