[PATCH 2 of 2] commands: allow debugobsolete to delete arbitrary obsmarkers
Kostia Balytskyi
ikostia at fb.com
Fri Apr 1 14:36:40 EDT 2016
On 4/1/16, 7:31 PM, "Pierre-Yves David" <pierre-yves.david at ens-lyon.org> wrote:
>
>
>On 04/01/2016 08:56 AM, Kostia Balytskyi wrote:
>> # HG changeset patch
>> # User Kostia Balytskyi <ikostia at fb.com>
>> # Date 1459525644 25200
>> # Fri Apr 01 08:47:24 2016 -0700
>> # Node ID ff46f27e8fca7b726cc042eb745e54a3bc9dbe39
>> # Parent d4fc1ec31c6666d85eb2e8c174f6c231546ad8fd
>> 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
>> @@ -3046,6 +3046,7 @@ def debuglocks(ui, repo, **opts):
>> _('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):
>> @@ -3066,6 +3067,16 @@ def debugobsolete(ui, repo, precursor=No
>> 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'))
>> + n = repo.obsstore.delete(indices)
>
>We'll want some locking around this to prevent other process reading the
>repository to misbehave.
>
>> + ui.write(_('Deleted %i obsolescense markers\n') % n)
>> + 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
>> @@ -633,6 +633,30 @@ class obsstore(object):
>> 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
>> +
>
>We probably want to have this somewhat collaborating with the
>transaction, like mercurial.repair.strip do. At least we want to ensure
>we are not in a transaction before butchering the obstore.
Why do we want transaction if we're writing to the atomictemp file? AFAIK,
it will write the new stuff into a temporary file and atomically rename it
when we call close. Why isn't it good enough?
>
>(and that we are locked)
>
>> def mergemarkers(self, transaction, data):
>> """merge a binary stream of markers inside the obsstore
>
>
>--
>Pierre-Yves David
More information about the Mercurial-devel
mailing list