[PATCH V2] revert: add support for reverting subrepos
Angel Ezquerra
angel.ezquerra at gmail.com
Sun Oct 9 21:17:52 UTC 2011
On Thu, Oct 6, 2011 at 6:15 PM, Angel Ezquerra <angel.ezquerra at gmail.com> wrote:
> On Thu, Oct 6, 2011 at 5:48 PM, Angel Ezquerra <angel.ezquerra at gmail.com> wrote:
>> # HG changeset patch
>> # User Angel Ezquerra <angel.ezquerra at gmail.com>
>> # Date 1317712886 -7200
>> # Node ID 48f9111208bfbbe831bb514bc133b854c3838d2d
>> # Parent 6dc67dced8c122f6139ae20ccdc03a6b11e8b765
>> revert: add support for reverting subrepos
>>
>> Reverting a subrepo is done by updating it to the revision that is selected on
>> the parent repo .hgsubstate file.
>>
>> * ISSUES/TODO: - I've refactored the revert() function in commands.py to make
>> this change less intrusive. I've moved most of the original revert function
>> into a function called revertfiles(), except the option checking part of the
>> code which is left in the revert() function, which will also call revertfiles()
>> and a new function named revertsubrepos(). These and other helps functions
>> should be moved to some other file? If so, where?
>>
>> - This version of this patch only allows reverting a subrepo if the --no-backup
>> flag is used, since no backups are performed on the contents of the subrepo. It
>> could be possible to add support for backing up the subrepo contents by first
>> performing a "revert --all" on the subrepo, and then updating the subrepo to
>> the proper revision.
>>
>> - The behavior of the --all flag has not been changed: The --all flag will not
>> revert the state of the subrepos. This could be changed as well, but it is left
>> for a later patch (if considered appropriate).
>>
>> - I'm calling update() on the subrepos while a wlock is active. I don't know if
>> this is correct.
>>
>> - I've used ui.status() to show a message while the subrepos are being
>> reverted. However TortoiseHg does not properly capture this message (it shows a
>> dialog box rather than showing the message on its console).
>>
>> diff --git a/mercurial/commands.py b/mercurial/commands.py
>> --- a/mercurial/commands.py
>> +++ b/mercurial/commands.py
>> @@ -4419,11 +4419,31 @@
>> raise util.Abort(_('uncommitted merge with no revision specified'),
>> hint=_('use "hg update" or see "hg help revert"'))
>>
>> + # Get the context of the target revision
>> ctx = scmutil.revsingle(repo, opts.get('rev'))
>> - node = ctx.node()
>> -
>> - if not pats and not opts.get('all'):
>> - msg = _("no files or directories specified")
>> +
>> + # reverting files and subrepos is a very different operation
>> + # separate subrepos from regular files from the pats list
>> + [filepats, subpats] = separatefilesandsubs(pats, ctx)
>> +
>> + if subpats and not opts.get('no_backup'):
>> + # we cannot revert subrepos unless the no_backup flag is set!
>> + msg = _("cannot revert subrepos unless the no-backup flag is set")
>> + hint = _("there are subrepos on the revert list, "
>> + "use --no-backup to revert them")
>> + raise util.Abort(msg, hint=hint)
>> +
>> + # We currently do not support reverting non mercurial subrepos, so check
>> + # that all subrepos on the subrepo list are mercurial subrepos
>> + for sname in subpats:
>> + stype = ctx.substate[sname][2]
>> + if stype != "hg":
>> + msg = _("cannot revert %s subrepo '%s'") % (stype, sname)
>> + hint = _("reverting %s repositories is not supported") % stype
>> + raise util.Abort(msg, hint=hint)
>> +
>> + if not pats and not substate and not opts.get('all'):
>> + msg = _("no files, directories or subrepos specified")
>> if p2 != nullid:
>> hint = _("uncommitted merge, use --all to discard all changes,"
>> " or 'hg update -C .' to abort the merge")
>> @@ -4442,6 +4462,71 @@
>> hint = _("use --all to revert all files")
>> raise util.Abort(msg, hint=hint)
>>
>> + # now we are ready to revert the files and subrepos on the list
>> + revertfiles(ui, repo, ctx, filepats, opts)
>> + revertsubrepos(ui, repo, ctx, subpats, opts)
>> +
>> +def separatefilesandsubs(pats, ctx):
>> + """
>> + Get a list of files, folders and subrepo names and a repository context and
>> + return two lists:
>> + - a list of files and folder names
>> + - a list of subrepo names
>> + """
>> +
>> + if not ctx.substate:
>> + return pats, []
>> +
>> + filepats = []
>> + subpats = []
>> + for p in pats:
>> + if p in ctx.substate:
>> + subpats.append(p)
>> + else:
>> + filepats.append(p)
>> +
>> + return (filepats, subpats)
>> +
>> +def revertsubrepos(ui, repo, ctx, subs, opts):
>> + """
>> + Revert a list of subrepos to the revision given by a particular context
>> +
>> + This function assumes that all the items on the subs list are valid
>> + mercurial subrepos on the target context
>> + """
>> + # we ignore the 'all' option when reverting subrepos
>> + # so we don't check it here
>> + if not subs:
>> + return
>> +
>> + print dir(ctx)
>> + wlock = repo.wlock()
>> + try:
>> + # Revert the subrepos on the revert list
>> + # reverting a subrepo is done by updating it to the revision specified
>> + # in the corresponding substate dictionary
>> + for sname in subs:
>> + ui.status(_('s reverting suprepo %s\n') % sname)
>> + if not opts.get('dry_run'):
>> + substate = ctx.substate[sname]
>> + srepo = ctx.sub(sname)._repo
>> + update(ui, srepo,
>> + node=ctx.substate[sname][1], clean=True)
>> + finally:
>> + wlock.release()
>> +
>> +def revertfiles(ui, repo, ctx, pats, opts):
>> + """
>> + Revert a list of files to the revision given by a particular context
>> +
>> + Assume that the revert options are valid.
>> + """
>> + if not pats and not opts.get('all'):
>> + return
>> +
>> + parent, p2 = repo.dirstate.parents()
>> + node = ctx.node()
>> +
>> mf = ctx.manifest()
>> if node == parent:
>> pmf = mf
>> _______________________________________________
>> Mercurial-devel mailing list
>> Mercurial-devel at selenic.com
>> http://selenic.com/mailman/listinfo/mercurial-devel
>>
>
> In this second version of this patch I tried to follow Greg's advice
> and made the patch easier to read (I hope!). The functionality is the
> same as in the previous version.
>
> One question that I have (and which I stated on the commit message) is
> whether it would be best to move the revertfiles(), revertsubrepos()
> and separatefilesandsubs() helper functions into some other file
> (perhaps into hg.py, as Greg suggested)?
>
> Cheers,
>
> Angel
>
Is there something that I can do to improve this patch? I'd really
like to get this into mercurial 2.0 if possible :-)
For example, should I move the helper functions to some file other
than commands.py?
Angel
More information about the Mercurial-devel
mailing list