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.
--- a/mercurial/commands.py Fri Apr 01 15:20:31 2016 -0700
+++ b/mercurial/commands.py Fri Apr 01 15:12:50 2016 -0700
@@ -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')
--- a/mercurial/obsolete.py Fri Apr 01 15:20:31 2016 -0700
+++ b/mercurial/obsolete.py Fri Apr 01 15:12:50 2016 -0700
@@ -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
--- a/tests/test-completion.t Fri Apr 01 15:20:31 2016 -0700
+++ b/tests/test-completion.t Fri Apr 01 15:12:50 2016 -0700
@@ -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:
--- a/tests/test-obsolete.t Fri Apr 01 15:20:31 2016 -0700
+++ b/tests/test-obsolete.t Fri Apr 01 15:12:50 2016 -0700
@@ -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 ..