##// END OF EJS Templates
strip: make repair.strip transactional to avoid repository corruption...
strip: make repair.strip transactional to avoid repository corruption Uses a transaction instance from the local repository to journal the truncation of revlog files, such that if a strip only partially completes, hg recover will be able to finish the truncate of all the files. The potential unbundling of changes that have been backed up to be restored later will, in case of an error, have to be unbundled manually. The difference is that it will be possible to recover the repository state so the unbundle can actually succeed.

File last commit:

r7882:8d78fc99 default
r8073:e8a28556 default
Show More
ancestor.py
85 lines | 2.3 KiB | text/x-python | PythonLexer
Matt Mackall
Abstract ancestor algorithm into generic function...
r3135 # ancestor.py - generic DAG ancestor algorithm for mercurial
#
# Copyright 2006 Matt Mackall <mpm@selenic.com>
#
# This software may be used and distributed according to the terms
# of the GNU General Public License, incorporated herein by reference.
import heapq
def ancestor(a, b, pfunc):
"""
return the least common ancestor of nodes a and b or None if there
is no such ancestor.
pfunc must return a list of parent vertices
"""
if a == b:
return a
# find depth from root of all ancestors
Nicolas Dumazet
ancestor: caching the parent list to improve performance...
r7882 parentcache = {}
Matt Mackall
Abstract ancestor algorithm into generic function...
r3135 visit = [a, b]
depth = {}
while visit:
vertex = visit[-1]
pl = pfunc(vertex)
Nicolas Dumazet
ancestor: caching the parent list to improve performance...
r7882 parentcache[vertex] = pl
Matt Mackall
Abstract ancestor algorithm into generic function...
r3135 if not pl:
depth[vertex] = 0
visit.pop()
else:
for p in pl:
if p == a or p == b: # did we find a or b as a parent?
return p # we're done
if p not in depth:
visit.append(p)
if visit[-1] == vertex:
depth[vertex] = min([depth[p] for p in pl]) - 1
visit.pop()
# traverse ancestors in order of decreasing distance from root
def ancestors(vertex):
h = [(depth[vertex], vertex)]
seen = {}
while h:
d, n = heapq.heappop(h)
if n not in seen:
seen[n] = 1
yield (d, n)
Nicolas Dumazet
ancestor: caching the parent list to improve performance...
r7882 for p in parentcache[n]:
Matt Mackall
Abstract ancestor algorithm into generic function...
r3135 heapq.heappush(h, (depth[p], p))
def generations(vertex):
sg, s = None, {}
Thomas Arendsen Hein
white space and line break cleanups
r3673 for g, v in ancestors(vertex):
Matt Mackall
Abstract ancestor algorithm into generic function...
r3135 if g != sg:
if sg:
yield sg, s
sg, s = g, {v:1}
else:
s[v] = 1
yield sg, s
x = generations(a)
y = generations(b)
gx = x.next()
gy = y.next()
# increment each ancestor list until it is closer to root than
# the other, or they match
try:
while 1:
if gx[0] == gy[0]:
for v in gx[1]:
if v in gy[1]:
return v
gy = y.next()
gx = x.next()
elif gx[0] > gy[0]:
gy = y.next()
else:
gx = x.next()
except StopIteration:
return None