# HG changeset patch # User Sean Farley # Date 1398473913 18000 # Node ID a94ce5400e1b8aaeb2fbce7f5a42bda219f83e8f # Parent 6c5a6c2706f654bbdc1e16a904cbef2a27354a32 evolve: protect call to rebase within a wlock (#42, #35, #16) Without a wlock, repo.commit would blow away the dirstate's parents on OSes that have no 'os.symlink' support in python, leading evolve to produce a merge instead of a rebase. If a user ran the rebase command instead of evolve, then things would work because rebase is wrapped in a giant wlock. Unfortunately, we can't use the same idea of wrapping the evolve command in one giant wlock because that's too early in the process. If the lock did wrap the entire evolve command, then the working directory would save its current parents which, since rebase hasn't been called yet, would be just p1. Therefore, we need to obtain the lock *after* the dirstate's parents are changed but *before* the call to rebase. This way ensures that when a conflict happens the working directory correctly shows both parent changeset. diff -r 6c5a6c2706f6 -r a94ce5400e1b hgext/evolve.py --- a/hgext/evolve.py Wed Apr 23 14:24:02 2014 -0700 +++ b/hgext/evolve.py Fri Apr 25 19:58:33 2014 -0500 @@ -753,7 +753,10 @@ destbookmarks = repo.nodebookmarks(dest.node()) nodesrc = orig.node() destphase = repo[nodesrc].phase() + wlock = lock = None try: + wlock = repo.wlock() + lock = repo.lock() r = rebase.rebasenode(repo, orig.node(), dest.node(), {node.nullrev: node.nullrev}, False) if r[-1]: #some conflict @@ -767,6 +770,8 @@ pass exc.__class__ = LocalMergeFailure raise + finally: + lockmod.release(lock, wlock) oldbookmarks = repo.nodebookmarks(nodesrc) if nodenew is not None: phases.retractboundary(repo, destphase, [nodenew])