##// END OF EJS Templates
discovery: slowly increase sampling size...
marmoute -
r42546:dbd0fcca default
parent child Browse files
Show More
@@ -1,436 +1,439
1 # setdiscovery.py - improved discovery of common nodeset for mercurial
1 # setdiscovery.py - improved discovery of common nodeset for mercurial
2 #
2 #
3 # Copyright 2010 Benoit Boissinot <bboissin@gmail.com>
3 # Copyright 2010 Benoit Boissinot <bboissin@gmail.com>
4 # and Peter Arrenbrecht <peter@arrenbrecht.ch>
4 # and Peter Arrenbrecht <peter@arrenbrecht.ch>
5 #
5 #
6 # This software may be used and distributed according to the terms of the
6 # This software may be used and distributed according to the terms of the
7 # GNU General Public License version 2 or any later version.
7 # GNU General Public License version 2 or any later version.
8 """
8 """
9 Algorithm works in the following way. You have two repository: local and
9 Algorithm works in the following way. You have two repository: local and
10 remote. They both contains a DAG of changelists.
10 remote. They both contains a DAG of changelists.
11
11
12 The goal of the discovery protocol is to find one set of node *common*,
12 The goal of the discovery protocol is to find one set of node *common*,
13 the set of nodes shared by local and remote.
13 the set of nodes shared by local and remote.
14
14
15 One of the issue with the original protocol was latency, it could
15 One of the issue with the original protocol was latency, it could
16 potentially require lots of roundtrips to discover that the local repo was a
16 potentially require lots of roundtrips to discover that the local repo was a
17 subset of remote (which is a very common case, you usually have few changes
17 subset of remote (which is a very common case, you usually have few changes
18 compared to upstream, while upstream probably had lots of development).
18 compared to upstream, while upstream probably had lots of development).
19
19
20 The new protocol only requires one interface for the remote repo: `known()`,
20 The new protocol only requires one interface for the remote repo: `known()`,
21 which given a set of changelists tells you if they are present in the DAG.
21 which given a set of changelists tells you if they are present in the DAG.
22
22
23 The algorithm then works as follow:
23 The algorithm then works as follow:
24
24
25 - We will be using three sets, `common`, `missing`, `unknown`. Originally
25 - We will be using three sets, `common`, `missing`, `unknown`. Originally
26 all nodes are in `unknown`.
26 all nodes are in `unknown`.
27 - Take a sample from `unknown`, call `remote.known(sample)`
27 - Take a sample from `unknown`, call `remote.known(sample)`
28 - For each node that remote knows, move it and all its ancestors to `common`
28 - For each node that remote knows, move it and all its ancestors to `common`
29 - For each node that remote doesn't know, move it and all its descendants
29 - For each node that remote doesn't know, move it and all its descendants
30 to `missing`
30 to `missing`
31 - Iterate until `unknown` is empty
31 - Iterate until `unknown` is empty
32
32
33 There are a couple optimizations, first is instead of starting with a random
33 There are a couple optimizations, first is instead of starting with a random
34 sample of missing, start by sending all heads, in the case where the local
34 sample of missing, start by sending all heads, in the case where the local
35 repo is a subset, you computed the answer in one round trip.
35 repo is a subset, you computed the answer in one round trip.
36
36
37 Then you can do something similar to the bisecting strategy used when
37 Then you can do something similar to the bisecting strategy used when
38 finding faulty changesets. Instead of random samples, you can try picking
38 finding faulty changesets. Instead of random samples, you can try picking
39 nodes that will maximize the number of nodes that will be
39 nodes that will maximize the number of nodes that will be
40 classified with it (since all ancestors or descendants will be marked as well).
40 classified with it (since all ancestors or descendants will be marked as well).
41 """
41 """
42
42
43 from __future__ import absolute_import
43 from __future__ import absolute_import
44
44
45 import collections
45 import collections
46 import random
46 import random
47
47
48 from .i18n import _
48 from .i18n import _
49 from .node import (
49 from .node import (
50 nullid,
50 nullid,
51 nullrev,
51 nullrev,
52 )
52 )
53 from . import (
53 from . import (
54 error,
54 error,
55 util,
55 util,
56 )
56 )
57
57
58 def _updatesample(revs, heads, sample, parentfn, quicksamplesize=0):
58 def _updatesample(revs, heads, sample, parentfn, quicksamplesize=0):
59 """update an existing sample to match the expected size
59 """update an existing sample to match the expected size
60
60
61 The sample is updated with revs exponentially distant from each head of the
61 The sample is updated with revs exponentially distant from each head of the
62 <revs> set. (H~1, H~2, H~4, H~8, etc).
62 <revs> set. (H~1, H~2, H~4, H~8, etc).
63
63
64 If a target size is specified, the sampling will stop once this size is
64 If a target size is specified, the sampling will stop once this size is
65 reached. Otherwise sampling will happen until roots of the <revs> set are
65 reached. Otherwise sampling will happen until roots of the <revs> set are
66 reached.
66 reached.
67
67
68 :revs: set of revs we want to discover (if None, assume the whole dag)
68 :revs: set of revs we want to discover (if None, assume the whole dag)
69 :heads: set of DAG head revs
69 :heads: set of DAG head revs
70 :sample: a sample to update
70 :sample: a sample to update
71 :parentfn: a callable to resolve parents for a revision
71 :parentfn: a callable to resolve parents for a revision
72 :quicksamplesize: optional target size of the sample"""
72 :quicksamplesize: optional target size of the sample"""
73 dist = {}
73 dist = {}
74 visit = collections.deque(heads)
74 visit = collections.deque(heads)
75 seen = set()
75 seen = set()
76 factor = 1
76 factor = 1
77 while visit:
77 while visit:
78 curr = visit.popleft()
78 curr = visit.popleft()
79 if curr in seen:
79 if curr in seen:
80 continue
80 continue
81 d = dist.setdefault(curr, 1)
81 d = dist.setdefault(curr, 1)
82 if d > factor:
82 if d > factor:
83 factor *= 2
83 factor *= 2
84 if d == factor:
84 if d == factor:
85 sample.add(curr)
85 sample.add(curr)
86 if quicksamplesize and (len(sample) >= quicksamplesize):
86 if quicksamplesize and (len(sample) >= quicksamplesize):
87 return
87 return
88 seen.add(curr)
88 seen.add(curr)
89
89
90 for p in parentfn(curr):
90 for p in parentfn(curr):
91 if p != nullrev and (not revs or p in revs):
91 if p != nullrev and (not revs or p in revs):
92 dist.setdefault(p, d + 1)
92 dist.setdefault(p, d + 1)
93 visit.append(p)
93 visit.append(p)
94
94
95 def _limitsample(sample, desiredlen):
95 def _limitsample(sample, desiredlen):
96 """return a random subset of sample of at most desiredlen item"""
96 """return a random subset of sample of at most desiredlen item"""
97 if len(sample) > desiredlen:
97 if len(sample) > desiredlen:
98 sample = set(random.sample(sample, desiredlen))
98 sample = set(random.sample(sample, desiredlen))
99 return sample
99 return sample
100
100
101 class partialdiscovery(object):
101 class partialdiscovery(object):
102 """an object representing ongoing discovery
102 """an object representing ongoing discovery
103
103
104 Feed with data from the remote repository, this object keep track of the
104 Feed with data from the remote repository, this object keep track of the
105 current set of changeset in various states:
105 current set of changeset in various states:
106
106
107 - common: revs also known remotely
107 - common: revs also known remotely
108 - undecided: revs we don't have information on yet
108 - undecided: revs we don't have information on yet
109 - missing: revs missing remotely
109 - missing: revs missing remotely
110 (all tracked revisions are known locally)
110 (all tracked revisions are known locally)
111 """
111 """
112
112
113 def __init__(self, repo, targetheads):
113 def __init__(self, repo, targetheads):
114 self._repo = repo
114 self._repo = repo
115 self._targetheads = targetheads
115 self._targetheads = targetheads
116 self._common = repo.changelog.incrementalmissingrevs()
116 self._common = repo.changelog.incrementalmissingrevs()
117 self._undecided = None
117 self._undecided = None
118 self.missing = set()
118 self.missing = set()
119 self._childrenmap = None
119 self._childrenmap = None
120
120
121 def addcommons(self, commons):
121 def addcommons(self, commons):
122 """register nodes known as common"""
122 """register nodes known as common"""
123 self._common.addbases(commons)
123 self._common.addbases(commons)
124 if self._undecided is not None:
124 if self._undecided is not None:
125 self._common.removeancestorsfrom(self._undecided)
125 self._common.removeancestorsfrom(self._undecided)
126
126
127 def addmissings(self, missings):
127 def addmissings(self, missings):
128 """register some nodes as missing"""
128 """register some nodes as missing"""
129 newmissing = self._repo.revs('%ld::%ld', missings, self.undecided)
129 newmissing = self._repo.revs('%ld::%ld', missings, self.undecided)
130 if newmissing:
130 if newmissing:
131 self.missing.update(newmissing)
131 self.missing.update(newmissing)
132 self.undecided.difference_update(newmissing)
132 self.undecided.difference_update(newmissing)
133
133
134 def addinfo(self, sample):
134 def addinfo(self, sample):
135 """consume an iterable of (rev, known) tuples"""
135 """consume an iterable of (rev, known) tuples"""
136 common = set()
136 common = set()
137 missing = set()
137 missing = set()
138 for rev, known in sample:
138 for rev, known in sample:
139 if known:
139 if known:
140 common.add(rev)
140 common.add(rev)
141 else:
141 else:
142 missing.add(rev)
142 missing.add(rev)
143 if common:
143 if common:
144 self.addcommons(common)
144 self.addcommons(common)
145 if missing:
145 if missing:
146 self.addmissings(missing)
146 self.addmissings(missing)
147
147
148 def hasinfo(self):
148 def hasinfo(self):
149 """return True is we have any clue about the remote state"""
149 """return True is we have any clue about the remote state"""
150 return self._common.hasbases()
150 return self._common.hasbases()
151
151
152 def iscomplete(self):
152 def iscomplete(self):
153 """True if all the necessary data have been gathered"""
153 """True if all the necessary data have been gathered"""
154 return self._undecided is not None and not self._undecided
154 return self._undecided is not None and not self._undecided
155
155
156 @property
156 @property
157 def undecided(self):
157 def undecided(self):
158 if self._undecided is not None:
158 if self._undecided is not None:
159 return self._undecided
159 return self._undecided
160 self._undecided = set(self._common.missingancestors(self._targetheads))
160 self._undecided = set(self._common.missingancestors(self._targetheads))
161 return self._undecided
161 return self._undecided
162
162
163 def stats(self):
163 def stats(self):
164 return {
164 return {
165 'undecided': len(self.undecided),
165 'undecided': len(self.undecided),
166 }
166 }
167
167
168 def commonheads(self):
168 def commonheads(self):
169 """the heads of the known common set"""
169 """the heads of the known common set"""
170 # heads(common) == heads(common.bases) since common represents
170 # heads(common) == heads(common.bases) since common represents
171 # common.bases and all its ancestors
171 # common.bases and all its ancestors
172 return self._common.basesheads()
172 return self._common.basesheads()
173
173
174 def _parentsgetter(self):
174 def _parentsgetter(self):
175 getrev = self._repo.changelog.index.__getitem__
175 getrev = self._repo.changelog.index.__getitem__
176 def getparents(r):
176 def getparents(r):
177 return getrev(r)[5:7]
177 return getrev(r)[5:7]
178 return getparents
178 return getparents
179
179
180 def _childrengetter(self):
180 def _childrengetter(self):
181
181
182 if self._childrenmap is not None:
182 if self._childrenmap is not None:
183 # During discovery, the `undecided` set keep shrinking.
183 # During discovery, the `undecided` set keep shrinking.
184 # Therefore, the map computed for an iteration N will be
184 # Therefore, the map computed for an iteration N will be
185 # valid for iteration N+1. Instead of computing the same
185 # valid for iteration N+1. Instead of computing the same
186 # data over and over we cached it the first time.
186 # data over and over we cached it the first time.
187 return self._childrenmap.__getitem__
187 return self._childrenmap.__getitem__
188
188
189 # _updatesample() essentially does interaction over revisions to look
189 # _updatesample() essentially does interaction over revisions to look
190 # up their children. This lookup is expensive and doing it in a loop is
190 # up their children. This lookup is expensive and doing it in a loop is
191 # quadratic. We precompute the children for all relevant revisions and
191 # quadratic. We precompute the children for all relevant revisions and
192 # make the lookup in _updatesample() a simple dict lookup.
192 # make the lookup in _updatesample() a simple dict lookup.
193 self._childrenmap = children = {}
193 self._childrenmap = children = {}
194
194
195 parentrevs = self._parentsgetter()
195 parentrevs = self._parentsgetter()
196 revs = self.undecided
196 revs = self.undecided
197
197
198 for rev in sorted(revs):
198 for rev in sorted(revs):
199 # Always ensure revision has an entry so we don't need to worry
199 # Always ensure revision has an entry so we don't need to worry
200 # about missing keys.
200 # about missing keys.
201 children[rev] = []
201 children[rev] = []
202 for prev in parentrevs(rev):
202 for prev in parentrevs(rev):
203 if prev == nullrev:
203 if prev == nullrev:
204 continue
204 continue
205 c = children.get(prev)
205 c = children.get(prev)
206 if c is not None:
206 if c is not None:
207 c.append(rev)
207 c.append(rev)
208 return children.__getitem__
208 return children.__getitem__
209
209
210 def takequicksample(self, headrevs, size):
210 def takequicksample(self, headrevs, size):
211 """takes a quick sample of size <size>
211 """takes a quick sample of size <size>
212
212
213 It is meant for initial sampling and focuses on querying heads and close
213 It is meant for initial sampling and focuses on querying heads and close
214 ancestors of heads.
214 ancestors of heads.
215
215
216 :headrevs: set of head revisions in local DAG to consider
216 :headrevs: set of head revisions in local DAG to consider
217 :size: the maximum size of the sample"""
217 :size: the maximum size of the sample"""
218 revs = self.undecided
218 revs = self.undecided
219 if len(revs) <= size:
219 if len(revs) <= size:
220 return list(revs)
220 return list(revs)
221 sample = set(self._repo.revs('heads(%ld)', revs))
221 sample = set(self._repo.revs('heads(%ld)', revs))
222
222
223 if len(sample) >= size:
223 if len(sample) >= size:
224 return _limitsample(sample, size)
224 return _limitsample(sample, size)
225
225
226 _updatesample(None, headrevs, sample, self._parentsgetter(),
226 _updatesample(None, headrevs, sample, self._parentsgetter(),
227 quicksamplesize=size)
227 quicksamplesize=size)
228 return sample
228 return sample
229
229
230 def takefullsample(self, headrevs, size):
230 def takefullsample(self, headrevs, size):
231 revs = self.undecided
231 revs = self.undecided
232 if len(revs) <= size:
232 if len(revs) <= size:
233 return list(revs)
233 return list(revs)
234 repo = self._repo
234 repo = self._repo
235 sample = set(repo.revs('heads(%ld)', revs))
235 sample = set(repo.revs('heads(%ld)', revs))
236 parentrevs = self._parentsgetter()
236 parentrevs = self._parentsgetter()
237
237
238 # update from heads
238 # update from heads
239 revsheads = sample.copy()
239 revsheads = sample.copy()
240 _updatesample(revs, revsheads, sample, parentrevs)
240 _updatesample(revs, revsheads, sample, parentrevs)
241
241
242 # update from roots
242 # update from roots
243 revsroots = set(repo.revs('roots(%ld)', revs))
243 revsroots = set(repo.revs('roots(%ld)', revs))
244
244
245 childrenrevs = self._childrengetter()
245 childrenrevs = self._childrengetter()
246
246
247 _updatesample(revs, revsroots, sample, childrenrevs)
247 _updatesample(revs, revsroots, sample, childrenrevs)
248 assert sample
248 assert sample
249 sample = _limitsample(sample, size)
249 sample = _limitsample(sample, size)
250 if len(sample) < size:
250 if len(sample) < size:
251 more = size - len(sample)
251 more = size - len(sample)
252 sample.update(random.sample(list(revs - sample), more))
252 sample.update(random.sample(list(revs - sample), more))
253 return sample
253 return sample
254
254
255 def findcommonheads(ui, local, remote,
255 def findcommonheads(ui, local, remote,
256 initialsamplesize=100,
256 initialsamplesize=100,
257 fullsamplesize=200,
257 fullsamplesize=200,
258 abortwhenunrelated=True,
258 abortwhenunrelated=True,
259 ancestorsof=None):
259 ancestorsof=None,
260 samplegrowth=1.05):
260 '''Return a tuple (common, anyincoming, remoteheads) used to identify
261 '''Return a tuple (common, anyincoming, remoteheads) used to identify
261 missing nodes from or in remote.
262 missing nodes from or in remote.
262 '''
263 '''
263 start = util.timer()
264 start = util.timer()
264
265
265 roundtrips = 0
266 roundtrips = 0
266 cl = local.changelog
267 cl = local.changelog
267 clnode = cl.node
268 clnode = cl.node
268 clrev = cl.rev
269 clrev = cl.rev
269
270
270 if ancestorsof is not None:
271 if ancestorsof is not None:
271 ownheads = [clrev(n) for n in ancestorsof]
272 ownheads = [clrev(n) for n in ancestorsof]
272 else:
273 else:
273 ownheads = [rev for rev in cl.headrevs() if rev != nullrev]
274 ownheads = [rev for rev in cl.headrevs() if rev != nullrev]
274
275
275 # early exit if we know all the specified remote heads already
276 # early exit if we know all the specified remote heads already
276 ui.debug("query 1; heads\n")
277 ui.debug("query 1; heads\n")
277 roundtrips += 1
278 roundtrips += 1
278 # We also ask remote about all the local heads. That set can be arbitrarily
279 # We also ask remote about all the local heads. That set can be arbitrarily
279 # large, so we used to limit it size to `initialsamplesize`. We no longer
280 # large, so we used to limit it size to `initialsamplesize`. We no longer
280 # do as it proved counter productive. The skipped heads could lead to a
281 # do as it proved counter productive. The skipped heads could lead to a
281 # large "undecided" set, slower to be clarified than if we asked the
282 # large "undecided" set, slower to be clarified than if we asked the
282 # question for all heads right away.
283 # question for all heads right away.
283 #
284 #
284 # We are already fetching all server heads using the `heads` commands,
285 # We are already fetching all server heads using the `heads` commands,
285 # sending a equivalent number of heads the other way should not have a
286 # sending a equivalent number of heads the other way should not have a
286 # significant impact. In addition, it is very likely that we are going to
287 # significant impact. In addition, it is very likely that we are going to
287 # have to issue "known" request for an equivalent amount of revisions in
288 # have to issue "known" request for an equivalent amount of revisions in
288 # order to decide if theses heads are common or missing.
289 # order to decide if theses heads are common or missing.
289 #
290 #
290 # find a detailled analysis below.
291 # find a detailled analysis below.
291 #
292 #
292 # Case A: local and server both has few heads
293 # Case A: local and server both has few heads
293 #
294 #
294 # Ownheads is below initialsamplesize, limit would not have any effect.
295 # Ownheads is below initialsamplesize, limit would not have any effect.
295 #
296 #
296 # Case B: local has few heads and server has many
297 # Case B: local has few heads and server has many
297 #
298 #
298 # Ownheads is below initialsamplesize, limit would not have any effect.
299 # Ownheads is below initialsamplesize, limit would not have any effect.
299 #
300 #
300 # Case C: local and server both has many heads
301 # Case C: local and server both has many heads
301 #
302 #
302 # We now transfert some more data, but not significantly more than is
303 # We now transfert some more data, but not significantly more than is
303 # already transfered to carry the server heads.
304 # already transfered to carry the server heads.
304 #
305 #
305 # Case D: local has many heads, server has few
306 # Case D: local has many heads, server has few
306 #
307 #
307 # D.1 local heads are mostly known remotely
308 # D.1 local heads are mostly known remotely
308 #
309 #
309 # All the known head will have be part of a `known` request at some
310 # All the known head will have be part of a `known` request at some
310 # point for the discovery to finish. Sending them all earlier is
311 # point for the discovery to finish. Sending them all earlier is
311 # actually helping.
312 # actually helping.
312 #
313 #
313 # (This case is fairly unlikely, it requires the numerous heads to all
314 # (This case is fairly unlikely, it requires the numerous heads to all
314 # be merged server side in only a few heads)
315 # be merged server side in only a few heads)
315 #
316 #
316 # D.2 local heads are mostly missing remotely
317 # D.2 local heads are mostly missing remotely
317 #
318 #
318 # To determine that the heads are missing, we'll have to issue `known`
319 # To determine that the heads are missing, we'll have to issue `known`
319 # request for them or one of their ancestors. This amount of `known`
320 # request for them or one of their ancestors. This amount of `known`
320 # request will likely be in the same order of magnitude than the amount
321 # request will likely be in the same order of magnitude than the amount
321 # of local heads.
322 # of local heads.
322 #
323 #
323 # The only case where we can be more efficient using `known` request on
324 # The only case where we can be more efficient using `known` request on
324 # ancestors are case were all the "missing" local heads are based on a
325 # ancestors are case were all the "missing" local heads are based on a
325 # few changeset, also "missing". This means we would have a "complex"
326 # few changeset, also "missing". This means we would have a "complex"
326 # graph (with many heads) attached to, but very independant to a the
327 # graph (with many heads) attached to, but very independant to a the
327 # "simple" graph on the server. This is a fairly usual case and have
328 # "simple" graph on the server. This is a fairly usual case and have
328 # not been met in the wild so far.
329 # not been met in the wild so far.
329 if remote.limitedarguments:
330 if remote.limitedarguments:
330 sample = _limitsample(ownheads, initialsamplesize)
331 sample = _limitsample(ownheads, initialsamplesize)
331 # indices between sample and externalized version must match
332 # indices between sample and externalized version must match
332 sample = list(sample)
333 sample = list(sample)
333 else:
334 else:
334 sample = ownheads
335 sample = ownheads
335
336
336 with remote.commandexecutor() as e:
337 with remote.commandexecutor() as e:
337 fheads = e.callcommand('heads', {})
338 fheads = e.callcommand('heads', {})
338 fknown = e.callcommand('known', {
339 fknown = e.callcommand('known', {
339 'nodes': [clnode(r) for r in sample],
340 'nodes': [clnode(r) for r in sample],
340 })
341 })
341
342
342 srvheadhashes, yesno = fheads.result(), fknown.result()
343 srvheadhashes, yesno = fheads.result(), fknown.result()
343
344
344 if cl.tip() == nullid:
345 if cl.tip() == nullid:
345 if srvheadhashes != [nullid]:
346 if srvheadhashes != [nullid]:
346 return [nullid], True, srvheadhashes
347 return [nullid], True, srvheadhashes
347 return [nullid], False, []
348 return [nullid], False, []
348
349
349 # start actual discovery (we note this before the next "if" for
350 # start actual discovery (we note this before the next "if" for
350 # compatibility reasons)
351 # compatibility reasons)
351 ui.status(_("searching for changes\n"))
352 ui.status(_("searching for changes\n"))
352
353
353 knownsrvheads = [] # revnos of remote heads that are known locally
354 knownsrvheads = [] # revnos of remote heads that are known locally
354 for node in srvheadhashes:
355 for node in srvheadhashes:
355 if node == nullid:
356 if node == nullid:
356 continue
357 continue
357
358
358 try:
359 try:
359 knownsrvheads.append(clrev(node))
360 knownsrvheads.append(clrev(node))
360 # Catches unknown and filtered nodes.
361 # Catches unknown and filtered nodes.
361 except error.LookupError:
362 except error.LookupError:
362 continue
363 continue
363
364
364 if len(knownsrvheads) == len(srvheadhashes):
365 if len(knownsrvheads) == len(srvheadhashes):
365 ui.debug("all remote heads known locally\n")
366 ui.debug("all remote heads known locally\n")
366 return srvheadhashes, False, srvheadhashes
367 return srvheadhashes, False, srvheadhashes
367
368
368 if len(sample) == len(ownheads) and all(yesno):
369 if len(sample) == len(ownheads) and all(yesno):
369 ui.note(_("all local heads known remotely\n"))
370 ui.note(_("all local heads known remotely\n"))
370 ownheadhashes = [clnode(r) for r in ownheads]
371 ownheadhashes = [clnode(r) for r in ownheads]
371 return ownheadhashes, True, srvheadhashes
372 return ownheadhashes, True, srvheadhashes
372
373
373 # full blown discovery
374 # full blown discovery
374
375
375 disco = partialdiscovery(local, ownheads)
376 disco = partialdiscovery(local, ownheads)
376 # treat remote heads (and maybe own heads) as a first implicit sample
377 # treat remote heads (and maybe own heads) as a first implicit sample
377 # response
378 # response
378 disco.addcommons(knownsrvheads)
379 disco.addcommons(knownsrvheads)
379 disco.addinfo(zip(sample, yesno))
380 disco.addinfo(zip(sample, yesno))
380
381
381 full = False
382 full = False
382 progress = ui.makeprogress(_('searching'), unit=_('queries'))
383 progress = ui.makeprogress(_('searching'), unit=_('queries'))
383 while not disco.iscomplete():
384 while not disco.iscomplete():
384
385
385 if full or disco.hasinfo():
386 if full or disco.hasinfo():
386 if full:
387 if full:
387 ui.note(_("sampling from both directions\n"))
388 ui.note(_("sampling from both directions\n"))
388 else:
389 else:
389 ui.debug("taking initial sample\n")
390 ui.debug("taking initial sample\n")
390 samplefunc = disco.takefullsample
391 samplefunc = disco.takefullsample
391 targetsize = fullsamplesize
392 targetsize = fullsamplesize
393 if not remote.limitedarguments:
394 fullsamplesize = int(fullsamplesize * samplegrowth)
392 else:
395 else:
393 # use even cheaper initial sample
396 # use even cheaper initial sample
394 ui.debug("taking quick initial sample\n")
397 ui.debug("taking quick initial sample\n")
395 samplefunc = disco.takequicksample
398 samplefunc = disco.takequicksample
396 targetsize = initialsamplesize
399 targetsize = initialsamplesize
397 sample = samplefunc(ownheads, targetsize)
400 sample = samplefunc(ownheads, targetsize)
398
401
399 roundtrips += 1
402 roundtrips += 1
400 progress.update(roundtrips)
403 progress.update(roundtrips)
401 stats = disco.stats()
404 stats = disco.stats()
402 ui.debug("query %i; still undecided: %i, sample size is: %i\n"
405 ui.debug("query %i; still undecided: %i, sample size is: %i\n"
403 % (roundtrips, stats['undecided'], len(sample)))
406 % (roundtrips, stats['undecided'], len(sample)))
404
407
405 # indices between sample and externalized version must match
408 # indices between sample and externalized version must match
406 sample = list(sample)
409 sample = list(sample)
407
410
408 with remote.commandexecutor() as e:
411 with remote.commandexecutor() as e:
409 yesno = e.callcommand('known', {
412 yesno = e.callcommand('known', {
410 'nodes': [clnode(r) for r in sample],
413 'nodes': [clnode(r) for r in sample],
411 }).result()
414 }).result()
412
415
413 full = True
416 full = True
414
417
415 disco.addinfo(zip(sample, yesno))
418 disco.addinfo(zip(sample, yesno))
416
419
417 result = disco.commonheads()
420 result = disco.commonheads()
418 elapsed = util.timer() - start
421 elapsed = util.timer() - start
419 progress.complete()
422 progress.complete()
420 ui.debug("%d total queries in %.4fs\n" % (roundtrips, elapsed))
423 ui.debug("%d total queries in %.4fs\n" % (roundtrips, elapsed))
421 msg = ('found %d common and %d unknown server heads,'
424 msg = ('found %d common and %d unknown server heads,'
422 ' %d roundtrips in %.4fs\n')
425 ' %d roundtrips in %.4fs\n')
423 missing = set(result) - set(knownsrvheads)
426 missing = set(result) - set(knownsrvheads)
424 ui.log('discovery', msg, len(result), len(missing), roundtrips,
427 ui.log('discovery', msg, len(result), len(missing), roundtrips,
425 elapsed)
428 elapsed)
426
429
427 if not result and srvheadhashes != [nullid]:
430 if not result and srvheadhashes != [nullid]:
428 if abortwhenunrelated:
431 if abortwhenunrelated:
429 raise error.Abort(_("repository is unrelated"))
432 raise error.Abort(_("repository is unrelated"))
430 else:
433 else:
431 ui.warn(_("warning: repository is unrelated\n"))
434 ui.warn(_("warning: repository is unrelated\n"))
432 return ({nullid}, True, srvheadhashes,)
435 return ({nullid}, True, srvheadhashes,)
433
436
434 anyincoming = (srvheadhashes != [nullid])
437 anyincoming = (srvheadhashes != [nullid])
435 result = {clnode(r) for r in result}
438 result = {clnode(r) for r in result}
436 return result, anyincoming, srvheadhashes
439 return result, anyincoming, srvheadhashes
@@ -1,1118 +1,1118
1
1
2 Function to test discovery between two repos in both directions, using both the local shortcut
2 Function to test discovery between two repos in both directions, using both the local shortcut
3 (which is currently not activated by default) and the full remotable protocol:
3 (which is currently not activated by default) and the full remotable protocol:
4
4
5 $ testdesc() { # revs_a, revs_b, dagdesc
5 $ testdesc() { # revs_a, revs_b, dagdesc
6 > if [ -d foo ]; then rm -rf foo; fi
6 > if [ -d foo ]; then rm -rf foo; fi
7 > hg init foo
7 > hg init foo
8 > cd foo
8 > cd foo
9 > hg debugbuilddag "$3"
9 > hg debugbuilddag "$3"
10 > hg clone . a $1 --quiet
10 > hg clone . a $1 --quiet
11 > hg clone . b $2 --quiet
11 > hg clone . b $2 --quiet
12 > echo
12 > echo
13 > echo "% -- a -> b tree"
13 > echo "% -- a -> b tree"
14 > hg -R a debugdiscovery b --verbose --old
14 > hg -R a debugdiscovery b --verbose --old
15 > echo
15 > echo
16 > echo "% -- a -> b set"
16 > echo "% -- a -> b set"
17 > hg -R a debugdiscovery b --verbose --debug --config progress.debug=true
17 > hg -R a debugdiscovery b --verbose --debug --config progress.debug=true
18 > echo
18 > echo
19 > echo "% -- a -> b set (tip only)"
19 > echo "% -- a -> b set (tip only)"
20 > hg -R a debugdiscovery b --verbose --debug --config progress.debug=true --rev tip
20 > hg -R a debugdiscovery b --verbose --debug --config progress.debug=true --rev tip
21 > echo
21 > echo
22 > echo "% -- b -> a tree"
22 > echo "% -- b -> a tree"
23 > hg -R b debugdiscovery a --verbose --old
23 > hg -R b debugdiscovery a --verbose --old
24 > echo
24 > echo
25 > echo "% -- b -> a set"
25 > echo "% -- b -> a set"
26 > hg -R b debugdiscovery a --verbose --debug --config progress.debug=true
26 > hg -R b debugdiscovery a --verbose --debug --config progress.debug=true
27 > echo
27 > echo
28 > echo "% -- b -> a set (tip only)"
28 > echo "% -- b -> a set (tip only)"
29 > hg -R b debugdiscovery a --verbose --debug --config progress.debug=true --rev tip
29 > hg -R b debugdiscovery a --verbose --debug --config progress.debug=true --rev tip
30 > cd ..
30 > cd ..
31 > }
31 > }
32
32
33
33
34 Small superset:
34 Small superset:
35
35
36 $ testdesc '-ra1 -ra2' '-rb1 -rb2 -rb3' '
36 $ testdesc '-ra1 -ra2' '-rb1 -rb2 -rb3' '
37 > +2:f +1:a1:b1
37 > +2:f +1:a1:b1
38 > <f +4 :a2
38 > <f +4 :a2
39 > +5 :b2
39 > +5 :b2
40 > <f +3 :b3'
40 > <f +3 :b3'
41
41
42 % -- a -> b tree
42 % -- a -> b tree
43 comparing with b
43 comparing with b
44 searching for changes
44 searching for changes
45 unpruned common: 01241442b3c2 66f7d451a68b b5714e113bc0
45 unpruned common: 01241442b3c2 66f7d451a68b b5714e113bc0
46 elapsed time: * seconds (glob)
46 elapsed time: * seconds (glob)
47 heads summary:
47 heads summary:
48 total common heads: 2
48 total common heads: 2
49 also local heads: 2
49 also local heads: 2
50 also remote heads: 1
50 also remote heads: 1
51 both: 1
51 both: 1
52 local heads: 2
52 local heads: 2
53 common: 2
53 common: 2
54 missing: 0
54 missing: 0
55 remote heads: 3
55 remote heads: 3
56 common: 1
56 common: 1
57 unknown: 2
57 unknown: 2
58 local changesets: 7
58 local changesets: 7
59 common: 7
59 common: 7
60 missing: 0
60 missing: 0
61 common heads: 01241442b3c2 b5714e113bc0
61 common heads: 01241442b3c2 b5714e113bc0
62
62
63 % -- a -> b set
63 % -- a -> b set
64 comparing with b
64 comparing with b
65 query 1; heads
65 query 1; heads
66 searching for changes
66 searching for changes
67 all local heads known remotely
67 all local heads known remotely
68 elapsed time: * seconds (glob)
68 elapsed time: * seconds (glob)
69 heads summary:
69 heads summary:
70 total common heads: 2
70 total common heads: 2
71 also local heads: 2
71 also local heads: 2
72 also remote heads: 1
72 also remote heads: 1
73 both: 1
73 both: 1
74 local heads: 2
74 local heads: 2
75 common: 2
75 common: 2
76 missing: 0
76 missing: 0
77 remote heads: 3
77 remote heads: 3
78 common: 1
78 common: 1
79 unknown: 2
79 unknown: 2
80 local changesets: 7
80 local changesets: 7
81 common: 7
81 common: 7
82 missing: 0
82 missing: 0
83 common heads: 01241442b3c2 b5714e113bc0
83 common heads: 01241442b3c2 b5714e113bc0
84
84
85 % -- a -> b set (tip only)
85 % -- a -> b set (tip only)
86 comparing with b
86 comparing with b
87 query 1; heads
87 query 1; heads
88 searching for changes
88 searching for changes
89 all local heads known remotely
89 all local heads known remotely
90 elapsed time: * seconds (glob)
90 elapsed time: * seconds (glob)
91 heads summary:
91 heads summary:
92 total common heads: 1
92 total common heads: 1
93 also local heads: 1
93 also local heads: 1
94 also remote heads: 0
94 also remote heads: 0
95 both: 0
95 both: 0
96 local heads: 2
96 local heads: 2
97 common: 1
97 common: 1
98 missing: 1
98 missing: 1
99 remote heads: 3
99 remote heads: 3
100 common: 0
100 common: 0
101 unknown: 3
101 unknown: 3
102 local changesets: 7
102 local changesets: 7
103 common: 6
103 common: 6
104 missing: 1
104 missing: 1
105 common heads: b5714e113bc0
105 common heads: b5714e113bc0
106
106
107 % -- b -> a tree
107 % -- b -> a tree
108 comparing with a
108 comparing with a
109 searching for changes
109 searching for changes
110 unpruned common: 01241442b3c2 b5714e113bc0
110 unpruned common: 01241442b3c2 b5714e113bc0
111 elapsed time: * seconds (glob)
111 elapsed time: * seconds (glob)
112 heads summary:
112 heads summary:
113 total common heads: 2
113 total common heads: 2
114 also local heads: 1
114 also local heads: 1
115 also remote heads: 2
115 also remote heads: 2
116 both: 1
116 both: 1
117 local heads: 3
117 local heads: 3
118 common: 1
118 common: 1
119 missing: 2
119 missing: 2
120 remote heads: 2
120 remote heads: 2
121 common: 2
121 common: 2
122 unknown: 0
122 unknown: 0
123 local changesets: 15
123 local changesets: 15
124 common: 7
124 common: 7
125 missing: 8
125 missing: 8
126 common heads: 01241442b3c2 b5714e113bc0
126 common heads: 01241442b3c2 b5714e113bc0
127
127
128 % -- b -> a set
128 % -- b -> a set
129 comparing with a
129 comparing with a
130 query 1; heads
130 query 1; heads
131 searching for changes
131 searching for changes
132 all remote heads known locally
132 all remote heads known locally
133 elapsed time: * seconds (glob)
133 elapsed time: * seconds (glob)
134 heads summary:
134 heads summary:
135 total common heads: 2
135 total common heads: 2
136 also local heads: 1
136 also local heads: 1
137 also remote heads: 2
137 also remote heads: 2
138 both: 1
138 both: 1
139 local heads: 3
139 local heads: 3
140 common: 1
140 common: 1
141 missing: 2
141 missing: 2
142 remote heads: 2
142 remote heads: 2
143 common: 2
143 common: 2
144 unknown: 0
144 unknown: 0
145 local changesets: 15
145 local changesets: 15
146 common: 7
146 common: 7
147 missing: 8
147 missing: 8
148 common heads: 01241442b3c2 b5714e113bc0
148 common heads: 01241442b3c2 b5714e113bc0
149
149
150 % -- b -> a set (tip only)
150 % -- b -> a set (tip only)
151 comparing with a
151 comparing with a
152 query 1; heads
152 query 1; heads
153 searching for changes
153 searching for changes
154 all remote heads known locally
154 all remote heads known locally
155 elapsed time: * seconds (glob)
155 elapsed time: * seconds (glob)
156 heads summary:
156 heads summary:
157 total common heads: 2
157 total common heads: 2
158 also local heads: 1
158 also local heads: 1
159 also remote heads: 2
159 also remote heads: 2
160 both: 1
160 both: 1
161 local heads: 3
161 local heads: 3
162 common: 1
162 common: 1
163 missing: 2
163 missing: 2
164 remote heads: 2
164 remote heads: 2
165 common: 2
165 common: 2
166 unknown: 0
166 unknown: 0
167 local changesets: 15
167 local changesets: 15
168 common: 7
168 common: 7
169 missing: 8
169 missing: 8
170 common heads: 01241442b3c2 b5714e113bc0
170 common heads: 01241442b3c2 b5714e113bc0
171
171
172
172
173 Many new:
173 Many new:
174
174
175 $ testdesc '-ra1 -ra2' '-rb' '
175 $ testdesc '-ra1 -ra2' '-rb' '
176 > +2:f +3:a1 +3:b
176 > +2:f +3:a1 +3:b
177 > <f +30 :a2'
177 > <f +30 :a2'
178
178
179 % -- a -> b tree
179 % -- a -> b tree
180 comparing with b
180 comparing with b
181 searching for changes
181 searching for changes
182 unpruned common: bebd167eb94d
182 unpruned common: bebd167eb94d
183 elapsed time: * seconds (glob)
183 elapsed time: * seconds (glob)
184 heads summary:
184 heads summary:
185 total common heads: 1
185 total common heads: 1
186 also local heads: 1
186 also local heads: 1
187 also remote heads: 0
187 also remote heads: 0
188 both: 0
188 both: 0
189 local heads: 2
189 local heads: 2
190 common: 1
190 common: 1
191 missing: 1
191 missing: 1
192 remote heads: 1
192 remote heads: 1
193 common: 0
193 common: 0
194 unknown: 1
194 unknown: 1
195 local changesets: 35
195 local changesets: 35
196 common: 5
196 common: 5
197 missing: 30
197 missing: 30
198 common heads: bebd167eb94d
198 common heads: bebd167eb94d
199
199
200 % -- a -> b set
200 % -- a -> b set
201 comparing with b
201 comparing with b
202 query 1; heads
202 query 1; heads
203 searching for changes
203 searching for changes
204 taking initial sample
204 taking initial sample
205 searching: 2 queries
205 searching: 2 queries
206 query 2; still undecided: 29, sample size is: 29
206 query 2; still undecided: 29, sample size is: 29
207 2 total queries in *.????s (glob)
207 2 total queries in *.????s (glob)
208 elapsed time: * seconds (glob)
208 elapsed time: * seconds (glob)
209 heads summary:
209 heads summary:
210 total common heads: 1
210 total common heads: 1
211 also local heads: 1
211 also local heads: 1
212 also remote heads: 0
212 also remote heads: 0
213 both: 0
213 both: 0
214 local heads: 2
214 local heads: 2
215 common: 1
215 common: 1
216 missing: 1
216 missing: 1
217 remote heads: 1
217 remote heads: 1
218 common: 0
218 common: 0
219 unknown: 1
219 unknown: 1
220 local changesets: 35
220 local changesets: 35
221 common: 5
221 common: 5
222 missing: 30
222 missing: 30
223 common heads: bebd167eb94d
223 common heads: bebd167eb94d
224
224
225 % -- a -> b set (tip only)
225 % -- a -> b set (tip only)
226 comparing with b
226 comparing with b
227 query 1; heads
227 query 1; heads
228 searching for changes
228 searching for changes
229 taking quick initial sample
229 taking quick initial sample
230 searching: 2 queries
230 searching: 2 queries
231 query 2; still undecided: 31, sample size is: 31
231 query 2; still undecided: 31, sample size is: 31
232 2 total queries in *.????s (glob)
232 2 total queries in *.????s (glob)
233 elapsed time: * seconds (glob)
233 elapsed time: * seconds (glob)
234 heads summary:
234 heads summary:
235 total common heads: 1
235 total common heads: 1
236 also local heads: 0
236 also local heads: 0
237 also remote heads: 0
237 also remote heads: 0
238 both: 0
238 both: 0
239 local heads: 2
239 local heads: 2
240 common: 0
240 common: 0
241 missing: 2
241 missing: 2
242 remote heads: 1
242 remote heads: 1
243 common: 0
243 common: 0
244 unknown: 1
244 unknown: 1
245 local changesets: 35
245 local changesets: 35
246 common: 2
246 common: 2
247 missing: 33
247 missing: 33
248 common heads: 66f7d451a68b
248 common heads: 66f7d451a68b
249
249
250 % -- b -> a tree
250 % -- b -> a tree
251 comparing with a
251 comparing with a
252 searching for changes
252 searching for changes
253 unpruned common: 66f7d451a68b bebd167eb94d
253 unpruned common: 66f7d451a68b bebd167eb94d
254 elapsed time: * seconds (glob)
254 elapsed time: * seconds (glob)
255 heads summary:
255 heads summary:
256 total common heads: 1
256 total common heads: 1
257 also local heads: 0
257 also local heads: 0
258 also remote heads: 1
258 also remote heads: 1
259 both: 0
259 both: 0
260 local heads: 1
260 local heads: 1
261 common: 0
261 common: 0
262 missing: 1
262 missing: 1
263 remote heads: 2
263 remote heads: 2
264 common: 1
264 common: 1
265 unknown: 1
265 unknown: 1
266 local changesets: 8
266 local changesets: 8
267 common: 5
267 common: 5
268 missing: 3
268 missing: 3
269 common heads: bebd167eb94d
269 common heads: bebd167eb94d
270
270
271 % -- b -> a set
271 % -- b -> a set
272 comparing with a
272 comparing with a
273 query 1; heads
273 query 1; heads
274 searching for changes
274 searching for changes
275 taking initial sample
275 taking initial sample
276 searching: 2 queries
276 searching: 2 queries
277 query 2; still undecided: 2, sample size is: 2
277 query 2; still undecided: 2, sample size is: 2
278 2 total queries in *.????s (glob)
278 2 total queries in *.????s (glob)
279 elapsed time: * seconds (glob)
279 elapsed time: * seconds (glob)
280 heads summary:
280 heads summary:
281 total common heads: 1
281 total common heads: 1
282 also local heads: 0
282 also local heads: 0
283 also remote heads: 1
283 also remote heads: 1
284 both: 0
284 both: 0
285 local heads: 1
285 local heads: 1
286 common: 0
286 common: 0
287 missing: 1
287 missing: 1
288 remote heads: 2
288 remote heads: 2
289 common: 1
289 common: 1
290 unknown: 1
290 unknown: 1
291 local changesets: 8
291 local changesets: 8
292 common: 5
292 common: 5
293 missing: 3
293 missing: 3
294 common heads: bebd167eb94d
294 common heads: bebd167eb94d
295
295
296 % -- b -> a set (tip only)
296 % -- b -> a set (tip only)
297 comparing with a
297 comparing with a
298 query 1; heads
298 query 1; heads
299 searching for changes
299 searching for changes
300 taking initial sample
300 taking initial sample
301 searching: 2 queries
301 searching: 2 queries
302 query 2; still undecided: 2, sample size is: 2
302 query 2; still undecided: 2, sample size is: 2
303 2 total queries in *.????s (glob)
303 2 total queries in *.????s (glob)
304 elapsed time: * seconds (glob)
304 elapsed time: * seconds (glob)
305 heads summary:
305 heads summary:
306 total common heads: 1
306 total common heads: 1
307 also local heads: 0
307 also local heads: 0
308 also remote heads: 1
308 also remote heads: 1
309 both: 0
309 both: 0
310 local heads: 1
310 local heads: 1
311 common: 0
311 common: 0
312 missing: 1
312 missing: 1
313 remote heads: 2
313 remote heads: 2
314 common: 1
314 common: 1
315 unknown: 1
315 unknown: 1
316 local changesets: 8
316 local changesets: 8
317 common: 5
317 common: 5
318 missing: 3
318 missing: 3
319 common heads: bebd167eb94d
319 common heads: bebd167eb94d
320
320
321 Both sides many new with stub:
321 Both sides many new with stub:
322
322
323 $ testdesc '-ra1 -ra2' '-rb' '
323 $ testdesc '-ra1 -ra2' '-rb' '
324 > +2:f +2:a1 +30 :b
324 > +2:f +2:a1 +30 :b
325 > <f +30 :a2'
325 > <f +30 :a2'
326
326
327 % -- a -> b tree
327 % -- a -> b tree
328 comparing with b
328 comparing with b
329 searching for changes
329 searching for changes
330 unpruned common: 2dc09a01254d
330 unpruned common: 2dc09a01254d
331 elapsed time: * seconds (glob)
331 elapsed time: * seconds (glob)
332 heads summary:
332 heads summary:
333 total common heads: 1
333 total common heads: 1
334 also local heads: 1
334 also local heads: 1
335 also remote heads: 0
335 also remote heads: 0
336 both: 0
336 both: 0
337 local heads: 2
337 local heads: 2
338 common: 1
338 common: 1
339 missing: 1
339 missing: 1
340 remote heads: 1
340 remote heads: 1
341 common: 0
341 common: 0
342 unknown: 1
342 unknown: 1
343 local changesets: 34
343 local changesets: 34
344 common: 4
344 common: 4
345 missing: 30
345 missing: 30
346 common heads: 2dc09a01254d
346 common heads: 2dc09a01254d
347
347
348 % -- a -> b set
348 % -- a -> b set
349 comparing with b
349 comparing with b
350 query 1; heads
350 query 1; heads
351 searching for changes
351 searching for changes
352 taking initial sample
352 taking initial sample
353 searching: 2 queries
353 searching: 2 queries
354 query 2; still undecided: 29, sample size is: 29
354 query 2; still undecided: 29, sample size is: 29
355 2 total queries in *.????s (glob)
355 2 total queries in *.????s (glob)
356 elapsed time: * seconds (glob)
356 elapsed time: * seconds (glob)
357 heads summary:
357 heads summary:
358 total common heads: 1
358 total common heads: 1
359 also local heads: 1
359 also local heads: 1
360 also remote heads: 0
360 also remote heads: 0
361 both: 0
361 both: 0
362 local heads: 2
362 local heads: 2
363 common: 1
363 common: 1
364 missing: 1
364 missing: 1
365 remote heads: 1
365 remote heads: 1
366 common: 0
366 common: 0
367 unknown: 1
367 unknown: 1
368 local changesets: 34
368 local changesets: 34
369 common: 4
369 common: 4
370 missing: 30
370 missing: 30
371 common heads: 2dc09a01254d
371 common heads: 2dc09a01254d
372
372
373 % -- a -> b set (tip only)
373 % -- a -> b set (tip only)
374 comparing with b
374 comparing with b
375 query 1; heads
375 query 1; heads
376 searching for changes
376 searching for changes
377 taking quick initial sample
377 taking quick initial sample
378 searching: 2 queries
378 searching: 2 queries
379 query 2; still undecided: 31, sample size is: 31
379 query 2; still undecided: 31, sample size is: 31
380 2 total queries in *.????s (glob)
380 2 total queries in *.????s (glob)
381 elapsed time: * seconds (glob)
381 elapsed time: * seconds (glob)
382 heads summary:
382 heads summary:
383 total common heads: 1
383 total common heads: 1
384 also local heads: 0
384 also local heads: 0
385 also remote heads: 0
385 also remote heads: 0
386 both: 0
386 both: 0
387 local heads: 2
387 local heads: 2
388 common: 0
388 common: 0
389 missing: 2
389 missing: 2
390 remote heads: 1
390 remote heads: 1
391 common: 0
391 common: 0
392 unknown: 1
392 unknown: 1
393 local changesets: 34
393 local changesets: 34
394 common: 2
394 common: 2
395 missing: 32
395 missing: 32
396 common heads: 66f7d451a68b
396 common heads: 66f7d451a68b
397
397
398 % -- b -> a tree
398 % -- b -> a tree
399 comparing with a
399 comparing with a
400 searching for changes
400 searching for changes
401 unpruned common: 2dc09a01254d 66f7d451a68b
401 unpruned common: 2dc09a01254d 66f7d451a68b
402 elapsed time: * seconds (glob)
402 elapsed time: * seconds (glob)
403 heads summary:
403 heads summary:
404 total common heads: 1
404 total common heads: 1
405 also local heads: 0
405 also local heads: 0
406 also remote heads: 1
406 also remote heads: 1
407 both: 0
407 both: 0
408 local heads: 1
408 local heads: 1
409 common: 0
409 common: 0
410 missing: 1
410 missing: 1
411 remote heads: 2
411 remote heads: 2
412 common: 1
412 common: 1
413 unknown: 1
413 unknown: 1
414 local changesets: 34
414 local changesets: 34
415 common: 4
415 common: 4
416 missing: 30
416 missing: 30
417 common heads: 2dc09a01254d
417 common heads: 2dc09a01254d
418
418
419 % -- b -> a set
419 % -- b -> a set
420 comparing with a
420 comparing with a
421 query 1; heads
421 query 1; heads
422 searching for changes
422 searching for changes
423 taking initial sample
423 taking initial sample
424 searching: 2 queries
424 searching: 2 queries
425 query 2; still undecided: 29, sample size is: 29
425 query 2; still undecided: 29, sample size is: 29
426 2 total queries in *.????s (glob)
426 2 total queries in *.????s (glob)
427 elapsed time: * seconds (glob)
427 elapsed time: * seconds (glob)
428 heads summary:
428 heads summary:
429 total common heads: 1
429 total common heads: 1
430 also local heads: 0
430 also local heads: 0
431 also remote heads: 1
431 also remote heads: 1
432 both: 0
432 both: 0
433 local heads: 1
433 local heads: 1
434 common: 0
434 common: 0
435 missing: 1
435 missing: 1
436 remote heads: 2
436 remote heads: 2
437 common: 1
437 common: 1
438 unknown: 1
438 unknown: 1
439 local changesets: 34
439 local changesets: 34
440 common: 4
440 common: 4
441 missing: 30
441 missing: 30
442 common heads: 2dc09a01254d
442 common heads: 2dc09a01254d
443
443
444 % -- b -> a set (tip only)
444 % -- b -> a set (tip only)
445 comparing with a
445 comparing with a
446 query 1; heads
446 query 1; heads
447 searching for changes
447 searching for changes
448 taking initial sample
448 taking initial sample
449 searching: 2 queries
449 searching: 2 queries
450 query 2; still undecided: 29, sample size is: 29
450 query 2; still undecided: 29, sample size is: 29
451 2 total queries in *.????s (glob)
451 2 total queries in *.????s (glob)
452 elapsed time: * seconds (glob)
452 elapsed time: * seconds (glob)
453 heads summary:
453 heads summary:
454 total common heads: 1
454 total common heads: 1
455 also local heads: 0
455 also local heads: 0
456 also remote heads: 1
456 also remote heads: 1
457 both: 0
457 both: 0
458 local heads: 1
458 local heads: 1
459 common: 0
459 common: 0
460 missing: 1
460 missing: 1
461 remote heads: 2
461 remote heads: 2
462 common: 1
462 common: 1
463 unknown: 1
463 unknown: 1
464 local changesets: 34
464 local changesets: 34
465 common: 4
465 common: 4
466 missing: 30
466 missing: 30
467 common heads: 2dc09a01254d
467 common heads: 2dc09a01254d
468
468
469
469
470 Both many new:
470 Both many new:
471
471
472 $ testdesc '-ra' '-rb' '
472 $ testdesc '-ra' '-rb' '
473 > +2:f +30 :b
473 > +2:f +30 :b
474 > <f +30 :a'
474 > <f +30 :a'
475
475
476 % -- a -> b tree
476 % -- a -> b tree
477 comparing with b
477 comparing with b
478 searching for changes
478 searching for changes
479 unpruned common: 66f7d451a68b
479 unpruned common: 66f7d451a68b
480 elapsed time: * seconds (glob)
480 elapsed time: * seconds (glob)
481 heads summary:
481 heads summary:
482 total common heads: 1
482 total common heads: 1
483 also local heads: 0
483 also local heads: 0
484 also remote heads: 0
484 also remote heads: 0
485 both: 0
485 both: 0
486 local heads: 1
486 local heads: 1
487 common: 0
487 common: 0
488 missing: 1
488 missing: 1
489 remote heads: 1
489 remote heads: 1
490 common: 0
490 common: 0
491 unknown: 1
491 unknown: 1
492 local changesets: 32
492 local changesets: 32
493 common: 2
493 common: 2
494 missing: 30
494 missing: 30
495 common heads: 66f7d451a68b
495 common heads: 66f7d451a68b
496
496
497 % -- a -> b set
497 % -- a -> b set
498 comparing with b
498 comparing with b
499 query 1; heads
499 query 1; heads
500 searching for changes
500 searching for changes
501 taking quick initial sample
501 taking quick initial sample
502 searching: 2 queries
502 searching: 2 queries
503 query 2; still undecided: 31, sample size is: 31
503 query 2; still undecided: 31, sample size is: 31
504 2 total queries in *.????s (glob)
504 2 total queries in *.????s (glob)
505 elapsed time: * seconds (glob)
505 elapsed time: * seconds (glob)
506 heads summary:
506 heads summary:
507 total common heads: 1
507 total common heads: 1
508 also local heads: 0
508 also local heads: 0
509 also remote heads: 0
509 also remote heads: 0
510 both: 0
510 both: 0
511 local heads: 1
511 local heads: 1
512 common: 0
512 common: 0
513 missing: 1
513 missing: 1
514 remote heads: 1
514 remote heads: 1
515 common: 0
515 common: 0
516 unknown: 1
516 unknown: 1
517 local changesets: 32
517 local changesets: 32
518 common: 2
518 common: 2
519 missing: 30
519 missing: 30
520 common heads: 66f7d451a68b
520 common heads: 66f7d451a68b
521
521
522 % -- a -> b set (tip only)
522 % -- a -> b set (tip only)
523 comparing with b
523 comparing with b
524 query 1; heads
524 query 1; heads
525 searching for changes
525 searching for changes
526 taking quick initial sample
526 taking quick initial sample
527 searching: 2 queries
527 searching: 2 queries
528 query 2; still undecided: 31, sample size is: 31
528 query 2; still undecided: 31, sample size is: 31
529 2 total queries in *.????s (glob)
529 2 total queries in *.????s (glob)
530 elapsed time: * seconds (glob)
530 elapsed time: * seconds (glob)
531 heads summary:
531 heads summary:
532 total common heads: 1
532 total common heads: 1
533 also local heads: 0
533 also local heads: 0
534 also remote heads: 0
534 also remote heads: 0
535 both: 0
535 both: 0
536 local heads: 1
536 local heads: 1
537 common: 0
537 common: 0
538 missing: 1
538 missing: 1
539 remote heads: 1
539 remote heads: 1
540 common: 0
540 common: 0
541 unknown: 1
541 unknown: 1
542 local changesets: 32
542 local changesets: 32
543 common: 2
543 common: 2
544 missing: 30
544 missing: 30
545 common heads: 66f7d451a68b
545 common heads: 66f7d451a68b
546
546
547 % -- b -> a tree
547 % -- b -> a tree
548 comparing with a
548 comparing with a
549 searching for changes
549 searching for changes
550 unpruned common: 66f7d451a68b
550 unpruned common: 66f7d451a68b
551 elapsed time: * seconds (glob)
551 elapsed time: * seconds (glob)
552 heads summary:
552 heads summary:
553 total common heads: 1
553 total common heads: 1
554 also local heads: 0
554 also local heads: 0
555 also remote heads: 0
555 also remote heads: 0
556 both: 0
556 both: 0
557 local heads: 1
557 local heads: 1
558 common: 0
558 common: 0
559 missing: 1
559 missing: 1
560 remote heads: 1
560 remote heads: 1
561 common: 0
561 common: 0
562 unknown: 1
562 unknown: 1
563 local changesets: 32
563 local changesets: 32
564 common: 2
564 common: 2
565 missing: 30
565 missing: 30
566 common heads: 66f7d451a68b
566 common heads: 66f7d451a68b
567
567
568 % -- b -> a set
568 % -- b -> a set
569 comparing with a
569 comparing with a
570 query 1; heads
570 query 1; heads
571 searching for changes
571 searching for changes
572 taking quick initial sample
572 taking quick initial sample
573 searching: 2 queries
573 searching: 2 queries
574 query 2; still undecided: 31, sample size is: 31
574 query 2; still undecided: 31, sample size is: 31
575 2 total queries in *.????s (glob)
575 2 total queries in *.????s (glob)
576 elapsed time: * seconds (glob)
576 elapsed time: * seconds (glob)
577 heads summary:
577 heads summary:
578 total common heads: 1
578 total common heads: 1
579 also local heads: 0
579 also local heads: 0
580 also remote heads: 0
580 also remote heads: 0
581 both: 0
581 both: 0
582 local heads: 1
582 local heads: 1
583 common: 0
583 common: 0
584 missing: 1
584 missing: 1
585 remote heads: 1
585 remote heads: 1
586 common: 0
586 common: 0
587 unknown: 1
587 unknown: 1
588 local changesets: 32
588 local changesets: 32
589 common: 2
589 common: 2
590 missing: 30
590 missing: 30
591 common heads: 66f7d451a68b
591 common heads: 66f7d451a68b
592
592
593 % -- b -> a set (tip only)
593 % -- b -> a set (tip only)
594 comparing with a
594 comparing with a
595 query 1; heads
595 query 1; heads
596 searching for changes
596 searching for changes
597 taking quick initial sample
597 taking quick initial sample
598 searching: 2 queries
598 searching: 2 queries
599 query 2; still undecided: 31, sample size is: 31
599 query 2; still undecided: 31, sample size is: 31
600 2 total queries in *.????s (glob)
600 2 total queries in *.????s (glob)
601 elapsed time: * seconds (glob)
601 elapsed time: * seconds (glob)
602 heads summary:
602 heads summary:
603 total common heads: 1
603 total common heads: 1
604 also local heads: 0
604 also local heads: 0
605 also remote heads: 0
605 also remote heads: 0
606 both: 0
606 both: 0
607 local heads: 1
607 local heads: 1
608 common: 0
608 common: 0
609 missing: 1
609 missing: 1
610 remote heads: 1
610 remote heads: 1
611 common: 0
611 common: 0
612 unknown: 1
612 unknown: 1
613 local changesets: 32
613 local changesets: 32
614 common: 2
614 common: 2
615 missing: 30
615 missing: 30
616 common heads: 66f7d451a68b
616 common heads: 66f7d451a68b
617
617
618
618
619 Both many new skewed:
619 Both many new skewed:
620
620
621 $ testdesc '-ra' '-rb' '
621 $ testdesc '-ra' '-rb' '
622 > +2:f +30 :b
622 > +2:f +30 :b
623 > <f +50 :a'
623 > <f +50 :a'
624
624
625 % -- a -> b tree
625 % -- a -> b tree
626 comparing with b
626 comparing with b
627 searching for changes
627 searching for changes
628 unpruned common: 66f7d451a68b
628 unpruned common: 66f7d451a68b
629 elapsed time: * seconds (glob)
629 elapsed time: * seconds (glob)
630 heads summary:
630 heads summary:
631 total common heads: 1
631 total common heads: 1
632 also local heads: 0
632 also local heads: 0
633 also remote heads: 0
633 also remote heads: 0
634 both: 0
634 both: 0
635 local heads: 1
635 local heads: 1
636 common: 0
636 common: 0
637 missing: 1
637 missing: 1
638 remote heads: 1
638 remote heads: 1
639 common: 0
639 common: 0
640 unknown: 1
640 unknown: 1
641 local changesets: 52
641 local changesets: 52
642 common: 2
642 common: 2
643 missing: 50
643 missing: 50
644 common heads: 66f7d451a68b
644 common heads: 66f7d451a68b
645
645
646 % -- a -> b set
646 % -- a -> b set
647 comparing with b
647 comparing with b
648 query 1; heads
648 query 1; heads
649 searching for changes
649 searching for changes
650 taking quick initial sample
650 taking quick initial sample
651 searching: 2 queries
651 searching: 2 queries
652 query 2; still undecided: 51, sample size is: 51
652 query 2; still undecided: 51, sample size is: 51
653 2 total queries in *.????s (glob)
653 2 total queries in *.????s (glob)
654 elapsed time: * seconds (glob)
654 elapsed time: * seconds (glob)
655 heads summary:
655 heads summary:
656 total common heads: 1
656 total common heads: 1
657 also local heads: 0
657 also local heads: 0
658 also remote heads: 0
658 also remote heads: 0
659 both: 0
659 both: 0
660 local heads: 1
660 local heads: 1
661 common: 0
661 common: 0
662 missing: 1
662 missing: 1
663 remote heads: 1
663 remote heads: 1
664 common: 0
664 common: 0
665 unknown: 1
665 unknown: 1
666 local changesets: 52
666 local changesets: 52
667 common: 2
667 common: 2
668 missing: 50
668 missing: 50
669 common heads: 66f7d451a68b
669 common heads: 66f7d451a68b
670
670
671 % -- a -> b set (tip only)
671 % -- a -> b set (tip only)
672 comparing with b
672 comparing with b
673 query 1; heads
673 query 1; heads
674 searching for changes
674 searching for changes
675 taking quick initial sample
675 taking quick initial sample
676 searching: 2 queries
676 searching: 2 queries
677 query 2; still undecided: 51, sample size is: 51
677 query 2; still undecided: 51, sample size is: 51
678 2 total queries in *.????s (glob)
678 2 total queries in *.????s (glob)
679 elapsed time: * seconds (glob)
679 elapsed time: * seconds (glob)
680 heads summary:
680 heads summary:
681 total common heads: 1
681 total common heads: 1
682 also local heads: 0
682 also local heads: 0
683 also remote heads: 0
683 also remote heads: 0
684 both: 0
684 both: 0
685 local heads: 1
685 local heads: 1
686 common: 0
686 common: 0
687 missing: 1
687 missing: 1
688 remote heads: 1
688 remote heads: 1
689 common: 0
689 common: 0
690 unknown: 1
690 unknown: 1
691 local changesets: 52
691 local changesets: 52
692 common: 2
692 common: 2
693 missing: 50
693 missing: 50
694 common heads: 66f7d451a68b
694 common heads: 66f7d451a68b
695
695
696 % -- b -> a tree
696 % -- b -> a tree
697 comparing with a
697 comparing with a
698 searching for changes
698 searching for changes
699 unpruned common: 66f7d451a68b
699 unpruned common: 66f7d451a68b
700 elapsed time: * seconds (glob)
700 elapsed time: * seconds (glob)
701 heads summary:
701 heads summary:
702 total common heads: 1
702 total common heads: 1
703 also local heads: 0
703 also local heads: 0
704 also remote heads: 0
704 also remote heads: 0
705 both: 0
705 both: 0
706 local heads: 1
706 local heads: 1
707 common: 0
707 common: 0
708 missing: 1
708 missing: 1
709 remote heads: 1
709 remote heads: 1
710 common: 0
710 common: 0
711 unknown: 1
711 unknown: 1
712 local changesets: 32
712 local changesets: 32
713 common: 2
713 common: 2
714 missing: 30
714 missing: 30
715 common heads: 66f7d451a68b
715 common heads: 66f7d451a68b
716
716
717 % -- b -> a set
717 % -- b -> a set
718 comparing with a
718 comparing with a
719 query 1; heads
719 query 1; heads
720 searching for changes
720 searching for changes
721 taking quick initial sample
721 taking quick initial sample
722 searching: 2 queries
722 searching: 2 queries
723 query 2; still undecided: 31, sample size is: 31
723 query 2; still undecided: 31, sample size is: 31
724 2 total queries in *.????s (glob)
724 2 total queries in *.????s (glob)
725 elapsed time: * seconds (glob)
725 elapsed time: * seconds (glob)
726 heads summary:
726 heads summary:
727 total common heads: 1
727 total common heads: 1
728 also local heads: 0
728 also local heads: 0
729 also remote heads: 0
729 also remote heads: 0
730 both: 0
730 both: 0
731 local heads: 1
731 local heads: 1
732 common: 0
732 common: 0
733 missing: 1
733 missing: 1
734 remote heads: 1
734 remote heads: 1
735 common: 0
735 common: 0
736 unknown: 1
736 unknown: 1
737 local changesets: 32
737 local changesets: 32
738 common: 2
738 common: 2
739 missing: 30
739 missing: 30
740 common heads: 66f7d451a68b
740 common heads: 66f7d451a68b
741
741
742 % -- b -> a set (tip only)
742 % -- b -> a set (tip only)
743 comparing with a
743 comparing with a
744 query 1; heads
744 query 1; heads
745 searching for changes
745 searching for changes
746 taking quick initial sample
746 taking quick initial sample
747 searching: 2 queries
747 searching: 2 queries
748 query 2; still undecided: 31, sample size is: 31
748 query 2; still undecided: 31, sample size is: 31
749 2 total queries in *.????s (glob)
749 2 total queries in *.????s (glob)
750 elapsed time: * seconds (glob)
750 elapsed time: * seconds (glob)
751 heads summary:
751 heads summary:
752 total common heads: 1
752 total common heads: 1
753 also local heads: 0
753 also local heads: 0
754 also remote heads: 0
754 also remote heads: 0
755 both: 0
755 both: 0
756 local heads: 1
756 local heads: 1
757 common: 0
757 common: 0
758 missing: 1
758 missing: 1
759 remote heads: 1
759 remote heads: 1
760 common: 0
760 common: 0
761 unknown: 1
761 unknown: 1
762 local changesets: 32
762 local changesets: 32
763 common: 2
763 common: 2
764 missing: 30
764 missing: 30
765 common heads: 66f7d451a68b
765 common heads: 66f7d451a68b
766
766
767
767
768 Both many new on top of long history:
768 Both many new on top of long history:
769
769
770 $ testdesc '-ra' '-rb' '
770 $ testdesc '-ra' '-rb' '
771 > +1000:f +30 :b
771 > +1000:f +30 :b
772 > <f +50 :a'
772 > <f +50 :a'
773
773
774 % -- a -> b tree
774 % -- a -> b tree
775 comparing with b
775 comparing with b
776 searching for changes
776 searching for changes
777 unpruned common: 7ead0cba2838
777 unpruned common: 7ead0cba2838
778 elapsed time: * seconds (glob)
778 elapsed time: * seconds (glob)
779 heads summary:
779 heads summary:
780 total common heads: 1
780 total common heads: 1
781 also local heads: 0
781 also local heads: 0
782 also remote heads: 0
782 also remote heads: 0
783 both: 0
783 both: 0
784 local heads: 1
784 local heads: 1
785 common: 0
785 common: 0
786 missing: 1
786 missing: 1
787 remote heads: 1
787 remote heads: 1
788 common: 0
788 common: 0
789 unknown: 1
789 unknown: 1
790 local changesets: 1050
790 local changesets: 1050
791 common: 1000
791 common: 1000
792 missing: 50
792 missing: 50
793 common heads: 7ead0cba2838
793 common heads: 7ead0cba2838
794
794
795 % -- a -> b set
795 % -- a -> b set
796 comparing with b
796 comparing with b
797 query 1; heads
797 query 1; heads
798 searching for changes
798 searching for changes
799 taking quick initial sample
799 taking quick initial sample
800 searching: 2 queries
800 searching: 2 queries
801 query 2; still undecided: 1049, sample size is: 11
801 query 2; still undecided: 1049, sample size is: 11
802 sampling from both directions
802 sampling from both directions
803 searching: 3 queries
803 searching: 3 queries
804 query 3; still undecided: 31, sample size is: 31
804 query 3; still undecided: 31, sample size is: 31
805 3 total queries in *.????s (glob)
805 3 total queries in *.????s (glob)
806 elapsed time: * seconds (glob)
806 elapsed time: * seconds (glob)
807 heads summary:
807 heads summary:
808 total common heads: 1
808 total common heads: 1
809 also local heads: 0
809 also local heads: 0
810 also remote heads: 0
810 also remote heads: 0
811 both: 0
811 both: 0
812 local heads: 1
812 local heads: 1
813 common: 0
813 common: 0
814 missing: 1
814 missing: 1
815 remote heads: 1
815 remote heads: 1
816 common: 0
816 common: 0
817 unknown: 1
817 unknown: 1
818 local changesets: 1050
818 local changesets: 1050
819 common: 1000
819 common: 1000
820 missing: 50
820 missing: 50
821 common heads: 7ead0cba2838
821 common heads: 7ead0cba2838
822
822
823 % -- a -> b set (tip only)
823 % -- a -> b set (tip only)
824 comparing with b
824 comparing with b
825 query 1; heads
825 query 1; heads
826 searching for changes
826 searching for changes
827 taking quick initial sample
827 taking quick initial sample
828 searching: 2 queries
828 searching: 2 queries
829 query 2; still undecided: 1049, sample size is: 11
829 query 2; still undecided: 1049, sample size is: 11
830 sampling from both directions
830 sampling from both directions
831 searching: 3 queries
831 searching: 3 queries
832 query 3; still undecided: 31, sample size is: 31
832 query 3; still undecided: 31, sample size is: 31
833 3 total queries in *.????s (glob)
833 3 total queries in *.????s (glob)
834 elapsed time: * seconds (glob)
834 elapsed time: * seconds (glob)
835 heads summary:
835 heads summary:
836 total common heads: 1
836 total common heads: 1
837 also local heads: 0
837 also local heads: 0
838 also remote heads: 0
838 also remote heads: 0
839 both: 0
839 both: 0
840 local heads: 1
840 local heads: 1
841 common: 0
841 common: 0
842 missing: 1
842 missing: 1
843 remote heads: 1
843 remote heads: 1
844 common: 0
844 common: 0
845 unknown: 1
845 unknown: 1
846 local changesets: 1050
846 local changesets: 1050
847 common: 1000
847 common: 1000
848 missing: 50
848 missing: 50
849 common heads: 7ead0cba2838
849 common heads: 7ead0cba2838
850
850
851 % -- b -> a tree
851 % -- b -> a tree
852 comparing with a
852 comparing with a
853 searching for changes
853 searching for changes
854 unpruned common: 7ead0cba2838
854 unpruned common: 7ead0cba2838
855 elapsed time: * seconds (glob)
855 elapsed time: * seconds (glob)
856 heads summary:
856 heads summary:
857 total common heads: 1
857 total common heads: 1
858 also local heads: 0
858 also local heads: 0
859 also remote heads: 0
859 also remote heads: 0
860 both: 0
860 both: 0
861 local heads: 1
861 local heads: 1
862 common: 0
862 common: 0
863 missing: 1
863 missing: 1
864 remote heads: 1
864 remote heads: 1
865 common: 0
865 common: 0
866 unknown: 1
866 unknown: 1
867 local changesets: 1030
867 local changesets: 1030
868 common: 1000
868 common: 1000
869 missing: 30
869 missing: 30
870 common heads: 7ead0cba2838
870 common heads: 7ead0cba2838
871
871
872 % -- b -> a set
872 % -- b -> a set
873 comparing with a
873 comparing with a
874 query 1; heads
874 query 1; heads
875 searching for changes
875 searching for changes
876 taking quick initial sample
876 taking quick initial sample
877 searching: 2 queries
877 searching: 2 queries
878 query 2; still undecided: 1029, sample size is: 11
878 query 2; still undecided: 1029, sample size is: 11
879 sampling from both directions
879 sampling from both directions
880 searching: 3 queries
880 searching: 3 queries
881 query 3; still undecided: 15, sample size is: 15
881 query 3; still undecided: 15, sample size is: 15
882 3 total queries in *.????s (glob)
882 3 total queries in *.????s (glob)
883 elapsed time: * seconds (glob)
883 elapsed time: * seconds (glob)
884 heads summary:
884 heads summary:
885 total common heads: 1
885 total common heads: 1
886 also local heads: 0
886 also local heads: 0
887 also remote heads: 0
887 also remote heads: 0
888 both: 0
888 both: 0
889 local heads: 1
889 local heads: 1
890 common: 0
890 common: 0
891 missing: 1
891 missing: 1
892 remote heads: 1
892 remote heads: 1
893 common: 0
893 common: 0
894 unknown: 1
894 unknown: 1
895 local changesets: 1030
895 local changesets: 1030
896 common: 1000
896 common: 1000
897 missing: 30
897 missing: 30
898 common heads: 7ead0cba2838
898 common heads: 7ead0cba2838
899
899
900 % -- b -> a set (tip only)
900 % -- b -> a set (tip only)
901 comparing with a
901 comparing with a
902 query 1; heads
902 query 1; heads
903 searching for changes
903 searching for changes
904 taking quick initial sample
904 taking quick initial sample
905 searching: 2 queries
905 searching: 2 queries
906 query 2; still undecided: 1029, sample size is: 11
906 query 2; still undecided: 1029, sample size is: 11
907 sampling from both directions
907 sampling from both directions
908 searching: 3 queries
908 searching: 3 queries
909 query 3; still undecided: 15, sample size is: 15
909 query 3; still undecided: 15, sample size is: 15
910 3 total queries in *.????s (glob)
910 3 total queries in *.????s (glob)
911 elapsed time: * seconds (glob)
911 elapsed time: * seconds (glob)
912 heads summary:
912 heads summary:
913 total common heads: 1
913 total common heads: 1
914 also local heads: 0
914 also local heads: 0
915 also remote heads: 0
915 also remote heads: 0
916 both: 0
916 both: 0
917 local heads: 1
917 local heads: 1
918 common: 0
918 common: 0
919 missing: 1
919 missing: 1
920 remote heads: 1
920 remote heads: 1
921 common: 0
921 common: 0
922 unknown: 1
922 unknown: 1
923 local changesets: 1030
923 local changesets: 1030
924 common: 1000
924 common: 1000
925 missing: 30
925 missing: 30
926 common heads: 7ead0cba2838
926 common heads: 7ead0cba2838
927
927
928
928
929 One with >200 heads. We now switch to send them all in the initial roundtrip, but still do sampling for the later request.
929 One with >200 heads. We now switch to send them all in the initial roundtrip, but still do sampling for the later request.
930
930
931 $ hg init manyheads
931 $ hg init manyheads
932 $ cd manyheads
932 $ cd manyheads
933 $ echo "+300:r @a" >dagdesc
933 $ echo "+300:r @a" >dagdesc
934 $ echo "*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3 *r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3" >>dagdesc # 20 heads
934 $ echo "*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3 *r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3" >>dagdesc # 20 heads
935 $ echo "*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3 *r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3" >>dagdesc # 20 heads
935 $ echo "*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3 *r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3" >>dagdesc # 20 heads
936 $ echo "*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3 *r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3" >>dagdesc # 20 heads
936 $ echo "*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3 *r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3" >>dagdesc # 20 heads
937 $ echo "*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3 *r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3" >>dagdesc # 20 heads
937 $ echo "*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3 *r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3" >>dagdesc # 20 heads
938 $ echo "*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3 *r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3" >>dagdesc # 20 heads
938 $ echo "*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3 *r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3" >>dagdesc # 20 heads
939 $ echo "*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3 *r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3" >>dagdesc # 20 heads
939 $ echo "*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3 *r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3" >>dagdesc # 20 heads
940 $ echo "*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3 *r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3" >>dagdesc # 20 heads
940 $ echo "*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3 *r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3" >>dagdesc # 20 heads
941 $ echo "*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3 *r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3" >>dagdesc # 20 heads
941 $ echo "*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3 *r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3" >>dagdesc # 20 heads
942 $ echo "*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3 *r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3" >>dagdesc # 20 heads
942 $ echo "*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3 *r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3" >>dagdesc # 20 heads
943 $ echo "*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3 *r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3" >>dagdesc # 20 heads
943 $ echo "*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3 *r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3" >>dagdesc # 20 heads
944 $ echo "*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3 *r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3" >>dagdesc # 20 heads
944 $ echo "*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3 *r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3" >>dagdesc # 20 heads
945 $ echo "*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3 *r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3" >>dagdesc # 20 heads
945 $ echo "*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3 *r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3" >>dagdesc # 20 heads
946 $ echo "*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3 *r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3" >>dagdesc # 20 heads
946 $ echo "*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3 *r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3*r+3" >>dagdesc # 20 heads
947 $ echo "@b *r+3" >>dagdesc # one more head
947 $ echo "@b *r+3" >>dagdesc # one more head
948 $ hg debugbuilddag <dagdesc
948 $ hg debugbuilddag <dagdesc
949 reading DAG from stdin
949 reading DAG from stdin
950
950
951 $ hg heads -t --template . | wc -c
951 $ hg heads -t --template . | wc -c
952 \s*261 (re)
952 \s*261 (re)
953
953
954 $ hg clone -b a . a
954 $ hg clone -b a . a
955 adding changesets
955 adding changesets
956 adding manifests
956 adding manifests
957 adding file changes
957 adding file changes
958 added 1340 changesets with 0 changes to 0 files (+259 heads)
958 added 1340 changesets with 0 changes to 0 files (+259 heads)
959 new changesets 1ea73414a91b:1c51e2c80832
959 new changesets 1ea73414a91b:1c51e2c80832
960 updating to branch a
960 updating to branch a
961 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
961 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
962 $ hg clone -b b . b
962 $ hg clone -b b . b
963 adding changesets
963 adding changesets
964 adding manifests
964 adding manifests
965 adding file changes
965 adding file changes
966 added 304 changesets with 0 changes to 0 files
966 added 304 changesets with 0 changes to 0 files
967 new changesets 1ea73414a91b:513314ca8b3a
967 new changesets 1ea73414a91b:513314ca8b3a
968 updating to branch b
968 updating to branch b
969 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
969 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
970
970
971 $ hg -R a debugdiscovery b --debug --verbose --config progress.debug=true
971 $ hg -R a debugdiscovery b --debug --verbose --config progress.debug=true
972 comparing with b
972 comparing with b
973 query 1; heads
973 query 1; heads
974 searching for changes
974 searching for changes
975 taking quick initial sample
975 taking quick initial sample
976 searching: 2 queries
976 searching: 2 queries
977 query 2; still undecided: 1080, sample size is: 100
977 query 2; still undecided: 1080, sample size is: 100
978 sampling from both directions
978 sampling from both directions
979 searching: 3 queries
979 searching: 3 queries
980 query 3; still undecided: 980, sample size is: 200
980 query 3; still undecided: 980, sample size is: 200
981 sampling from both directions
981 sampling from both directions
982 searching: 4 queries
982 searching: 4 queries
983 query 4; still undecided: \d+, sample size is: 200 (re)
983 query 4; still undecided: 435, sample size is: 210
984 sampling from both directions
984 sampling from both directions
985 searching: 5 queries
985 searching: 5 queries
986 query 5; still undecided: 195, sample size is: 195
986 query 5; still undecided: 185, sample size is: 185
987 5 total queries in *.????s (glob)
987 5 total queries in *.????s (glob)
988 elapsed time: * seconds (glob)
988 elapsed time: * seconds (glob)
989 heads summary:
989 heads summary:
990 total common heads: 1
990 total common heads: 1
991 also local heads: 0
991 also local heads: 0
992 also remote heads: 0
992 also remote heads: 0
993 both: 0
993 both: 0
994 local heads: 260
994 local heads: 260
995 common: 0
995 common: 0
996 missing: 260
996 missing: 260
997 remote heads: 1
997 remote heads: 1
998 common: 0
998 common: 0
999 unknown: 1
999 unknown: 1
1000 local changesets: 1340
1000 local changesets: 1340
1001 common: 300
1001 common: 300
1002 missing: 1040
1002 missing: 1040
1003 common heads: 3ee37d65064a
1003 common heads: 3ee37d65064a
1004 $ hg -R a debugdiscovery b --debug --verbose --config progress.debug=true --rev tip
1004 $ hg -R a debugdiscovery b --debug --verbose --config progress.debug=true --rev tip
1005 comparing with b
1005 comparing with b
1006 query 1; heads
1006 query 1; heads
1007 searching for changes
1007 searching for changes
1008 taking quick initial sample
1008 taking quick initial sample
1009 searching: 2 queries
1009 searching: 2 queries
1010 query 2; still undecided: 303, sample size is: 9
1010 query 2; still undecided: 303, sample size is: 9
1011 sampling from both directions
1011 sampling from both directions
1012 searching: 3 queries
1012 searching: 3 queries
1013 query 3; still undecided: 3, sample size is: 3
1013 query 3; still undecided: 3, sample size is: 3
1014 3 total queries in *.????s (glob)
1014 3 total queries in *.????s (glob)
1015 elapsed time: * seconds (glob)
1015 elapsed time: * seconds (glob)
1016 heads summary:
1016 heads summary:
1017 total common heads: 1
1017 total common heads: 1
1018 also local heads: 0
1018 also local heads: 0
1019 also remote heads: 0
1019 also remote heads: 0
1020 both: 0
1020 both: 0
1021 local heads: 260
1021 local heads: 260
1022 common: 0
1022 common: 0
1023 missing: 260
1023 missing: 260
1024 remote heads: 1
1024 remote heads: 1
1025 common: 0
1025 common: 0
1026 unknown: 1
1026 unknown: 1
1027 local changesets: 1340
1027 local changesets: 1340
1028 common: 300
1028 common: 300
1029 missing: 1040
1029 missing: 1040
1030 common heads: 3ee37d65064a
1030 common heads: 3ee37d65064a
1031
1031
1032 Test actual protocol when pulling one new head in addition to common heads
1032 Test actual protocol when pulling one new head in addition to common heads
1033
1033
1034 $ hg clone -U b c
1034 $ hg clone -U b c
1035 $ hg -R c id -ir tip
1035 $ hg -R c id -ir tip
1036 513314ca8b3a
1036 513314ca8b3a
1037 $ hg -R c up -qr default
1037 $ hg -R c up -qr default
1038 $ touch c/f
1038 $ touch c/f
1039 $ hg -R c ci -Aqm "extra head"
1039 $ hg -R c ci -Aqm "extra head"
1040 $ hg -R c id -i
1040 $ hg -R c id -i
1041 e64a39e7da8b
1041 e64a39e7da8b
1042
1042
1043 $ hg serve -R c -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
1043 $ hg serve -R c -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
1044 $ cat hg.pid >> $DAEMON_PIDS
1044 $ cat hg.pid >> $DAEMON_PIDS
1045
1045
1046 $ hg -R b incoming http://localhost:$HGPORT/ -T '{node|short}\n'
1046 $ hg -R b incoming http://localhost:$HGPORT/ -T '{node|short}\n'
1047 comparing with http://localhost:$HGPORT/
1047 comparing with http://localhost:$HGPORT/
1048 searching for changes
1048 searching for changes
1049 e64a39e7da8b
1049 e64a39e7da8b
1050
1050
1051 $ killdaemons.py
1051 $ killdaemons.py
1052 $ cut -d' ' -f6- access.log | grep -v cmd=known # cmd=known uses random sampling
1052 $ cut -d' ' -f6- access.log | grep -v cmd=known # cmd=known uses random sampling
1053 "GET /?cmd=capabilities HTTP/1.1" 200 -
1053 "GET /?cmd=capabilities HTTP/1.1" 200 -
1054 "GET /?cmd=batch HTTP/1.1" 200 - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D513314ca8b3ae4dac8eec56966265b00fcf866db x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
1054 "GET /?cmd=batch HTTP/1.1" 200 - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D513314ca8b3ae4dac8eec56966265b00fcf866db x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
1055 "GET /?cmd=getbundle HTTP/1.1" 200 - x-hgarg-1:$USUAL_BUNDLE_CAPS$&cg=1&common=513314ca8b3ae4dac8eec56966265b00fcf866db&heads=e64a39e7da8b0d54bc63e81169aff001c13b3477 x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
1055 "GET /?cmd=getbundle HTTP/1.1" 200 - x-hgarg-1:$USUAL_BUNDLE_CAPS$&cg=1&common=513314ca8b3ae4dac8eec56966265b00fcf866db&heads=e64a39e7da8b0d54bc63e81169aff001c13b3477 x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
1056 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=phases x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
1056 "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=phases x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull
1057 $ cat errors.log
1057 $ cat errors.log
1058
1058
1059 $ cd ..
1059 $ cd ..
1060
1060
1061
1061
1062 Issue 4438 - test coverage for 3ef893520a85 issues.
1062 Issue 4438 - test coverage for 3ef893520a85 issues.
1063
1063
1064 $ mkdir issue4438
1064 $ mkdir issue4438
1065 $ cd issue4438
1065 $ cd issue4438
1066 #if false
1066 #if false
1067 generate new bundles:
1067 generate new bundles:
1068 $ hg init r1
1068 $ hg init r1
1069 $ for i in `"$PYTHON" $TESTDIR/seq.py 101`; do hg -R r1 up -qr null && hg -R r1 branch -q b$i && hg -R r1 ci -qmb$i; done
1069 $ for i in `"$PYTHON" $TESTDIR/seq.py 101`; do hg -R r1 up -qr null && hg -R r1 branch -q b$i && hg -R r1 ci -qmb$i; done
1070 $ hg clone -q r1 r2
1070 $ hg clone -q r1 r2
1071 $ for i in `"$PYTHON" $TESTDIR/seq.py 10`; do hg -R r1 up -qr null && hg -R r1 branch -q c$i && hg -R r1 ci -qmc$i; done
1071 $ for i in `"$PYTHON" $TESTDIR/seq.py 10`; do hg -R r1 up -qr null && hg -R r1 branch -q c$i && hg -R r1 ci -qmc$i; done
1072 $ hg -R r2 branch -q r2change && hg -R r2 ci -qmr2change
1072 $ hg -R r2 branch -q r2change && hg -R r2 ci -qmr2change
1073 $ hg -R r1 bundle -qa $TESTDIR/bundles/issue4438-r1.hg
1073 $ hg -R r1 bundle -qa $TESTDIR/bundles/issue4438-r1.hg
1074 $ hg -R r2 bundle -qa $TESTDIR/bundles/issue4438-r2.hg
1074 $ hg -R r2 bundle -qa $TESTDIR/bundles/issue4438-r2.hg
1075 #else
1075 #else
1076 use existing bundles:
1076 use existing bundles:
1077 $ hg init r1
1077 $ hg init r1
1078 $ hg -R r1 -q unbundle $TESTDIR/bundles/issue4438-r1.hg
1078 $ hg -R r1 -q unbundle $TESTDIR/bundles/issue4438-r1.hg
1079 $ hg -R r1 -q up
1079 $ hg -R r1 -q up
1080 $ hg init r2
1080 $ hg init r2
1081 $ hg -R r2 -q unbundle $TESTDIR/bundles/issue4438-r2.hg
1081 $ hg -R r2 -q unbundle $TESTDIR/bundles/issue4438-r2.hg
1082 $ hg -R r2 -q up
1082 $ hg -R r2 -q up
1083 #endif
1083 #endif
1084
1084
1085 Set iteration order could cause wrong and unstable results - fixed in 73cfaa348650:
1085 Set iteration order could cause wrong and unstable results - fixed in 73cfaa348650:
1086
1086
1087 $ hg -R r1 outgoing r2 -T'{rev} '
1087 $ hg -R r1 outgoing r2 -T'{rev} '
1088 comparing with r2
1088 comparing with r2
1089 searching for changes
1089 searching for changes
1090 101 102 103 104 105 106 107 108 109 110 (no-eol)
1090 101 102 103 104 105 106 107 108 109 110 (no-eol)
1091
1091
1092 The case where all the 'initialsamplesize' samples already were common would
1092 The case where all the 'initialsamplesize' samples already were common would
1093 give 'all remote heads known locally' without checking the remaining heads -
1093 give 'all remote heads known locally' without checking the remaining heads -
1094 fixed in 86c35b7ae300:
1094 fixed in 86c35b7ae300:
1095
1095
1096 $ cat >> $TESTTMP/unrandomsample.py << EOF
1096 $ cat >> $TESTTMP/unrandomsample.py << EOF
1097 > import random
1097 > import random
1098 > def sample(population, k):
1098 > def sample(population, k):
1099 > return sorted(population)[:k]
1099 > return sorted(population)[:k]
1100 > random.sample = sample
1100 > random.sample = sample
1101 > EOF
1101 > EOF
1102
1102
1103 $ cat >> r1/.hg/hgrc << EOF
1103 $ cat >> r1/.hg/hgrc << EOF
1104 > [extensions]
1104 > [extensions]
1105 > unrandomsample = $TESTTMP/unrandomsample.py
1105 > unrandomsample = $TESTTMP/unrandomsample.py
1106 > EOF
1106 > EOF
1107
1107
1108 $ hg -R r1 outgoing r2 -T'{rev} ' --config extensions.blackbox= \
1108 $ hg -R r1 outgoing r2 -T'{rev} ' --config extensions.blackbox= \
1109 > --config blackbox.track='command commandfinish discovery'
1109 > --config blackbox.track='command commandfinish discovery'
1110 comparing with r2
1110 comparing with r2
1111 searching for changes
1111 searching for changes
1112 101 102 103 104 105 106 107 108 109 110 (no-eol)
1112 101 102 103 104 105 106 107 108 109 110 (no-eol)
1113 $ hg -R r1 --config extensions.blackbox= blackbox --config blackbox.track=
1113 $ hg -R r1 --config extensions.blackbox= blackbox --config blackbox.track=
1114 * @5d0b986a083e0d91f116de4691e2aaa54d5bbec0 (*)> serve --cmdserver chgunix * (glob) (chg !)
1114 * @5d0b986a083e0d91f116de4691e2aaa54d5bbec0 (*)> serve --cmdserver chgunix * (glob) (chg !)
1115 * @5d0b986a083e0d91f116de4691e2aaa54d5bbec0 (*)> -R r1 outgoing r2 *-T{rev} * --config *extensions.blackbox=* (glob)
1115 * @5d0b986a083e0d91f116de4691e2aaa54d5bbec0 (*)> -R r1 outgoing r2 *-T{rev} * --config *extensions.blackbox=* (glob)
1116 * @5d0b986a083e0d91f116de4691e2aaa54d5bbec0 (*)> found 101 common and 1 unknown server heads, 1 roundtrips in *.????s (glob)
1116 * @5d0b986a083e0d91f116de4691e2aaa54d5bbec0 (*)> found 101 common and 1 unknown server heads, 1 roundtrips in *.????s (glob)
1117 * @5d0b986a083e0d91f116de4691e2aaa54d5bbec0 (*)> -R r1 outgoing r2 *-T{rev} * --config *extensions.blackbox=* exited 0 after *.?? seconds (glob)
1117 * @5d0b986a083e0d91f116de4691e2aaa54d5bbec0 (*)> -R r1 outgoing r2 *-T{rev} * --config *extensions.blackbox=* exited 0 after *.?? seconds (glob)
1118 $ cd ..
1118 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now