comparison src/org/tmatesoft/hg/core/HgIncomingCommand.java @ 192:e5407b5a586a

Incoming and Outgoing commands are alive
author Artem Tikhomirov <tikhomirov.artem@gmail.com>
date Fri, 15 Apr 2011 03:17:03 +0200
parents cd3371670f0b
children 344e8d7e4d6e
comparison
equal deleted inserted replaced
191:b777502a06f5 192:e5407b5a586a
14 * the terms of a license other than GNU General Public License 14 * the terms of a license other than GNU General Public License
15 * contact TMate Software at support@hg4j.com 15 * contact TMate Software at support@hg4j.com
16 */ 16 */
17 package org.tmatesoft.hg.core; 17 package org.tmatesoft.hg.core;
18 18
19 import java.io.IOException;
20 import java.util.ArrayList;
21 import java.util.LinkedHashSet;
22 import java.util.LinkedList;
19 import java.util.List; 23 import java.util.List;
20 24
25 import org.tmatesoft.hg.internal.RepositoryComparator;
26 import org.tmatesoft.hg.internal.RepositoryComparator.BranchChain;
27 import org.tmatesoft.hg.repo.HgBundle;
28 import org.tmatesoft.hg.repo.HgChangelog;
29 import org.tmatesoft.hg.repo.HgChangelog.RawChangeset;
30 import org.tmatesoft.hg.repo.HgRemoteRepository;
21 import org.tmatesoft.hg.repo.HgRepository; 31 import org.tmatesoft.hg.repo.HgRepository;
22 import org.tmatesoft.hg.util.CancelledException; 32 import org.tmatesoft.hg.util.CancelledException;
23 33
24 /** 34 /**
25 * 35 * Command to find out changes available in a remote repository, missing locally.
36 *
26 * @author Artem Tikhomirov 37 * @author Artem Tikhomirov
27 * @author TMate Software Ltd. 38 * @author TMate Software Ltd.
28 */ 39 */
29 public class HgIncomingCommand { 40 public class HgIncomingCommand {
30 41
31 private final HgRepository repo; 42 private final HgRepository localRepo;
43 private HgRemoteRepository remoteRepo;
32 private boolean includeSubrepo; 44 private boolean includeSubrepo;
45 private RepositoryComparator comparator;
46 private List<BranchChain> missingBranches;
47 private HgChangelog.ParentWalker parentHelper;
33 48
34 public HgIncomingCommand(HgRepository hgRepo) { 49 public HgIncomingCommand(HgRepository hgRepo) {
35 repo = hgRepo; 50 localRepo = hgRepo;
51 }
52
53 public HgIncomingCommand against(HgRemoteRepository hgRemote) {
54 remoteRepo = hgRemote;
55 comparator = null;
56 missingBranches = null;
57 return this;
36 } 58 }
37 59
38 /** 60 /**
61 * PLACEHOLDER, NOT IMPLEMENTED YET.
62 *
39 * Select specific branch to pull 63 * Select specific branch to pull
40 * @return <code>this</code> for convenience 64 * @return <code>this</code> for convenience
41 */ 65 */
42 public HgIncomingCommand branch(String branch) { 66 public HgIncomingCommand branch(String branch) {
43 throw HgRepository.notImplemented(); 67 throw HgRepository.notImplemented();
44 } 68 }
45 69
46 /** 70 /**
71 * PLACEHOLDER, NOT IMPLEMENTED YET.
72 *
47 * Whether to include sub-repositories when collecting changes, default is <code>true</code> XXX or false? 73 * Whether to include sub-repositories when collecting changes, default is <code>true</code> XXX or false?
48 * @return <code>this</code> for convenience 74 * @return <code>this</code> for convenience
49 */ 75 */
50 public HgIncomingCommand subrepo(boolean include) { 76 public HgIncomingCommand subrepo(boolean include) {
51 includeSubrepo = include; 77 includeSubrepo = include;
59 * @return list of nodes present at remote and missing locally 85 * @return list of nodes present at remote and missing locally
60 * @throws HgException 86 * @throws HgException
61 * @throws CancelledException 87 * @throws CancelledException
62 */ 88 */
63 public List<Nodeid> executeLite(Object context) throws HgException, CancelledException { 89 public List<Nodeid> executeLite(Object context) throws HgException, CancelledException {
64 throw HgRepository.notImplemented(); 90 LinkedHashSet<Nodeid> result = new LinkedHashSet<Nodeid>();
91 RepositoryComparator repoCompare = getComparator(context);
92 for (BranchChain bc : getMissingBranches(context)) {
93 List<Nodeid> missing = repoCompare.visitBranches(bc);
94 assert bc.branchRoot.equals(missing.get(0));
95 missing.remove(0);
96 result.addAll(missing);
97 }
98 ArrayList<Nodeid> rv = new ArrayList<Nodeid>(result);
99 return rv;
65 } 100 }
66 101
67 /** 102 /**
68 * Full information about incoming changes 103 * Full information about incoming changes
69 * 104 *
70 * @throws HgException 105 * @throws HgException
71 * @throws CancelledException 106 * @throws CancelledException
72 */ 107 */
73 public void executeFull(HgLogCommand.Handler handler) throws HgException, CancelledException { 108 public void executeFull(final HgLogCommand.Handler handler) throws HgException, CancelledException {
74 throw HgRepository.notImplemented(); 109 if (handler == null) {
110 throw new IllegalArgumentException("Delegate can't be null");
111 }
112 final List<Nodeid> common = getCommon(handler);
113 HgBundle changegroup = remoteRepo.getChanges(new LinkedList<Nodeid>(common));
114 try {
115 changegroup.changes(localRepo, new HgChangelog.Inspector() {
116 private int localIndex;
117 private final HgChangelog.ParentWalker parentHelper;
118 private final ChangesetTransformer transformer;
119 private final HgChangelog changelog;
120
121 {
122 transformer = new ChangesetTransformer(localRepo, handler);
123 parentHelper = getParentHelper();
124 changelog = localRepo.getChangelog();
125 }
126
127 public void next(int revisionNumber, Nodeid nodeid, RawChangeset cset) {
128 if (parentHelper.knownNode(nodeid)) {
129 if (!common.contains(nodeid)) {
130 throw new HgBadStateException("Bundle shall not report known nodes other than roots we've supplied");
131 }
132 localIndex = changelog.getLocalRevision(nodeid);
133 return;
134 }
135 transformer.next(++localIndex, nodeid, cset);
136 }
137 });
138 } catch (IOException ex) {
139 throw new HgException(ex);
140 }
141 }
142
143 private RepositoryComparator getComparator(Object context) throws HgException, CancelledException {
144 if (remoteRepo == null) {
145 throw new HgBadArgumentException("Shall specify remote repository to compare against", null);
146 }
147 if (comparator == null) {
148 comparator = new RepositoryComparator(getParentHelper(), remoteRepo);
149 comparator.compare(context);
150 }
151 return comparator;
152 }
153
154 private HgChangelog.ParentWalker getParentHelper() {
155 if (parentHelper == null) {
156 parentHelper = localRepo.getChangelog().new ParentWalker();
157 parentHelper.init();
158 }
159 return parentHelper;
160 }
161
162 private List<BranchChain> getMissingBranches(Object context) throws HgException, CancelledException {
163 if (missingBranches == null) {
164 missingBranches = getComparator(context).calculateMissingBranches();
165 }
166 return missingBranches;
167 }
168
169 private List<Nodeid> getCommon(Object context) throws HgException, CancelledException {
170 final LinkedHashSet<Nodeid> common = new LinkedHashSet<Nodeid>();
171 // XXX common can be obtained from repoCompare, but at the moment it would almost duplicate work of calculateMissingBranches
172 // once I refactor latter, common shall be taken from repoCompare.
173 for (BranchChain bc : getMissingBranches(context)) {
174 common.add(bc.branchRoot);
175 }
176 return new LinkedList<Nodeid>(common);
75 } 177 }
76 } 178 }