[PATCH 3 of 3] histedit: delete histedit statefile on any exception during abort

Augie Fackler raf at durin42.com
Fri Oct 9 10:28:38 CDT 2015


On Thu, Oct 08, 2015 at 03:00:06PM -0700, Christian Delahousse wrote:
> # HG changeset patch
> # User Christian Delahousse <cdelahousse at fb.com>
> # Date 1444088685 25200
> #      Mon Oct 05 16:44:45 2015 -0700
> # Node ID 1035b07658b5d21c80ad1d26c88fe6c63ba81b19
> # Parent  d7088586b95e2efd96f9e9d3a71a4346a211306d
> histedit: delete histedit statefile on any exception during abort

Queued this.

> When an user aborts a histedit, many things could go wrong. At a minimum, after
> a histedit abort failure, their repository should be out of that state. We've
> found situations where the user could not exit the histedit state without
> manually deleting the histedit state file. This patch ensures that if any
> exception happens during an abort, the histedit statefile will be deleted so
> that users are out of the histedit state and can at least manually get the repo
> back to a workable condition.

I guess, though in principle I'd like to see the bugs in this area get
fixed (manual corruption of the state file doesn't really count.)

>
> diff --git a/hgext/histedit.py b/hgext/histedit.py
> --- a/hgext/histedit.py
> +++ b/hgext/histedit.py
> @@ -812,26 +812,35 @@
>          state.write()
>          return
>      elif goal == 'abort':
> -        state.read()
> -        tmpnodes, leafs = newnodestoabort(state)
> -        ui.debug('restore wc to old parent %s\n' % node.short(state.topmost))
> +        try:
> +            state.read()
> +            tmpnodes, leafs = newnodestoabort(state)
> +            ui.debug('restore wc to old parent %s\n'
> +                    % node.short(state.topmost))
>
> -        # Recover our old commits if necessary
> -        if not state.topmost in repo and state.backupfile:
> -            backupfile = repo.join(state.backupfile)
> -            f = hg.openpath(ui, backupfile)
> -            gen = exchange.readbundle(ui, f, backupfile)
> -            changegroup.addchangegroup(repo, gen, 'histedit',
> -                                       'bundle:' + backupfile)
> -            os.remove(backupfile)
> +            # Recover our old commits if necessary
> +            if not state.topmost in repo and state.backupfile:
> +                backupfile = repo.join(state.backupfile)
> +                f = hg.openpath(ui, backupfile)
> +                gen = exchange.readbundle(ui, f, backupfile)
> +                changegroup.addchangegroup(repo, gen, 'histedit',
> +                                        'bundle:' + backupfile)
> +                os.remove(backupfile)
>
> -        # check whether we should update away
> -        if repo.unfiltered().revs('parents() and (%n  or %ln::)',
> -                                  state.parentctxnode, leafs | tmpnodes):
> -            hg.clean(repo, state.topmost)
> -        cleanupnode(ui, repo, 'created', tmpnodes)
> -        cleanupnode(ui, repo, 'temp', leafs)
> -        state.clear()
> +            # check whether we should update away
> +            if repo.unfiltered().revs('parents() and (%n  or %ln::)',
> +                                    state.parentctxnode, leafs | tmpnodes):
> +                hg.clean(repo, state.topmost)
> +            cleanupnode(ui, repo, 'created', tmpnodes)
> +            cleanupnode(ui, repo, 'temp', leafs)
> +        except Exception:
> +            if state.inprogress():
> +                ui.warn(_('warning: encountered an exception during histedit '
> +                    '--abort; the repository may not have been completely '
> +                    'cleaned up\n'))
> +            raise
> +        finally:
> +                state.clear()
>          return
>      else:
>          cmdutil.checkunfinished(repo)
> diff --git a/tests/test-histedit-arguments.t b/tests/test-histedit-arguments.t
> --- a/tests/test-histedit-arguments.t
> +++ b/tests/test-histedit-arguments.t
> @@ -324,3 +324,24 @@
>    |
>    o  0:6058cbb6cfd7 one
>
> +
> +Test that abort fails gracefully on exception
> +----------------------------------------------
> +  $ hg histedit . -q --commands - << EOF
> +  > edit 8fda0c726bf2 6 x
> +  > EOF
> +  Make changes as needed, you may commit or record as needed now.
> +  When you are finished, run hg histedit --continue to resume.
> +  [1]
> +Corrupt histedit state file
> +  $ sed -i 's/8fda0c726bf2/123456789012/' .hg/histedit-state
> +  $ hg histedit --abort
> +  warning: encountered an exception during histedit --abort; the repository may not have been completely cleaned up
> +  abort: No such file or directory: * (glob)
> +  [255]
> +Histedit state has been exited
> +  $ hg summary -q
> +  parent: 5:63379946892c
> +  commit: 1 added, 1 unknown (new branch head)
> +  update: 4 new changesets (update)
> +
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel at selenic.com
> https://selenic.com/mailman/listinfo/mercurial-devel


More information about the Mercurial-devel mailing list