[obsolete] published changeset can't be obsoleted
authorPierre-Yves David <pierre-yves.david@ens-lyon.org>
Tue, 13 Sep 2011 22:05:19 +0200
changeset 75 d7b11772f0b5
parent 74 c7dd26dec7fc
child 76 e68f6821ae84
[obsolete] published changeset can't be obsoleted states extension is now required. A warning message is emitted when obsoleting a published changeset.
hgext/obsolete.py
tests/test-obsolete.t
--- a/hgext/obsolete.py	Tue Sep 13 22:19:28 2011 +0200
+++ b/hgext/obsolete.py	Tue Sep 13 22:05:19 2011 +0200
@@ -76,6 +76,7 @@
 except ImportError:
     from StringIO import StringIO
 
+from mercurial.i18n import _
 
 from mercurial import util
 from mercurial import context
@@ -85,7 +86,7 @@
 from mercurial import pushkey
 from mercurial import discovery
 from mercurial import error
-from mercurial.node import hex, bin
+from mercurial.node import hex, bin, short
 from mercurial.lock import release
 
 ### Patch changectx
@@ -95,7 +96,7 @@
     """is the changeset obsolete by other"""
     if ctx.node()is None:
         return False
-    return bool(ctx._repo.obsoletedby(ctx.node()))
+    return bool(ctx._repo.obsoletedby(ctx.node())) and ctx.state().mutable
 
 context.changectx.obsolete = obsolete
 
@@ -107,7 +108,9 @@
     # hack to fill hiddenrevs
     # compute hidden (XXX should move elsewhere)
     if not getattr(ctx._repo.changelog, 'hiddeninit', False):
-        basicquery = 'obsolete() - (ancestors(not obsolete() or . or bookmark()))'
+        shown = ['not obsolete()', '.', 'bookmark()', 'tagged()',
+                 'publishedheads()']
+        basicquery = 'obsolete() - (::(%s))' % (' or '.join(shown))
         for rev in scmutil.revrange(ctx._repo, [basicquery]):
             ctx._repo.changelog.hiddenrevs.add(rev)
         ctx._repo.changelog.hiddeninit = True
@@ -162,6 +165,11 @@
     return common, heads
 
 def extsetup(ui):
+    try:
+        rebase = extensions.find('states')
+    except KeyError:
+        raise error.Abort(_('obsolete extension require states extension.'))
+
     revset.symbols["obsolete"] = revsetobsolete
 
     extensions.wrapfunction(discovery, 'findcommonoutgoing', filterobsoleteout)
@@ -272,8 +280,12 @@
             self._obssubrels.setdefault(sub, set()).add(obj)
             self._obsobjrels.setdefault(obj, set()).add(sub)
             try:
+                if not self.nodestate(obj).mutable:
+                    self.ui.warn(
+                        _("%(sub)s try to obsolete immutable changeset %(obj)s\n")
+                        % {'sub': short(sub), 'obj': short(obj)})
                 self.changelog.hiddenrevs.add(repo[obj].rev())
-            except error.RepoLookupError:
+            except (error.RepoLookupError, error.LookupError):
                 pass #unknow revision (but keep propagating the data
             self._writeobsrels()
 
--- a/tests/test-obsolete.t	Tue Sep 13 22:19:28 2011 +0200
+++ b/tests/test-obsolete.t	Tue Sep 13 22:05:19 2011 +0200
@@ -4,6 +4,7 @@
   > allow_push = *
   > [extensions]
   > EOF
+  $ echo "states=$(echo $(dirname $TESTDIR))/hgext/states.py" >> $HGRCPATH
   $ echo "obsolete=$(echo $(dirname $TESTDIR))/hgext/obsolete.py" >> $HGRCPATH
   $ mkcommit() {
   >    echo "$1" > "$1"
@@ -14,7 +15,9 @@
   $ alias qlog="hg log --template='{rev}\n- {node|short}\n'"
   $ hg init local
   $ cd local
+  $ hg states ready # XXX should be put in default config when state support it
   $ mkcommit a # 0
+  $ hg published 0
   $ mkcommit b # 1
   $ mkcommit c # 2
   $ hg up 1
@@ -72,6 +75,7 @@
 Test communication of obsolete relation with a compatible client
 
   $ hg init ../other-new
+  $ hg -R ../other-new states ready # XXX should be put in default config when state support it
   $ hg push --traceback ../other-new
   pushing to ../other-new
   searching for changes
@@ -159,6 +163,9 @@
 pushing to stuff that doesn't support obsolete
 
   $ hg init ../other-old
+  > # XXX I don't like this but changeset get published otherwise
+  > # remove it when we will get a --keep-state flag for push
+  $ hg -R ../other-old states ready
   $ echo '[extensions]'  > ../other-old/.hg/hgrc
   $ echo "obsolete=!$(echo $(dirname $TESTDIR))/obsolete.py" >> ../other-old/.hg/hgrc
   $ hg push ../other-old
@@ -183,14 +190,20 @@
 clone support
 
   $ hg clone . ../cloned
+  > # The warning should go away once we have default value to set ready before we pull
   requesting all changes
   adding changesets
   adding manifests
   adding file changes
   added 8 changesets with 8 changes to 8 files (+4 heads)
+  909a0fb57e5d try to obsolete immutable changeset 95de7fc6918d
+  95de7fc6918d try to obsolete immutable changeset a7a6f2b5d8a5
+  725c380fe99b try to obsolete immutable changeset 0d3f46688ccc
+  0d3f46688ccc try to obsolete immutable changeset 4538525df7e2
   updating to branch default
   4 files updated, 0 files merged, 0 files removed, 0 files unresolved
 
+  $ hg -R ../cloned states ready # XXX should be put in default config when state support it
   $ qlog -R ../cloned
   7
   - 909a0fb57e5d
@@ -244,3 +257,14 @@
   0
   - 1f0dee641bb7
 
+obsolete published changeset
+
+  $ hg up null
+  0 files updated, 0 files merged, 4 files removed, 0 files unresolved
+  $ mkcommit toto # 8
+  created new head
+  $ hg debugobsolete 8 0
+  159dfc9fa5d3 try to obsolete immutable changeset 1f0dee641bb7
+  $ qlog -r 'obsolete()'
+  3
+  - 0d3f46688ccc