Mercurial > hg > evolve
changeset 1839:299cdaa24fa5
merge with stable
author | Pierre-Yves David <pierre-yves.david@ens-lyon.org> |
---|---|
date | Sun, 16 Oct 2016 20:29:27 +0200 |
parents | cb5edd4b160c (current diff) 970a4c13ebc3 (diff) |
children | 6c922448ccec f746f787f82c |
files | README hgext/evolve.py tests/test-prev-next.t |
diffstat | 4 files changed, 178 insertions(+), 130 deletions(-) [+] |
line wrap: on
line diff
--- a/README +++ b/README @@ -63,6 +63,9 @@ 5.4.2 -- - Fix erroneous manifest computation when solving 'bumped' changeset. + - split: avoid crash on empty commit (issue5191), + - next: improve locking to avoid issue with working copy parent (issue5244) + - prev: improve locking to avoid issue with working copy parent (issue5244) 5.4.1 -- 2016-08-01
--- a/hgext/evolve.py +++ b/hgext/evolve.py @@ -2213,57 +2213,63 @@ """update to parent revision Displays the summary line of the destination for clarity.""" - wkctx = repo[None] - wparents = wkctx.parents() + wlock = None dryrunopt = opts['dry_run'] - if len(wparents) != 1: - raise error.Abort('merge in progress') - if not opts['merge']: - try: - cmdutil.bailifchanged(repo) - except error.Abort as exc: - exc.hint = _('do you want --merge?') - raise - - parents = wparents[0].parents() - topic = getattr(repo, 'currenttopic', '') - if topic and not opts.get("no_topic", False): - parents = [ctx for ctx in parents if ctx.topic() == topic] - displayer = cmdutil.show_changeset(ui, repo, {'template': shorttemplate}) - if not parents: - ui.warn(_('no parent in topic "%s"\n') % topic) - ui.warn(_('(do you want --no-topic)\n')) - elif len(parents) == 1: - p = parents[0] - bm = bmactive(repo) - shouldmove = opts.get('move_bookmark') and bm is not None - if dryrunopt: - ui.write(('hg update %s;\n' % p.rev())) - if shouldmove: - ui.write(('hg bookmark %s -r %s;\n' % (bm, p.rev()))) + if not dryrunopt: + wlock = repo.wlock() + try: + wkctx = repo[None] + wparents = wkctx.parents() + if len(wparents) != 1: + raise error.Abort('merge in progress') + if not opts['merge']: + try: + cmdutil.bailifchanged(repo) + except error.Abort as exc: + exc.hint = _('do you want --merge?') + raise + + parents = wparents[0].parents() + topic = getattr(repo, 'currenttopic', '') + if topic and not opts.get("no_topic", False): + parents = [ctx for ctx in parents if ctx.topic() == topic] + displayer = cmdutil.show_changeset(ui, repo, {'template': shorttemplate}) + if not parents: + ui.warn(_('no parent in topic "%s"\n') % topic) + ui.warn(_('(do you want --no-topic)\n')) + elif len(parents) == 1: + p = parents[0] + bm = bmactive(repo) + shouldmove = opts.get('move_bookmark') and bm is not None + if dryrunopt: + ui.write(('hg update %s;\n' % p.rev())) + if shouldmove: + ui.write(('hg bookmark %s -r %s;\n' % (bm, p.rev()))) + else: + ret = hg.update(repo, p.rev()) + if not ret: + tr = lock = None + try: + lock = repo.lock() + tr = repo.transaction('previous') + if shouldmove: + repo._bookmarks[bm] = p.node() + repo._bookmarks.recordchange(tr) + else: + bmdeactivate(repo) + tr.close() + finally: + lockmod.release(tr, lock) + + displayer.show(p) + return 0 else: - ret = hg.update(repo, p.rev()) - if not ret: - tr = lock = None - wlock = repo.wlock() - try: - lock = repo.lock() - tr = repo.transaction('previous') - if shouldmove: - repo._bookmarks[bm] = p.node() - repo._bookmarks.recordchange(tr) - else: - bmdeactivate(repo) - tr.close() - finally: - lockmod.release(tr, lock, wlock) - displayer.show(p) - return 0 - else: - for p in parents: - displayer.show(p) - ui.warn(_('multiple parents, explicitly update to one\n')) - return 1 + for p in parents: + displayer.show(p) + ui.warn(_('multiple parents, explicitly update to one\n')) + return 1 + finally: + lockmod.release(wlock) @command('^next', [('B', 'move-bookmark', False, @@ -2281,91 +2287,96 @@ Displays the summary line of the destination for clarity. """ - wkctx = repo[None] - wparents = wkctx.parents() + wlock = None dryrunopt = opts['dry_run'] - if len(wparents) != 1: - raise error.Abort('merge in progress') - if not opts['merge']: - try: - cmdutil.bailifchanged(repo) - except error.Abort as exc: - exc.hint = _('do you want --merge?') - raise - - children = [ctx for ctx in wparents[0].children() if not ctx.obsolete()] - topic = getattr(repo, 'currenttopic', '') - filtered = [] - if topic and not opts.get("no_topic", False): - filtered = [ctx for ctx in children if ctx.topic() != topic] - # XXX N-square membership on children - children = [ctx for ctx in children if ctx not in filtered] - displayer = cmdutil.show_changeset(ui, repo, {'template': shorttemplate}) - if len(children) == 1: - c = children[0] - bm = bmactive(repo) - shouldmove = opts.get('move_bookmark') and bm is not None - if dryrunopt: - ui.write(('hg update %s;\n' % c.rev())) - if shouldmove: - ui.write(('hg bookmark %s -r %s;\n' % (bm, c.rev()))) + if not dryrunopt: + wlock = repo.wlock() + try: + wkctx = repo[None] + wparents = wkctx.parents() + if len(wparents) != 1: + raise error.Abort('merge in progress') + if not opts['merge']: + try: + cmdutil.bailifchanged(repo) + except error.Abort as exc: + exc.hint = _('do you want --merge?') + raise + + children = [ctx for ctx in wparents[0].children() if not ctx.obsolete()] + topic = getattr(repo, 'currenttopic', '') + filtered = [] + if topic and not opts.get("no_topic", False): + filtered = [ctx for ctx in children if ctx.topic() != topic] + # XXX N-square membership on children + children = [ctx for ctx in children if ctx not in filtered] + displayer = cmdutil.show_changeset(ui, repo, {'template': shorttemplate}) + if len(children) == 1: + c = children[0] + bm = bmactive(repo) + shouldmove = opts.get('move_bookmark') and bm is not None + if dryrunopt: + ui.write(('hg update %s;\n' % c.rev())) + if shouldmove: + ui.write(('hg bookmark %s -r %s;\n' % (bm, c.rev()))) + else: + ret = hg.update(repo, c.rev()) + if not ret: + lock = tr = None + try: + lock = repo.lock() + tr = repo.transaction('next') + if shouldmove: + repo._bookmarks[bm] = c.node() + repo._bookmarks.recordchange(tr) + else: + bmdeactivate(repo) + tr.close() + finally: + lockmod.release(tr, lock) + displayer.show(c) + result = 0 + elif children: + ui.warn(_("ambigious next changeset:\n")) + for c in children: + displayer.show(c) + ui.warn(_('explicitly update to one of them\n')) + result = 1 else: - ret = hg.update(repo, c.rev()) - if not ret: - lock = tr = None - wlock = repo.wlock() - try: - lock = repo.lock() - tr = repo.transaction('next') - if shouldmove: - repo._bookmarks[bm] = c.node() - repo._bookmarks.recordchange(tr) - else: - bmdeactivate(repo) - tr.close() - finally: - lockmod.release(tr, lock, wlock) - displayer.show(c) - result = 0 - elif children: - ui.warn(_("ambigious next changeset:\n")) - for c in children: - displayer.show(c) - ui.warn(_('explicitly update to one of them\n')) - result = 1 - else: - aspchildren = _aspiringchildren(repo, [repo['.'].rev()]) - if topic: - filtered.extend(repo[c] for c in children - if repo[c].topic() != topic) - # XXX N-square membership on children - aspchildren = [ctx for ctx in aspchildren if ctx not in filtered] - if not opts['evolve'] or not aspchildren: - if filtered: - ui.warn(_('no children on topic "%s"\n') % topic) - ui.warn(_('do you want --no-topic\n')) + aspchildren = _aspiringchildren(repo, [repo['.'].rev()]) + if topic: + filtered.extend(repo[c] for c in children + if repo[c].topic() != topic) + # XXX N-square membership on children + aspchildren = [ctx for ctx in aspchildren if ctx not in filtered] + if not opts['evolve'] or not aspchildren: + if filtered: + ui.warn(_('no children on topic "%s"\n') % topic) + ui.warn(_('do you want --no-topic\n')) + else: + ui.warn(_('no children\n')) + if aspchildren: + msg = _('(%i unstable changesets to be evolved here, ' + 'do you want --evolve?)\n') + ui.warn(msg % len(aspchildren)) + result = 1 + elif 1 < len(aspchildren): + ui.warn(_("ambigious next (unstable) changeset:\n")) + for c in aspchildren: + displayer.show(repo[c]) + ui.warn(_('(run "hg evolve --rev REV" on one of them)\n')) + return 1 else: - ui.warn(_('no children\n')) - if aspchildren: - msg = _('(%i unstable changesets to be evolved here, ' - 'do you want --evolve?)\n') - ui.warn(msg % len(aspchildren)) - result = 1 - elif 1 < len(aspchildren): - ui.warn(_("ambigious next (unstable) changeset:\n")) - for c in aspchildren: - displayer.show(repo[c]) - ui.warn(_('(run "hg evolve --rev REV" on one of them)\n')) + cmdutil.bailifchanged(repo) + result = _solveone(ui, repo, repo[aspchildren[0]], dryrunopt, + False, lambda:None, category='unstable') + if not result: + ui.status(_('working directory now at %s\n') % repo['.']) + return result return 1 - else: - cmdutil.bailifchanged(repo) - result = _solveone(ui, repo, repo[aspchildren[0]], dryrunopt, - False, lambda:None, category='unstable') - if not result: - ui.status(_('working directory now at %s\n') % repo['.']) - return result - return 1 - return result + return result + finally: + lockmod.release(wlock) def _reachablefrombookmark(repo, revs, bookmarks): """filter revisions and bookmarks reachable from the given bookmark
new file mode 100755 --- /dev/null +++ b/tests/fake-editor.sh @@ -0,0 +1,3 @@ +#!/bin/sh +sleep 5 +echo "new desc" >> $1
--- a/tests/test-prev-next.t +++ b/tests/test-prev-next.t @@ -206,3 +206,34 @@ move:[5] added d atop:[6] added b (3) working directory is now at 47ea25be8aea + +prev and next should lock properly against other commands + + $ hg init repo + $ cd repo + $ HGEDITOR=${TESTDIR}/fake-editor.sh + $ echo hi > foo + $ hg ci -Am 'one' + adding foo + $ echo bye > foo + $ hg ci -Am 'two' + + $ hg amend --edit & + $ sleep 1 + $ hg prev + waiting for lock on working directory of $TESTTMP/repo held by process '*' on host '*' (glob) + got lock after [4-6] seconds (re) + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved + [0] one + $ wait + + $ hg amend --edit & + $ sleep 1 + $ hg next --evolve + waiting for lock on working directory of $TESTTMP/repo held by process '*' on host '*' (glob) + 1 new unstable changesets + got lock after [4-6] seconds (re) + move:[2] two + atop:[3] one + working directory now at a7d885c75614 + $ wait