3 # Copyright 2006 Matt Mackall <mpm@selenic.com> |
3 # Copyright 2006 Matt Mackall <mpm@selenic.com> |
4 # |
4 # |
5 # This software may be used and distributed according to the terms of the |
5 # This software may be used and distributed according to the terms of the |
6 # GNU General Public License version 2 or any later version. |
6 # GNU General Public License version 2 or any later version. |
7 |
7 |
8 import error, heapq, util |
8 import heapq, util |
9 from node import nullrev |
9 from node import nullrev |
10 |
10 |
11 def ancestors(pfunc, *orignodes): |
11 def ancestors(pfunc, *orignodes): |
12 """ |
12 """ |
13 Returns the common ancestors of a and b that are furthest from a |
13 Returns the common ancestors of a and b that are furthest from a |
211 else: |
211 else: |
212 gx = x.next() |
212 gx = x.next() |
213 except StopIteration: |
213 except StopIteration: |
214 return None |
214 return None |
215 |
215 |
216 def finddepths(nodes, pfunc): |
|
217 visit = list(nodes) |
|
218 rootpl = [nullrev, nullrev] |
|
219 depth = {} |
|
220 while visit: |
|
221 vertex = visit[-1] |
|
222 pl = pfunc(vertex) |
|
223 if not pl or pl == rootpl: |
|
224 depth[vertex] = 0 |
|
225 visit.pop() |
|
226 else: |
|
227 for p in pl: |
|
228 if p != nullrev and p not in depth: |
|
229 visit.append(p) |
|
230 if visit[-1] == vertex: |
|
231 dp = [depth[p] for p in pl if p != nullrev] |
|
232 if dp: |
|
233 depth[vertex] = max(dp) + 1 |
|
234 else: |
|
235 depth[vertex] = 0 |
|
236 visit.pop() |
|
237 return depth |
|
238 |
|
239 def ancestor(a, b, pfunc): |
|
240 xs = ancestors(pfunc, a, b) |
|
241 y = genericancestor(a, b, pfunc) |
|
242 if y == -1: |
|
243 y = None |
|
244 if not xs: |
|
245 if y is None: |
|
246 return None |
|
247 print xs, y |
|
248 raise error.RepoError('ancestors disagree on whether a gca exists') |
|
249 elif y is None: |
|
250 print xs, y |
|
251 raise error.RepoError('ancestors disagree on whether a gca exists') |
|
252 if y in xs: |
|
253 return y |
|
254 xds = finddepths(xs, pfunc) |
|
255 xds = [ds[x] for x in xs] |
|
256 yd = finddepths([y], pfunc)[y] |
|
257 if len([xd != yd for xd in xds]) > 0: |
|
258 raise error.RepoError('ancestor depths do not match') |
|
259 return xs.pop() |
|
260 |
|
261 def missingancestors(revs, bases, pfunc): |
216 def missingancestors(revs, bases, pfunc): |
262 """Return all the ancestors of revs that are not ancestors of bases. |
217 """Return all the ancestors of revs that are not ancestors of bases. |
263 |
218 |
264 This may include elements from revs. |
219 This may include elements from revs. |
265 |
220 |