##// END OF EJS Templates
dagutil: fix off-by-one in inverserevlogdag buildup
Peter Arrenbrecht -
r15052:06c3667c stable
parent child Browse files
Show More
@@ -1,277 +1,277 b''
1 # dagutil.py - dag utilities for mercurial
1 # dagutil.py - dag utilities 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 from node import nullrev
9 from node import nullrev
10 from i18n import _
10 from i18n import _
11
11
12
12
13 class basedag(object):
13 class basedag(object):
14 '''generic interface for DAGs
14 '''generic interface for DAGs
15
15
16 terms:
16 terms:
17 "ix" (short for index) identifies a nodes internally,
17 "ix" (short for index) identifies a nodes internally,
18 "id" identifies one externally.
18 "id" identifies one externally.
19
19
20 All params are ixs unless explicitly suffixed otherwise.
20 All params are ixs unless explicitly suffixed otherwise.
21 Pluralized params are lists or sets.
21 Pluralized params are lists or sets.
22 '''
22 '''
23
23
24 def __init__(self):
24 def __init__(self):
25 self._inverse = None
25 self._inverse = None
26
26
27 def nodeset(self):
27 def nodeset(self):
28 '''set of all node idxs'''
28 '''set of all node idxs'''
29 raise NotImplementedError()
29 raise NotImplementedError()
30
30
31 def heads(self):
31 def heads(self):
32 '''list of head ixs'''
32 '''list of head ixs'''
33 raise NotImplementedError()
33 raise NotImplementedError()
34
34
35 def parents(self, ix):
35 def parents(self, ix):
36 '''list of parents ixs of ix'''
36 '''list of parents ixs of ix'''
37 raise NotImplementedError()
37 raise NotImplementedError()
38
38
39 def inverse(self):
39 def inverse(self):
40 '''inverse DAG, where parents becomes children, etc.'''
40 '''inverse DAG, where parents becomes children, etc.'''
41 raise NotImplementedError()
41 raise NotImplementedError()
42
42
43 def ancestorset(self, starts, stops=None):
43 def ancestorset(self, starts, stops=None):
44 '''
44 '''
45 set of all ancestors of starts (incl), but stop walk at stops (excl)
45 set of all ancestors of starts (incl), but stop walk at stops (excl)
46 '''
46 '''
47 raise NotImplementedError()
47 raise NotImplementedError()
48
48
49 def descendantset(self, starts, stops=None):
49 def descendantset(self, starts, stops=None):
50 '''
50 '''
51 set of all descendants of starts (incl), but stop walk at stops (excl)
51 set of all descendants of starts (incl), but stop walk at stops (excl)
52 '''
52 '''
53 return self.inverse().ancestorset(starts, stops)
53 return self.inverse().ancestorset(starts, stops)
54
54
55 def headsetofconnecteds(self, ixs):
55 def headsetofconnecteds(self, ixs):
56 '''
56 '''
57 subset of connected list of ixs so that no node has a descendant in it
57 subset of connected list of ixs so that no node has a descendant in it
58
58
59 By "connected list" we mean that if an ancestor and a descendant are in
59 By "connected list" we mean that if an ancestor and a descendant are in
60 the list, then so is at least one path connecting them.
60 the list, then so is at least one path connecting them.
61 '''
61 '''
62 raise NotImplementedError()
62 raise NotImplementedError()
63
63
64 def externalize(self, ix):
64 def externalize(self, ix):
65 '''return a list of (or set if given a set) of node ids'''
65 '''return a list of (or set if given a set) of node ids'''
66 return self._externalize(ix)
66 return self._externalize(ix)
67
67
68 def externalizeall(self, ixs):
68 def externalizeall(self, ixs):
69 '''return a list of (or set if given a set) of node ids'''
69 '''return a list of (or set if given a set) of node ids'''
70 ids = self._externalizeall(ixs)
70 ids = self._externalizeall(ixs)
71 if isinstance(ixs, set):
71 if isinstance(ixs, set):
72 return set(ids)
72 return set(ids)
73 return list(ids)
73 return list(ids)
74
74
75 def internalize(self, id):
75 def internalize(self, id):
76 '''return a list of (or set if given a set) of node ixs'''
76 '''return a list of (or set if given a set) of node ixs'''
77 return self._internalize(id)
77 return self._internalize(id)
78
78
79 def internalizeall(self, ids, filterunknown=False):
79 def internalizeall(self, ids, filterunknown=False):
80 '''return a list of (or set if given a set) of node ids'''
80 '''return a list of (or set if given a set) of node ids'''
81 ixs = self._internalizeall(ids, filterunknown)
81 ixs = self._internalizeall(ids, filterunknown)
82 if isinstance(ids, set):
82 if isinstance(ids, set):
83 return set(ixs)
83 return set(ixs)
84 return list(ixs)
84 return list(ixs)
85
85
86
86
87 class genericdag(basedag):
87 class genericdag(basedag):
88 '''generic implementations for DAGs'''
88 '''generic implementations for DAGs'''
89
89
90 def ancestorset(self, starts, stops=None):
90 def ancestorset(self, starts, stops=None):
91 stops = stops and set(stops) or set()
91 stops = stops and set(stops) or set()
92 seen = set()
92 seen = set()
93 pending = list(starts)
93 pending = list(starts)
94 while pending:
94 while pending:
95 n = pending.pop()
95 n = pending.pop()
96 if n not in seen and n not in stops:
96 if n not in seen and n not in stops:
97 seen.add(n)
97 seen.add(n)
98 pending.extend(self.parents(n))
98 pending.extend(self.parents(n))
99 return seen
99 return seen
100
100
101 def headsetofconnecteds(self, ixs):
101 def headsetofconnecteds(self, ixs):
102 hds = set(ixs)
102 hds = set(ixs)
103 if not hds:
103 if not hds:
104 return hds
104 return hds
105 for n in ixs:
105 for n in ixs:
106 for p in self.parents(n):
106 for p in self.parents(n):
107 hds.discard(p)
107 hds.discard(p)
108 assert hds
108 assert hds
109 return hds
109 return hds
110
110
111
111
112 class revlogbaseddag(basedag):
112 class revlogbaseddag(basedag):
113 '''generic dag interface to a revlog'''
113 '''generic dag interface to a revlog'''
114
114
115 def __init__(self, revlog, nodeset):
115 def __init__(self, revlog, nodeset):
116 basedag.__init__(self)
116 basedag.__init__(self)
117 self._revlog = revlog
117 self._revlog = revlog
118 self._heads = None
118 self._heads = None
119 self._nodeset = nodeset
119 self._nodeset = nodeset
120
120
121 def nodeset(self):
121 def nodeset(self):
122 return self._nodeset
122 return self._nodeset
123
123
124 def heads(self):
124 def heads(self):
125 if self._heads is None:
125 if self._heads is None:
126 self._heads = self._getheads()
126 self._heads = self._getheads()
127 return self._heads
127 return self._heads
128
128
129 def _externalize(self, ix):
129 def _externalize(self, ix):
130 return self._revlog.index[ix][7]
130 return self._revlog.index[ix][7]
131 def _externalizeall(self, ixs):
131 def _externalizeall(self, ixs):
132 idx = self._revlog.index
132 idx = self._revlog.index
133 return [idx[i][7] for i in ixs]
133 return [idx[i][7] for i in ixs]
134
134
135 def _internalize(self, id):
135 def _internalize(self, id):
136 ix = self._revlog.rev(id)
136 ix = self._revlog.rev(id)
137 if ix == nullrev:
137 if ix == nullrev:
138 raise LookupError(id, self._revlog.indexfile, _('nullid'))
138 raise LookupError(id, self._revlog.indexfile, _('nullid'))
139 return ix
139 return ix
140 def _internalizeall(self, ids, filterunknown):
140 def _internalizeall(self, ids, filterunknown):
141 rl = self._revlog
141 rl = self._revlog
142 if filterunknown:
142 if filterunknown:
143 return [r for r in map(rl.nodemap.get, ids)
143 return [r for r in map(rl.nodemap.get, ids)
144 if r is not None and r != nullrev]
144 if r is not None and r != nullrev]
145 return map(self._internalize, ids)
145 return map(self._internalize, ids)
146
146
147
147
148 class revlogdag(revlogbaseddag):
148 class revlogdag(revlogbaseddag):
149 '''dag interface to a revlog'''
149 '''dag interface to a revlog'''
150
150
151 def __init__(self, revlog):
151 def __init__(self, revlog):
152 revlogbaseddag.__init__(self, revlog, set(xrange(len(revlog))))
152 revlogbaseddag.__init__(self, revlog, set(xrange(len(revlog))))
153
153
154 def _getheads(self):
154 def _getheads(self):
155 return [r for r in self._revlog.headrevs() if r != nullrev]
155 return [r for r in self._revlog.headrevs() if r != nullrev]
156
156
157 def parents(self, ix):
157 def parents(self, ix):
158 rlog = self._revlog
158 rlog = self._revlog
159 idx = rlog.index
159 idx = rlog.index
160 revdata = idx[ix]
160 revdata = idx[ix]
161 prev = revdata[5]
161 prev = revdata[5]
162 if prev != nullrev:
162 if prev != nullrev:
163 prev2 = revdata[6]
163 prev2 = revdata[6]
164 if prev2 == nullrev:
164 if prev2 == nullrev:
165 return [prev]
165 return [prev]
166 return [prev, prev2]
166 return [prev, prev2]
167 prev2 = revdata[6]
167 prev2 = revdata[6]
168 if prev2 != nullrev:
168 if prev2 != nullrev:
169 return [prev2]
169 return [prev2]
170 return []
170 return []
171
171
172 def inverse(self):
172 def inverse(self):
173 if self._inverse is None:
173 if self._inverse is None:
174 self._inverse = inverserevlogdag(self)
174 self._inverse = inverserevlogdag(self)
175 return self._inverse
175 return self._inverse
176
176
177 def ancestorset(self, starts, stops=None):
177 def ancestorset(self, starts, stops=None):
178 rlog = self._revlog
178 rlog = self._revlog
179 idx = rlog.index
179 idx = rlog.index
180 stops = stops and set(stops) or set()
180 stops = stops and set(stops) or set()
181 seen = set()
181 seen = set()
182 pending = list(starts)
182 pending = list(starts)
183 while pending:
183 while pending:
184 rev = pending.pop()
184 rev = pending.pop()
185 if rev not in seen and rev not in stops:
185 if rev not in seen and rev not in stops:
186 seen.add(rev)
186 seen.add(rev)
187 revdata = idx[rev]
187 revdata = idx[rev]
188 for i in [5, 6]:
188 for i in [5, 6]:
189 prev = revdata[i]
189 prev = revdata[i]
190 if prev != nullrev:
190 if prev != nullrev:
191 pending.append(prev)
191 pending.append(prev)
192 return seen
192 return seen
193
193
194 def headsetofconnecteds(self, ixs):
194 def headsetofconnecteds(self, ixs):
195 if not ixs:
195 if not ixs:
196 return set()
196 return set()
197 rlog = self._revlog
197 rlog = self._revlog
198 idx = rlog.index
198 idx = rlog.index
199 headrevs = set(ixs)
199 headrevs = set(ixs)
200 for rev in ixs:
200 for rev in ixs:
201 revdata = idx[rev]
201 revdata = idx[rev]
202 for i in [5, 6]:
202 for i in [5, 6]:
203 prev = revdata[i]
203 prev = revdata[i]
204 if prev != nullrev:
204 if prev != nullrev:
205 headrevs.discard(prev)
205 headrevs.discard(prev)
206 assert headrevs
206 assert headrevs
207 return headrevs
207 return headrevs
208
208
209 def linearize(self, ixs):
209 def linearize(self, ixs):
210 '''linearize and topologically sort a list of revisions
210 '''linearize and topologically sort a list of revisions
211
211
212 The linearization process tries to create long runs of revs where
212 The linearization process tries to create long runs of revs where
213 a child rev comes immediately after its first parent. This is done by
213 a child rev comes immediately after its first parent. This is done by
214 visiting the heads of the given revs in inverse topological order,
214 visiting the heads of the given revs in inverse topological order,
215 and for each visited rev, visiting its second parent, then its first
215 and for each visited rev, visiting its second parent, then its first
216 parent, then adding the rev itself to the output list.
216 parent, then adding the rev itself to the output list.
217 '''
217 '''
218 sorted = []
218 sorted = []
219 visit = list(self.headsetofconnecteds(ixs))
219 visit = list(self.headsetofconnecteds(ixs))
220 visit.sort(reverse=True)
220 visit.sort(reverse=True)
221 finished = set()
221 finished = set()
222
222
223 while visit:
223 while visit:
224 cur = visit.pop()
224 cur = visit.pop()
225 if cur < 0:
225 if cur < 0:
226 cur = -cur - 1
226 cur = -cur - 1
227 if cur not in finished:
227 if cur not in finished:
228 sorted.append(cur)
228 sorted.append(cur)
229 finished.add(cur)
229 finished.add(cur)
230 else:
230 else:
231 visit.append(-cur - 1)
231 visit.append(-cur - 1)
232 visit += [p for p in self.parents(cur)
232 visit += [p for p in self.parents(cur)
233 if p in ixs and p not in finished]
233 if p in ixs and p not in finished]
234 assert len(sorted) == len(ixs)
234 assert len(sorted) == len(ixs)
235 return sorted
235 return sorted
236
236
237
237
238 class inverserevlogdag(revlogbaseddag, genericdag):
238 class inverserevlogdag(revlogbaseddag, genericdag):
239 '''inverse of an existing revlog dag; see revlogdag.inverse()'''
239 '''inverse of an existing revlog dag; see revlogdag.inverse()'''
240
240
241 def __init__(self, orig):
241 def __init__(self, orig):
242 revlogbaseddag.__init__(self, orig._revlog, orig._nodeset)
242 revlogbaseddag.__init__(self, orig._revlog, orig._nodeset)
243 self._orig = orig
243 self._orig = orig
244 self._children = {}
244 self._children = {}
245 self._roots = []
245 self._roots = []
246 self._walkfrom = len(self._revlog) - 1
246 self._walkfrom = len(self._revlog) - 1
247
247
248 def _walkto(self, walkto):
248 def _walkto(self, walkto):
249 rev = self._walkfrom
249 rev = self._walkfrom
250 cs = self._children
250 cs = self._children
251 roots = self._roots
251 roots = self._roots
252 idx = self._revlog.index
252 idx = self._revlog.index
253 while rev >= walkto:
253 while rev >= walkto:
254 data = idx[rev]
254 data = idx[rev]
255 isroot = True
255 isroot = True
256 for prev in [data[5], data[6]]: # parent revs
256 for prev in [data[5], data[6]]: # parent revs
257 if prev != nullrev:
257 if prev != nullrev:
258 cs.setdefault(prev, []).append(rev)
258 cs.setdefault(prev, []).append(rev)
259 isroot = False
259 isroot = False
260 if isroot:
260 if isroot:
261 roots.append(rev)
261 roots.append(rev)
262 rev -= 1
262 rev -= 1
263 self._walkfrom = rev - 1
263 self._walkfrom = rev
264
264
265 def _getheads(self):
265 def _getheads(self):
266 self._walkto(nullrev)
266 self._walkto(nullrev)
267 return self._roots
267 return self._roots
268
268
269 def parents(self, ix):
269 def parents(self, ix):
270 if ix is None:
270 if ix is None:
271 return []
271 return []
272 if ix <= self._walkfrom:
272 if ix <= self._walkfrom:
273 self._walkto(ix)
273 self._walkto(ix)
274 return self._children.get(ix, [])
274 return self._children.get(ix, [])
275
275
276 def inverse(self):
276 def inverse(self):
277 return self._orig
277 return self._orig
@@ -1,268 +1,268 b''
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
17 > hg -R a debugdiscovery b --verbose --debug
18 > echo
18 > echo
19 > echo "% -- b -> a tree"
19 > echo "% -- b -> a tree"
20 > hg -R b debugdiscovery a --verbose --old
20 > hg -R b debugdiscovery a --verbose --old
21 > echo
21 > echo
22 > echo "% -- b -> a set"
22 > echo "% -- b -> a set"
23 > hg -R b debugdiscovery a --verbose --debug
23 > hg -R b debugdiscovery a --verbose --debug
24 > cd ..
24 > cd ..
25 > }
25 > }
26
26
27
27
28 Small superset:
28 Small superset:
29
29
30 $ testdesc '-ra1 -ra2' '-rb1 -rb2 -rb3' '
30 $ testdesc '-ra1 -ra2' '-rb1 -rb2 -rb3' '
31 > +2:f +1:a1:b1
31 > +2:f +1:a1:b1
32 > <f +4 :a2
32 > <f +4 :a2
33 > +5 :b2
33 > +5 :b2
34 > <f +3 :b3'
34 > <f +3 :b3'
35
35
36 % -- a -> b tree
36 % -- a -> b tree
37 comparing with b
37 comparing with b
38 searching for changes
38 searching for changes
39 unpruned common: b5714e113bc0 66f7d451a68b 01241442b3c2
39 unpruned common: b5714e113bc0 66f7d451a68b 01241442b3c2
40 common heads: b5714e113bc0 01241442b3c2
40 common heads: b5714e113bc0 01241442b3c2
41 local is subset
41 local is subset
42
42
43 % -- a -> b set
43 % -- a -> b set
44 comparing with b
44 comparing with b
45 query 1; heads
45 query 1; heads
46 searching for changes
46 searching for changes
47 all local heads known remotely
47 all local heads known remotely
48 common heads: b5714e113bc0 01241442b3c2
48 common heads: b5714e113bc0 01241442b3c2
49 local is subset
49 local is subset
50
50
51 % -- b -> a tree
51 % -- b -> a tree
52 comparing with a
52 comparing with a
53 searching for changes
53 searching for changes
54 unpruned common: b5714e113bc0 01241442b3c2
54 unpruned common: b5714e113bc0 01241442b3c2
55 common heads: b5714e113bc0 01241442b3c2
55 common heads: b5714e113bc0 01241442b3c2
56 remote is subset
56 remote is subset
57
57
58 % -- b -> a set
58 % -- b -> a set
59 comparing with a
59 comparing with a
60 query 1; heads
60 query 1; heads
61 searching for changes
61 searching for changes
62 all remote heads known locally
62 all remote heads known locally
63 common heads: b5714e113bc0 01241442b3c2
63 common heads: b5714e113bc0 01241442b3c2
64 remote is subset
64 remote is subset
65
65
66
66
67 Many new:
67 Many new:
68
68
69 $ testdesc '-ra1 -ra2' '-rb' '
69 $ testdesc '-ra1 -ra2' '-rb' '
70 > +2:f +3:a1 +3:b
70 > +2:f +3:a1 +3:b
71 > <f +30 :a2'
71 > <f +30 :a2'
72
72
73 % -- a -> b tree
73 % -- a -> b tree
74 comparing with b
74 comparing with b
75 searching for changes
75 searching for changes
76 unpruned common: bebd167eb94d
76 unpruned common: bebd167eb94d
77 common heads: bebd167eb94d
77 common heads: bebd167eb94d
78
78
79 % -- a -> b set
79 % -- a -> b set
80 comparing with b
80 comparing with b
81 query 1; heads
81 query 1; heads
82 searching for changes
82 searching for changes
83 taking initial sample
83 taking initial sample
84 searching: 2 queries
84 searching: 2 queries
85 query 2; still undecided: 29, sample size is: 29
85 query 2; still undecided: 29, sample size is: 29
86 2 total queries
86 2 total queries
87 common heads: bebd167eb94d
87 common heads: bebd167eb94d
88
88
89 % -- b -> a tree
89 % -- b -> a tree
90 comparing with a
90 comparing with a
91 searching for changes
91 searching for changes
92 unpruned common: bebd167eb94d 66f7d451a68b
92 unpruned common: bebd167eb94d 66f7d451a68b
93 common heads: bebd167eb94d
93 common heads: bebd167eb94d
94
94
95 % -- b -> a set
95 % -- b -> a set
96 comparing with a
96 comparing with a
97 query 1; heads
97 query 1; heads
98 searching for changes
98 searching for changes
99 taking initial sample
99 taking initial sample
100 searching: 2 queries
100 searching: 2 queries
101 query 2; still undecided: 2, sample size is: 2
101 query 2; still undecided: 2, sample size is: 2
102 2 total queries
102 2 total queries
103 common heads: bebd167eb94d
103 common heads: bebd167eb94d
104
104
105
105
106 Both sides many new with stub:
106 Both sides many new with stub:
107
107
108 $ testdesc '-ra1 -ra2' '-rb' '
108 $ testdesc '-ra1 -ra2' '-rb' '
109 > +2:f +2:a1 +30 :b
109 > +2:f +2:a1 +30 :b
110 > <f +30 :a2'
110 > <f +30 :a2'
111
111
112 % -- a -> b tree
112 % -- a -> b tree
113 comparing with b
113 comparing with b
114 searching for changes
114 searching for changes
115 unpruned common: 2dc09a01254d
115 unpruned common: 2dc09a01254d
116 common heads: 2dc09a01254d
116 common heads: 2dc09a01254d
117
117
118 % -- a -> b set
118 % -- a -> b set
119 comparing with b
119 comparing with b
120 query 1; heads
120 query 1; heads
121 searching for changes
121 searching for changes
122 taking initial sample
122 taking initial sample
123 searching: 2 queries
123 searching: 2 queries
124 query 2; still undecided: 29, sample size is: 29
124 query 2; still undecided: 29, sample size is: 29
125 2 total queries
125 2 total queries
126 common heads: 2dc09a01254d
126 common heads: 2dc09a01254d
127
127
128 % -- b -> a tree
128 % -- b -> a tree
129 comparing with a
129 comparing with a
130 searching for changes
130 searching for changes
131 unpruned common: 66f7d451a68b 2dc09a01254d
131 unpruned common: 66f7d451a68b 2dc09a01254d
132 common heads: 2dc09a01254d
132 common heads: 2dc09a01254d
133
133
134 % -- b -> a set
134 % -- b -> a set
135 comparing with a
135 comparing with a
136 query 1; heads
136 query 1; heads
137 searching for changes
137 searching for changes
138 taking initial sample
138 taking initial sample
139 searching: 2 queries
139 searching: 2 queries
140 query 2; still undecided: 29, sample size is: 29
140 query 2; still undecided: 29, sample size is: 29
141 2 total queries
141 2 total queries
142 common heads: 2dc09a01254d
142 common heads: 2dc09a01254d
143
143
144
144
145 Both many new:
145 Both many new:
146
146
147 $ testdesc '-ra' '-rb' '
147 $ testdesc '-ra' '-rb' '
148 > +2:f +30 :b
148 > +2:f +30 :b
149 > <f +30 :a'
149 > <f +30 :a'
150
150
151 % -- a -> b tree
151 % -- a -> b tree
152 comparing with b
152 comparing with b
153 searching for changes
153 searching for changes
154 unpruned common: 66f7d451a68b
154 unpruned common: 66f7d451a68b
155 common heads: 66f7d451a68b
155 common heads: 66f7d451a68b
156
156
157 % -- a -> b set
157 % -- a -> b set
158 comparing with b
158 comparing with b
159 query 1; heads
159 query 1; heads
160 searching for changes
160 searching for changes
161 taking quick initial sample
161 taking quick initial sample
162 searching: 2 queries
162 searching: 2 queries
163 query 2; still undecided: 31, sample size is: 31
163 query 2; still undecided: 31, sample size is: 31
164 2 total queries
164 2 total queries
165 common heads: 66f7d451a68b
165 common heads: 66f7d451a68b
166
166
167 % -- b -> a tree
167 % -- b -> a tree
168 comparing with a
168 comparing with a
169 searching for changes
169 searching for changes
170 unpruned common: 66f7d451a68b
170 unpruned common: 66f7d451a68b
171 common heads: 66f7d451a68b
171 common heads: 66f7d451a68b
172
172
173 % -- b -> a set
173 % -- b -> a set
174 comparing with a
174 comparing with a
175 query 1; heads
175 query 1; heads
176 searching for changes
176 searching for changes
177 taking quick initial sample
177 taking quick initial sample
178 searching: 2 queries
178 searching: 2 queries
179 query 2; still undecided: 31, sample size is: 31
179 query 2; still undecided: 31, sample size is: 31
180 2 total queries
180 2 total queries
181 common heads: 66f7d451a68b
181 common heads: 66f7d451a68b
182
182
183
183
184 Both many new skewed:
184 Both many new skewed:
185
185
186 $ testdesc '-ra' '-rb' '
186 $ testdesc '-ra' '-rb' '
187 > +2:f +30 :b
187 > +2:f +30 :b
188 > <f +50 :a'
188 > <f +50 :a'
189
189
190 % -- a -> b tree
190 % -- a -> b tree
191 comparing with b
191 comparing with b
192 searching for changes
192 searching for changes
193 unpruned common: 66f7d451a68b
193 unpruned common: 66f7d451a68b
194 common heads: 66f7d451a68b
194 common heads: 66f7d451a68b
195
195
196 % -- a -> b set
196 % -- a -> b set
197 comparing with b
197 comparing with b
198 query 1; heads
198 query 1; heads
199 searching for changes
199 searching for changes
200 taking quick initial sample
200 taking quick initial sample
201 searching: 2 queries
201 searching: 2 queries
202 query 2; still undecided: 51, sample size is: 51
202 query 2; still undecided: 51, sample size is: 51
203 2 total queries
203 2 total queries
204 common heads: 66f7d451a68b
204 common heads: 66f7d451a68b
205
205
206 % -- b -> a tree
206 % -- b -> a tree
207 comparing with a
207 comparing with a
208 searching for changes
208 searching for changes
209 unpruned common: 66f7d451a68b
209 unpruned common: 66f7d451a68b
210 common heads: 66f7d451a68b
210 common heads: 66f7d451a68b
211
211
212 % -- b -> a set
212 % -- b -> a set
213 comparing with a
213 comparing with a
214 query 1; heads
214 query 1; heads
215 searching for changes
215 searching for changes
216 taking quick initial sample
216 taking quick initial sample
217 searching: 2 queries
217 searching: 2 queries
218 query 2; still undecided: 31, sample size is: 31
218 query 2; still undecided: 31, sample size is: 31
219 2 total queries
219 2 total queries
220 common heads: 66f7d451a68b
220 common heads: 66f7d451a68b
221
221
222
222
223 Both many new on top of long history:
223 Both many new on top of long history:
224
224
225 $ testdesc '-ra' '-rb' '
225 $ testdesc '-ra' '-rb' '
226 > +1000:f +30 :b
226 > +1000:f +30 :b
227 > <f +50 :a'
227 > <f +50 :a'
228
228
229 % -- a -> b tree
229 % -- a -> b tree
230 comparing with b
230 comparing with b
231 searching for changes
231 searching for changes
232 unpruned common: 7ead0cba2838
232 unpruned common: 7ead0cba2838
233 common heads: 7ead0cba2838
233 common heads: 7ead0cba2838
234
234
235 % -- a -> b set
235 % -- a -> b set
236 comparing with b
236 comparing with b
237 query 1; heads
237 query 1; heads
238 searching for changes
238 searching for changes
239 taking quick initial sample
239 taking quick initial sample
240 searching: 2 queries
240 searching: 2 queries
241 query 2; still undecided: 1049, sample size is: 11
241 query 2; still undecided: 1049, sample size is: 11
242 sampling from both directions
242 sampling from both directions
243 searching: 3 queries
243 searching: 3 queries
244 query 3; still undecided: 31, sample size is: 31
244 query 3; still undecided: 31, sample size is: 31
245 3 total queries
245 3 total queries
246 common heads: 7ead0cba2838
246 common heads: 7ead0cba2838
247
247
248 % -- b -> a tree
248 % -- b -> a tree
249 comparing with a
249 comparing with a
250 searching for changes
250 searching for changes
251 unpruned common: 7ead0cba2838
251 unpruned common: 7ead0cba2838
252 common heads: 7ead0cba2838
252 common heads: 7ead0cba2838
253
253
254 % -- b -> a set
254 % -- b -> a set
255 comparing with a
255 comparing with a
256 query 1; heads
256 query 1; heads
257 searching for changes
257 searching for changes
258 taking quick initial sample
258 taking quick initial sample
259 searching: 2 queries
259 searching: 2 queries
260 query 2; still undecided: 1029, sample size is: 11
260 query 2; still undecided: 1029, sample size is: 11
261 sampling from both directions
261 sampling from both directions
262 searching: 3 queries
262 searching: 3 queries
263 query 3; still undecided: 16, sample size is: 16
263 query 3; still undecided: 15, sample size is: 15
264 3 total queries
264 3 total queries
265 common heads: 7ead0cba2838
265 common heads: 7ead0cba2838
266
266
267
267
268
268
General Comments 0
You need to be logged in to leave comments. Login now