dirstate: warn on invalid parents rather than aborting
This allows more graceful recovery from some mangled dirstates
--- a/hgext/bookmarks.py Mon Nov 22 18:15:58 2010 +0100
+++ b/hgext/bookmarks.py Mon Nov 22 12:43:31 2010 -0600
@@ -348,14 +348,12 @@
return result
def addchangegroup(self, *args, **kwargs):
- parents = self.dirstate.parents()
-
result = super(bookmark_repo, self).addchangegroup(*args, **kwargs)
if result > 1:
# We have more heads than before
return result
node = self.changelog.tip()
-
+ parents = self.dirstate.parents()
self._bookmarksupdate(parents, node)
return result
--- a/mercurial/dirstate.py Mon Nov 22 18:15:58 2010 +0100
+++ b/mercurial/dirstate.py Mon Nov 22 12:43:31 2010 -0600
@@ -36,7 +36,7 @@
class dirstate(object):
- def __init__(self, opener, ui, root):
+ def __init__(self, opener, ui, root, validate):
'''Create a new dirstate object.
opener is an open()-like callable that can be used to open the
@@ -44,6 +44,7 @@
the dirstate.
'''
self._opener = opener
+ self._validate = validate
self._root = root
self._rootdir = os.path.join(root, '')
self._dirty = False
@@ -197,7 +198,7 @@
yield x
def parents(self):
- return self._pl
+ return [self._validate(p) for p in self._pl]
def branch(self):
return self._branch
--- a/mercurial/localrepo.py Mon Nov 22 18:15:58 2010 +0100
+++ b/mercurial/localrepo.py Mon Nov 22 12:43:31 2010 -0600
@@ -178,7 +178,19 @@
@propertycache
def dirstate(self):
- return dirstate.dirstate(self.opener, self.ui, self.root)
+ warned = [0]
+ def validate(node):
+ try:
+ r = self.changelog.rev(node)
+ return node
+ except error.LookupError:
+ if not warned[0]:
+ warned[0] = True
+ self.ui.warn(_("warning: ignoring unknown"
+ " working parent %s!\n" % short(node)))
+ return nullid
+
+ return dirstate.dirstate(self.opener, self.ui, self.root, validate)
def __getitem__(self, changeid):
if changeid is None: