graft: do not use `.remove` on a smart set (regression) stable
authorPierre-Yves David <pierre-yves.david@fb.com>
Mon, 28 Apr 2014 17:25:36 -0700
branchstable
changeset 21200 a1381eea7c7d
parent 21199 e9c2f76be74b
child 21201 c8b9c6147108
graft: do not use `.remove` on a smart set (regression) Revset calls use to return a list. Graft use to mutate that list. We cannot do this anymore leading to a crash when grafting multiple changeset with a revset. File ".../mercurial/commands.py", line 3117, in graft revs.remove(rev) AttributeError: '_addset' object has no attribute 'remove' We are late in code-freeze so we make the shortest possible fix by turning it back to a list.
mercurial/commands.py
tests/test-graft.t
--- a/mercurial/commands.py	Mon Apr 28 15:09:23 2014 -0700
+++ b/mercurial/commands.py	Mon Apr 28 17:25:36 2014 -0700
@@ -3110,10 +3110,14 @@
     # check for ancestors of dest branch
     crev = repo['.'].rev()
     ancestors = repo.changelog.ancestors([crev], inclusive=True)
+    # Cannot use x.remove(y) on smart set, this has to be a list.
+    # XXX make this lazy in the future
+    revs = list(revs)
     # don't mutate while iterating, create a copy
     for rev in list(revs):
         if rev in ancestors:
             ui.warn(_('skipping ancestor revision %s\n') % rev)
+            # XXX remove on list is slow
             revs.remove(rev)
     if not revs:
         return -1
--- a/tests/test-graft.t	Mon Apr 28 15:09:23 2014 -0700
+++ b/tests/test-graft.t	Mon Apr 28 17:25:36 2014 -0700
@@ -571,3 +571,14 @@
   date:        Thu Jan 01 00:00:00 1970 +0000
   summary:     2
   
+
+graft works on complex revset
+
+  $ hg graft 'origin(13) or destination(origin(13))'
+  skipping ancestor revision 21
+  skipping ancestor revision 22
+  skipping revision 2 (already grafted to 22)
+  grafting revision 7
+  grafting revision 13
+  grafting revision 19
+  merging b