diff --git a/mercurial/commands.py b/mercurial/commands.py --- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -2673,52 +2673,56 @@ def graft(ui, repo, *revs, **opts): if not revs: return -1 - for pos, ctx in enumerate(repo.set("%ld", revs)): - current = repo['.'] - - ui.status(_('grafting revision %s\n') % ctx.rev()) - if opts.get('dry_run'): - continue - - # we don't merge the first commit when continuing - if not cont: - # perform the graft merge with p1(rev) as 'ancestor' - try: - # ui.forcemerge is an internal variable, do not document - repo.ui.setconfig('ui', 'forcemerge', opts.get('tool', '')) - stats = mergemod.update(repo, ctx.node(), True, True, False, - ctx.p1().node()) - finally: - ui.setconfig('ui', 'forcemerge', '') - # drop the second merge parent - repo.dirstate.setparents(current.node(), nullid) - repo.dirstate.write() - # fix up dirstate for copies and renames - cmdutil.duplicatecopies(repo, ctx.rev(), ctx.p1().rev()) - # report any conflicts - if stats and stats[3] > 0: - # write out state for --continue - nodelines = [repo[rev].hex() + "\n" for rev in revs[pos:]] - repo.opener.write('graftstate', ''.join(nodelines)) - raise util.Abort( - _("unresolved conflicts, can't continue"), - hint=_('use hg resolve and hg graft --continue')) - else: - cont = False - - # commit - source = ctx.extra().get('source') - if not source: - source = ctx.hex() - extra = {'source': source} - user = ctx.user() - if opts.get('user'): - user = opts['user'] - date = ctx.date() - if opts.get('date'): - date = opts['date'] - repo.commit(text=ctx.description(), user=user, - date=date, extra=extra, editor=editor) + wlock = repo.wlock() + try: + for pos, ctx in enumerate(repo.set("%ld", revs)): + current = repo['.'] + + ui.status(_('grafting revision %s\n') % ctx.rev()) + if opts.get('dry_run'): + continue + + # we don't merge the first commit when continuing + if not cont: + # perform the graft merge with p1(rev) as 'ancestor' + try: + # ui.forcemerge is an internal variable, do not document + repo.ui.setconfig('ui', 'forcemerge', opts.get('tool', '')) + stats = mergemod.update(repo, ctx.node(), True, True, False, + ctx.p1().node()) + finally: + ui.setconfig('ui', 'forcemerge', '') + # drop the second merge parent + repo.dirstate.setparents(current.node(), nullid) + repo.dirstate.write() + # fix up dirstate for copies and renames + cmdutil.duplicatecopies(repo, ctx.rev(), ctx.p1().rev()) + # report any conflicts + if stats and stats[3] > 0: + # write out state for --continue + nodelines = [repo[rev].hex() + "\n" for rev in revs[pos:]] + repo.opener.write('graftstate', ''.join(nodelines)) + raise util.Abort( + _("unresolved conflicts, can't continue"), + hint=_('use hg resolve and hg graft --continue')) + else: + cont = False + + # commit + source = ctx.extra().get('source') + if not source: + source = ctx.hex() + extra = {'source': source} + user = ctx.user() + if opts.get('user'): + user = opts['user'] + date = ctx.date() + if opts.get('date'): + date = opts['date'] + repo.commit(text=ctx.description(), user=user, + date=date, extra=extra, editor=editor) + finally: + wlock.release() # remove state when we complete successfully if not opts.get('dry_run') and os.path.exists(repo.join('graftstate')): diff --git a/tests/test-graft.t b/tests/test-graft.t --- a/tests/test-graft.t +++ b/tests/test-graft.t @@ -242,12 +242,12 @@ Graft again onto another branch should p 2:5c095ad7e90f871700f02dd1fa5012cb4498a2d4 $ hg log --debug -r tip - changeset: 13:39bb1d13572759bd1e6fc874fed1b12ece047a18 + changeset: 13:95adbe5de6b10f376b699ece9ed5a57cd7b4b0f6 tag: tip phase: draft parent: 12:b592ea63bb0c19a6c5c44685ee29a2284f9f1b8f parent: -1:0000000000000000000000000000000000000000 - manifest: 13:0780e055d8f4cd12eadd5a2719481648f336f7a9 + manifest: 13:9944044f82a462bbaccc9bdf7e0ac5b811db7d1b user: foo date: Thu Jan 01 00:00:00 1970 +0000 files+: b