Patchwork [8,of,8] commands: allow debugobsolete to delete arbitrary obsmarkers

login
register
mail settings
Submitter Jun Wu
Date April 7, 2016, 2:51 a.m.
Message ID <87531ed836f9aaa4524b.1459997495@waste.org>
Download mbox | patch
Permalink /patch/14418/
State Accepted
Commit f456834b2f7e664250ebbb9e165afa690a296967
Headers show

Comments

Jun Wu - April 7, 2016, 2:51 a.m.
# HG changeset patch
# User Kostia Balytskyi <ikostia@fb.com>
# Date 1459548770 25200
#      Fri Apr 01 15:12:50 2016 -0700
# Node ID 87531ed836f9aaa4524b0d1c40d9a868c43c5902
# Parent  84deb23ba221e545aca3930d6ba9deed78200225
commands: allow debugobsolete to delete arbitrary obsmarkers

Sample usage is:
  '$ hg debugobsolete --delete 0 5'

This is a debug feature that will help people working on evolution and
obsolescense.
timeless - April 7, 2016, 2:53 a.m.
please ignore this series -- I accidentally used pushgate on @committed

On Wed, Apr 6, 2016 at 10:51 PM, Jun Wu <quark@fb.com> wrote:
> # HG changeset patch
> # User Kostia Balytskyi <ikostia@fb.com>
> # Date 1459548770 25200
> #      Fri Apr 01 15:12:50 2016 -0700
> # Node ID 87531ed836f9aaa4524b0d1c40d9a868c43c5902
> # Parent  84deb23ba221e545aca3930d6ba9deed78200225
> commands: allow debugobsolete to delete arbitrary obsmarkers
>
> Sample usage is:
>   '$ hg debugobsolete --delete 0 5'
>
> This is a debug feature that will help people working on evolution and
> obsolescense.
>
> diff --git a/mercurial/commands.py b/mercurial/commands.py
> --- a/mercurial/commands.py
> +++ b/mercurial/commands.py
> @@ -3041,6 +3041,7 @@
>            _('record parent information for the precursor')),
>           ('r', 'rev', [], _('display markers relevant to REV')),
>           ('', 'index', False, _('display index of the marker')),
> +         ('', 'delete', [], _('delete markers specified by indices')),
>          ] + commitopts2,
>           _('[OBSOLETED [REPLACEMENT ...]]'))
>  def debugobsolete(ui, repo, precursor=None, *successors, **opts):
> @@ -3061,6 +3062,32 @@
>              raise error.Abort('changeset references must be full hexadecimal '
>                               'node identifiers')
>
> +    if opts.get('delete'):
> +        try:
> +            indices = [int(v) for v in opts.get('delete')]
> +        except ValueError:
> +            raise error.Abort(_('invalid index value'),
> +                              hint=_('use integers fro indices'))
> +
> +        if repo.currenttransaction():
> +            raise error.Abort(_('Cannot delete obsmarkers in the middle '
> +                                'of transaction.'))
> +
> +        w = repo.wlock()
> +        l = repo.lock()
> +        try:
> +            tr = repo.transaction('debugobsolete')
> +            try:
> +                n = repo.obsstore.delete(indices)
> +                ui.write(_('Deleted %i obsolescense markers\n') % n)
> +                tr.close()
> +            finally:
> +                tr.release()
> +        finally:
> +            l.release()
> +            w.release()
> +        return
> +
>      if precursor is not None:
>          if opts['rev']:
>              raise error.Abort('cannot select revision when creating marker')
> diff --git a/mercurial/obsolete.py b/mercurial/obsolete.py
> --- a/mercurial/obsolete.py
> +++ b/mercurial/obsolete.py
> @@ -628,6 +628,30 @@
>          transaction.hookargs['new_obsmarkers'] = str(previous + len(new))
>          return len(new)
>
> +    def delete(self, indices):
> +        """Delete some obsmarkers from store and return the number of them
> +
> +        Indices is a list of ints which are the indices
> +        of the markers to be deleted."""
> +        if not indices:
> +            # we don't want to rewrite the obsstore with the same content
> +            return
> +
> +        left = []
> +        current = self._all
> +        n = 0
> +        for i, m in enumerate(current):
> +            if i in indices:
> +                n += 1
> +                continue
> +            left.append(m)
> +
> +        newobsstore = self.svfs('obsstore', 'w', atomictemp=True)
> +        for bytes in encodemarkers(left, True, self._version):
> +            newobsstore.write(bytes)
> +        newobsstore.close()
> +        return n
> +
>      def mergemarkers(self, transaction, data):
>          """merge a binary stream of markers inside the obsstore
>
> diff --git a/tests/test-completion.t b/tests/test-completion.t
> --- a/tests/test-completion.t
> +++ b/tests/test-completion.t
> @@ -261,7 +261,7 @@
>    debuglocks: force-lock, force-wlock
>    debugmergestate:
>    debugnamecomplete:
> -  debugobsolete: flags, record-parents, rev, index, date, user
> +  debugobsolete: flags, record-parents, rev, index, delete, date, user
>    debugpathcomplete: full, normal, added, removed
>    debugpushkey:
>    debugpvec:
> diff --git a/tests/test-obsolete.t b/tests/test-obsolete.t
> --- a/tests/test-obsolete.t
> +++ b/tests/test-obsolete.t
> @@ -1083,4 +1083,17 @@
>    |
>    @  0:a78f55e5508c (draft) [ ] 0
>
> +  $ cd ..
>
> +Test the --delete option of debugobsolete command
> +  $ hg init dorepo
> +  $ cd dorepo
> +  $ echo a > a && hg ci -Am a
> +  adding a
> +  $ hg ci --amend -m aa
> +  $ hg debugobsolete
> +  cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b f9bd49731b0b175e42992a3c8fa6c678b2bc11f1 0 (.*) {'user': 'test'} (re)
> +  $ hg debugobsolete --delete 0
> +  Deleted 1 obsolescense markers
> +  $ hg debugobsolete
> +  $ cd ..
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel@mercurial-scm.org
> https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel

Patch

diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -3041,6 +3041,7 @@ 
           _('record parent information for the precursor')),
          ('r', 'rev', [], _('display markers relevant to REV')),
          ('', 'index', False, _('display index of the marker')),
+         ('', 'delete', [], _('delete markers specified by indices')),
         ] + commitopts2,
          _('[OBSOLETED [REPLACEMENT ...]]'))
 def debugobsolete(ui, repo, precursor=None, *successors, **opts):
@@ -3061,6 +3062,32 @@ 
             raise error.Abort('changeset references must be full hexadecimal '
                              'node identifiers')
 
+    if opts.get('delete'):
+        try:
+            indices = [int(v) for v in opts.get('delete')]
+        except ValueError:
+            raise error.Abort(_('invalid index value'),
+                              hint=_('use integers fro indices'))
+
+        if repo.currenttransaction():
+            raise error.Abort(_('Cannot delete obsmarkers in the middle '
+                                'of transaction.'))
+
+        w = repo.wlock()
+        l = repo.lock()
+        try:
+            tr = repo.transaction('debugobsolete')
+            try:
+                n = repo.obsstore.delete(indices)
+                ui.write(_('Deleted %i obsolescense markers\n') % n)
+                tr.close()
+            finally:
+                tr.release()
+        finally:
+            l.release()
+            w.release()
+        return
+
     if precursor is not None:
         if opts['rev']:
             raise error.Abort('cannot select revision when creating marker')
diff --git a/mercurial/obsolete.py b/mercurial/obsolete.py
--- a/mercurial/obsolete.py
+++ b/mercurial/obsolete.py
@@ -628,6 +628,30 @@ 
         transaction.hookargs['new_obsmarkers'] = str(previous + len(new))
         return len(new)
 
+    def delete(self, indices):
+        """Delete some obsmarkers from store and return the number of them
+
+        Indices is a list of ints which are the indices
+        of the markers to be deleted."""
+        if not indices:
+            # we don't want to rewrite the obsstore with the same content
+            return
+
+        left = []
+        current = self._all
+        n = 0
+        for i, m in enumerate(current):
+            if i in indices:
+                n += 1
+                continue
+            left.append(m)
+
+        newobsstore = self.svfs('obsstore', 'w', atomictemp=True)
+        for bytes in encodemarkers(left, True, self._version):
+            newobsstore.write(bytes)
+        newobsstore.close()
+        return n
+
     def mergemarkers(self, transaction, data):
         """merge a binary stream of markers inside the obsstore
 
diff --git a/tests/test-completion.t b/tests/test-completion.t
--- a/tests/test-completion.t
+++ b/tests/test-completion.t
@@ -261,7 +261,7 @@ 
   debuglocks: force-lock, force-wlock
   debugmergestate: 
   debugnamecomplete: 
-  debugobsolete: flags, record-parents, rev, index, date, user
+  debugobsolete: flags, record-parents, rev, index, delete, date, user
   debugpathcomplete: full, normal, added, removed
   debugpushkey: 
   debugpvec: 
diff --git a/tests/test-obsolete.t b/tests/test-obsolete.t
--- a/tests/test-obsolete.t
+++ b/tests/test-obsolete.t
@@ -1083,4 +1083,17 @@ 
   |
   @  0:a78f55e5508c (draft) [ ] 0
   
+  $ cd ..
 
+Test the --delete option of debugobsolete command
+  $ hg init dorepo
+  $ cd dorepo
+  $ echo a > a && hg ci -Am a
+  adding a
+  $ hg ci --amend -m aa
+  $ hg debugobsolete
+  cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b f9bd49731b0b175e42992a3c8fa6c678b2bc11f1 0 (.*) {'user': 'test'} (re)
+  $ hg debugobsolete --delete 0
+  Deleted 1 obsolescense markers
+  $ hg debugobsolete
+  $ cd ..