prune: add --keep to not touch the working copy
authorDurham Goode <durham@fb.com>
Fri, 20 Mar 2015 12:51:57 -0700
changeset 1221 524dbc8ffeac
parent 1220 71240f696f26
child 1222 88e61e45026d
prune: add --keep to not touch the working copy In order to more closely emulate strip, lets add --keep to leave the working copy untouched when we do our prune.
hgext/evolve.py
tests/test-prune.t
--- a/hgext/evolve.py	Thu Mar 19 12:31:51 2015 -0700
+++ b/hgext/evolve.py	Fri Mar 20 12:51:57 2015 -0700
@@ -1741,6 +1741,7 @@
     [('n', 'new', [], _("successor changeset (DEPRECATED)")),
      ('s', 'succ', [], _("successor changeset")),
      ('r', 'rev', [], _("revisions to prune")),
+     ('k', 'keep', None, _("does not modify working copy during prune")),
      ('', 'biject', False, _("do a 1-1 map between rev and successor ranges")),
      ('B', 'bookmark', '', _("remove revs only reachable from given"
                              " bookmark"))] + metadataopts,
@@ -1833,8 +1834,28 @@
                 newnode = newnode.parents()[0]
 
         if newnode.node() != wdp.node():
-            commands.update(ui, repo, newnode.rev())
-            ui.status(_('working directory now at %s\n') % newnode)
+            if opts.get('keep', False):
+                # This is largely the same as the implementation in
+                # strip.stripcmd(). We might want to refactor this somewhere
+                # common at some point.
+
+                # only reset the dirstate for files that would actually change
+                # between the working context and uctx
+                descendantrevs = repo.revs("%d::." % newnode.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(newnode.node(), newnode.manifest(), changedfiles)
+                repo.dirstate.write()
+            else:
+                commands.update(ui, repo, newnode.rev())
+                ui.status(_('working directory now at %s\n') % newnode)
         # update bookmarks
         if bookmark:
             _deletebookmark(ui, marks, bookmark)
--- a/tests/test-prune.t	Thu Mar 19 12:31:51 2015 -0700
+++ b/tests/test-prune.t	Fri Mar 20 12:51:57 2015 -0700
@@ -238,6 +238,20 @@
   0 files updated, 0 files merged, 1 files removed, 0 files unresolved
   saved backup bundle to $TESTTMP/repo/.hg/strip-backup/c7e58696a948-69ca36d3-backup.hg (glob)
 
+test hg prune --keep
+  $ mkcommit n1
+  created new head
+  $ hg diff -r .^
+  diff -r aa96dc3f04c2 n1
+  --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+  +++ b/n1	* +0000 (glob)
+  @@ -0,0 +1,1 @@
+  +n1
+  $ hg prune -r . --keep
+  1 changesets pruned
+  $ hg status
+  ? n1
+
 test hg prune -B bookmark
 yoinked from test-mq-strip.t