hgext/strip.py
changeset 20101 80d8bd69b5db
parent 20099 6284b0b16033
parent 20096 88e172871ad7
child 20102 04eaa8eec6a0
--- a/hgext/strip.py	Fri Nov 15 18:41:40 2013 -0800
+++ b/hgext/strip.py	Mon Nov 25 12:18:29 2013 -0600
@@ -119,101 +119,107 @@
     revs = list(revs) + opts.get('rev')
     revs = set(scmutil.revrange(repo, revs))
 
-    if opts.get('bookmark'):
-        mark = opts.get('bookmark')
-        marks = repo._bookmarks
-        if mark not in marks:
-            raise util.Abort(_("bookmark '%s' not found") % mark)
+    wlock = repo.wlock()
+    try:
+        if opts.get('bookmark'):
+            mark = opts.get('bookmark')
+            marks = repo._bookmarks
+            if mark not in marks:
+                raise util.Abort(_("bookmark '%s' not found") % mark)
+
+            # If the requested bookmark is not the only one pointing to a
+            # a revision we have to only delete the bookmark and not strip
+            # anything. revsets cannot detect that case.
+            uniquebm = True
+            for m, n in marks.iteritems():
+                if m != mark and n == repo[mark].node():
+                    uniquebm = False
+                    break
+            if uniquebm:
+                rsrevs = repo.revs("ancestors(bookmark(%s)) - "
+                                   "ancestors(head() and not bookmark(%s)) - "
+                                   "ancestors(bookmark() and not bookmark(%s))",
+                                   mark, mark, mark)
+                revs.update(set(rsrevs))
+            if not revs:
+                del marks[mark]
+                marks.write()
+                ui.write(_("bookmark '%s' deleted\n") % mark)
+
+        if not revs:
+            raise util.Abort(_('empty revision set'))
+
+        descendants = set(cl.descendants(revs))
+        strippedrevs = revs.union(descendants)
+        roots = revs.difference(descendants)
+
+        update = False
+        # if one of the wdir parent is stripped we'll need
+        # to update away to an earlier revision
+        for p in repo.dirstate.parents():
+            if p != nullid and cl.rev(p) in strippedrevs:
+                update = True
+                break
+
+        rootnodes = set(cl.node(r) for r in roots)
 
-        # If the requested bookmark is not the only one pointing to a
-        # a revision we have to only delete the bookmark and not strip
-        # anything. revsets cannot detect that case.
-        uniquebm = True
-        for m, n in marks.iteritems():
-            if m != mark and n == repo[mark].node():
-                uniquebm = False
-                break
-        if uniquebm:
-            rsrevs = repo.revs("ancestors(bookmark(%s)) - "
-                               "ancestors(head() and not bookmark(%s)) - "
-                               "ancestors(bookmark() and not bookmark(%s))",
-                               mark, mark, mark)
-            revs.update(set(rsrevs))
-        if not revs:
+        q = getattr(repo, 'mq', None)
+        if q is not None and q.applied:
+            # refresh queue state if we're about to strip
+            # applied patches
+            if cl.rev(repo.lookup('qtip')) in strippedrevs:
+                q.applieddirty = True
+                start = 0
+                end = len(q.applied)
+                for i, statusentry in enumerate(q.applied):
+                    if statusentry.node in rootnodes:
+                        # if one of the stripped roots is an applied
+                        # patch, only part of the queue is stripped
+                        start = i
+                        break
+                del q.applied[start:end]
+                q.savedirty()
+
+        revs = sorted(rootnodes)
+        if update and opts.get('keep'):
+            wlock = repo.wlock()
+            try:
+                urev, p2 = repo.changelog.parents(revs[0])
+                if (util.safehasattr(repo, 'mq') and p2 != nullid
+                    and p2 in [x.node for x in repo.mq.applied]):
+                    urev = p2
+                uctx = repo[urev]
+
+                # only reset the dirstate for files that would actually change
+                # between the working context and uctx
+                descendantrevs = repo.revs("%s::." % uctx.rev())
+                changedfiles = []
+                for rev in descendantrevs:
+                    # blindly reset the files, regardless of what actually
+                    # changed
+                    changedfiles.extend(repo[rev].files())
+
+                # reset files that only changed in the dirstate too
+                dirstate = repo.dirstate
+                dirchanges = [f for f in dirstate if dirstate[f] != 'n']
+                changedfiles.extend(dirchanges)
+
+                repo.dirstate.rebuild(urev, uctx.manifest(), changedfiles)
+                repo.dirstate.write()
+                update = False
+            finally:
+                wlock.release()
+
+        if opts.get('bookmark'):
+            if mark == repo._bookmarkcurrent:
+                bookmarks.unsetcurrent(repo)
             del marks[mark]
             marks.write()
             ui.write(_("bookmark '%s' deleted\n") % mark)
 
-    if not revs:
-        raise util.Abort(_('empty revision set'))
-
-    descendants = set(cl.descendants(revs))
-    strippedrevs = revs.union(descendants)
-    roots = revs.difference(descendants)
-
-    update = False
-    # if one of the wdir parent is stripped we'll need
-    # to update away to an earlier revision
-    for p in repo.dirstate.parents():
-        if p != nullid and cl.rev(p) in strippedrevs:
-            update = True
-            break
-
-    rootnodes = set(cl.node(r) for r in roots)
-
-    q = getattr(repo, 'mq', None)
-    if q is not None and q.applied:
-        # refresh queue state if we're about to strip
-        # applied patches
-        if cl.rev(repo.lookup('qtip')) in strippedrevs:
-            q.applieddirty = True
-            start = 0
-            end = len(q.applied)
-            for i, statusentry in enumerate(q.applied):
-                if statusentry.node in rootnodes:
-                    # if one of the stripped roots is an applied
-                    # patch, only part of the queue is stripped
-                    start = i
-                    break
-            del q.applied[start:end]
-            q.savedirty()
-
-    revs = sorted(rootnodes)
-    if update and opts.get('keep'):
-        wlock = repo.wlock()
-        try:
-            urev, p2 = repo.changelog.parents(revs[0])
-            if (util.safehasattr(repo, 'mq') and p2 != nullid
-                and p2 in [x.node for x in repo.mq.applied]):
-                urev = p2
-            uctx = repo[urev]
-
-            # only reset the dirstate for files that would actually change
-            # between the working context and uctx
-            descendantrevs = repo.revs("%s::." % uctx.rev())
-            changedfiles = []
-            for rev in descendantrevs:
-                # blindly reset the files, regardless of what actually changed
-                changedfiles.extend(repo[rev].files())
-
-            # reset files that only changed in the dirstate too
-            dirstate = repo.dirstate
-            dirchanges = [f for f in dirstate if dirstate[f] != 'n']
-            changedfiles.extend(dirchanges)
-
-            repo.dirstate.rebuild(urev, uctx.manifest(), changedfiles)
-            repo.dirstate.write()
-            update = False
-        finally:
-            wlock.release()
-
-    if opts.get('bookmark'):
-        if mark == repo._bookmarkcurrent:
-            bookmarks.unsetcurrent(repo)
-        del marks[mark]
-        marks.write()
-        ui.write(_("bookmark '%s' deleted\n") % mark)
-
-    strip(ui, repo, revs, backup=backup, update=update, force=opts.get('force'))
+        strip(ui, repo, revs, backup=backup, update=update,
+              force=opts.get('force'))
+    finally:
+        wlock.release()
 
     return 0