comparison cmdline/org/tmatesoft/hg/console/Incoming.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 44a34baabea0
children 63c9fed4369e
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.console; 17 package org.tmatesoft.hg.console;
18 18
19 import java.util.ArrayList;
20 import java.util.Arrays; 19 import java.util.Arrays;
21 import java.util.Collections; 20 import java.util.Collections;
22 import java.util.Comparator; 21 import java.util.Comparator;
23 import java.util.HashSet; 22 import java.util.HashSet;
24 import java.util.Iterator; 23 import java.util.Iterator;
25 import java.util.LinkedHashMap; 24 import java.util.LinkedHashMap;
26 import java.util.LinkedHashSet; 25 import java.util.LinkedHashSet;
27 import java.util.LinkedList; 26 import java.util.LinkedList;
28 import java.util.List; 27 import java.util.List;
29 import java.util.ListIterator;
30 import java.util.Map.Entry; 28 import java.util.Map.Entry;
31 29
30 import org.tmatesoft.hg.console.Outgoing.ChangesetFormatter;
32 import org.tmatesoft.hg.core.HgBadStateException; 31 import org.tmatesoft.hg.core.HgBadStateException;
33 import org.tmatesoft.hg.core.HgException;
34 import org.tmatesoft.hg.core.Nodeid; 32 import org.tmatesoft.hg.core.Nodeid;
35 import org.tmatesoft.hg.internal.RepositoryComparator; 33 import org.tmatesoft.hg.internal.RepositoryComparator;
36 import org.tmatesoft.hg.internal.RepositoryComparator.BranchChain; 34 import org.tmatesoft.hg.internal.RepositoryComparator.BranchChain;
37 import org.tmatesoft.hg.repo.HgBundle; 35 import org.tmatesoft.hg.repo.HgBundle;
38 import org.tmatesoft.hg.repo.HgChangelog; 36 import org.tmatesoft.hg.repo.HgChangelog;
37 import org.tmatesoft.hg.repo.HgChangelog.RawChangeset;
39 import org.tmatesoft.hg.repo.HgLookup; 38 import org.tmatesoft.hg.repo.HgLookup;
40 import org.tmatesoft.hg.repo.HgRemoteRepository; 39 import org.tmatesoft.hg.repo.HgRemoteRepository;
41 import org.tmatesoft.hg.repo.HgRepository; 40 import org.tmatesoft.hg.repo.HgRepository;
42 import org.tmatesoft.hg.repo.HgChangelog.RawChangeset;
43 41
44 42
45 /** 43 /**
46 * WORK IN PROGRESS, DO NOT USE 44 * WORK IN PROGRESS, DO NOT USE
47 * hg incoming counterpart 45 * hg incoming counterpart
73 final HgChangelog.ParentWalker pw = hgRepo.getChangelog().new ParentWalker(); 71 final HgChangelog.ParentWalker pw = hgRepo.getChangelog().new ParentWalker();
74 pw.init(); 72 pw.init();
75 // 73 //
76 RepositoryComparator repoCompare = new RepositoryComparator(pw, hgRemote); 74 RepositoryComparator repoCompare = new RepositoryComparator(pw, hgRemote);
77 repoCompare.compare(null); 75 repoCompare.compare(null);
78 List<BranchChain> missingBranches0 = repoCompare.calculateMissingBranches(); 76 List<BranchChain> missingBranches = repoCompare.calculateMissingBranches();
79 final LinkedHashSet<Nodeid> common = new LinkedHashSet<Nodeid>(); 77 final LinkedHashSet<Nodeid> common = new LinkedHashSet<Nodeid>();
80 // XXX common can be obtained from repoCompare, but at the moment it would almost duplicate work of calculateMissingBranches 78 // XXX common can be obtained from repoCompare, but at the moment it would almost duplicate work of calculateMissingBranches
81 // once I refactor latter, common shall be taken from repoCompare. 79 // once I refactor latter, common shall be taken from repoCompare.
82 for (BranchChain bc : missingBranches0) { 80 for (BranchChain bc : missingBranches) {
83 bc.dump(); 81 bc.dump();
84 common.add(bc.branchRoot); // common known node 82 common.add(bc.branchRoot); // common known node
85 List<Nodeid> missing = visitBranches(repoCompare, bc); 83 List<Nodeid> missing = repoCompare.visitBranches(bc);
86 assert bc.branchRoot.equals(missing.get(0)); 84 assert bc.branchRoot.equals(missing.get(0));
87 missing.remove(0); 85 missing.remove(0);
88 Collections.reverse(missing); // useful to test output, from newer to older 86 Collections.reverse(missing); // useful to test output, from newer to older
89 System.out.println("Nodes to fetch in this branch:"); 87 System.out.println("Nodes to fetch in this branch:");
90 for (Nodeid n : missing) { 88 for (Nodeid n : missing) {
99 // 97 //
100 // Complete 98 // Complete
101 HgBundle changegroup = hgRemote.getChanges(new LinkedList<Nodeid>(common)); 99 HgBundle changegroup = hgRemote.getChanges(new LinkedList<Nodeid>(common));
102 changegroup.changes(hgRepo, new HgChangelog.Inspector() { 100 changegroup.changes(hgRepo, new HgChangelog.Inspector() {
103 private int localIndex; 101 private int localIndex;
102 private final ChangesetFormatter formatter = new ChangesetFormatter();
104 103
105 public void next(int revisionNumber, Nodeid nodeid, RawChangeset cset) { 104 public void next(int revisionNumber, Nodeid nodeid, RawChangeset cset) {
106 if (pw.knownNode(nodeid)) { 105 if (pw.knownNode(nodeid)) {
107 if (!common.contains(nodeid)) { 106 if (!common.contains(nodeid)) {
108 throw new HgBadStateException("Bundle shall not report known nodes other than roots we've supplied"); 107 throw new HgBadStateException("Bundle shall not report known nodes other than roots we've supplied");
109 } 108 }
110 localIndex = hgRepo.getChangelog().getLocalRevision(nodeid); 109 localIndex = hgRepo.getChangelog().getLocalRevision(nodeid);
111 return; 110 return;
112 } 111 }
113 System.out.printf("changeset: %d:%s\n", ++localIndex, nodeid.toString()); 112 System.out.println(formatter.simple(++localIndex, nodeid, cset));
114 System.out.printf("user: %s\n", cset.user());
115 System.out.printf("date: %s\n", cset.dateString());
116 System.out.printf("comment: %s\n\n", cset.comment());
117 } 113 }
118 }); 114 });
119 } 115 }
120 116
121 // returns in order from branch root to head
122 // for a non-empty BranchChain, shall return modifiable list
123 private static List<Nodeid> visitBranches(RepositoryComparator repoCompare, BranchChain bc) throws HgException {
124 if (bc == null) {
125 return Collections.emptyList();
126 }
127 List<Nodeid> mine = repoCompare.completeBranch(bc.branchRoot, bc.branchHead);
128 if (bc.isTerminal()) {
129 return mine;
130 }
131 List<Nodeid> parentBranch1 = visitBranches(repoCompare, bc.p1);
132 List<Nodeid> parentBranch2 = visitBranches(repoCompare, bc.p2);
133 // merge
134 LinkedList<Nodeid> merged = new LinkedList<Nodeid>();
135 ListIterator<Nodeid> i1 = parentBranch1.listIterator(), i2 = parentBranch2.listIterator();
136 while (i1.hasNext() && i2.hasNext()) {
137 Nodeid n1 = i1.next();
138 Nodeid n2 = i2.next();
139 if (n1.equals(n2)) {
140 merged.addLast(n1);
141 } else {
142 // first different => add both, and continue adding both tails sequentially
143 merged.add(n2);
144 merged.add(n1);
145 break;
146 }
147 }
148 // copy rest of second parent branch
149 while (i2.hasNext()) {
150 merged.add(i2.next());
151 }
152 // copy rest of first parent branch
153 while (i1.hasNext()) {
154 merged.add(i1.next());
155 }
156 //
157 ArrayList<Nodeid> rv = new ArrayList<Nodeid>(mine.size() + merged.size());
158 rv.addAll(merged);
159 rv.addAll(mine);
160 return rv;
161 }
162
163 117
164 private static class SequenceConstructor { 118 private static class SequenceConstructor {
165 119
166 private int[] between(int root, int head) { 120 private int[] between(int root, int head) {
167 if (head <= (root+1)) { 121 if (head <= (root+1)) {