# HG changeset patch # User Boris Feld # Date 2018-01-11 11:57:59 # Node ID 4b68ca118d8d316cff1fbfe260e8fdb0dae3e26a # Parent 45a8163619266ed71cc65c1413a62bc2f997b4a0 pull: hold wlock for the full operation when --update is used With now, the wlock is not held between the pull and the update. This can lead to race condition and make logic checking to post pull results more complicated (eg: with _afterlock). diff --git a/mercurial/commands.py b/mercurial/commands.py --- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -4007,36 +4007,40 @@ def pull(ui, repo, source="default", **o "so a rev cannot be specified.") raise error.Abort(err) - pullopargs.update(opts.get('opargs', {})) - modheads = exchange.pull(repo, other, heads=revs, - force=opts.get('force'), - bookmarks=opts.get('bookmark', ()), - opargs=pullopargs).cgresult - - # brev is a name, which might be a bookmark to be activated at - # the end of the update. In other words, it is an explicit - # destination of the update - brev = None - - if checkout: - checkout = str(repo.changelog.rev(checkout)) - - # order below depends on implementation of - # hg.addbranchrevs(). opts['bookmark'] is ignored, - # because 'checkout' is determined without it. - if opts.get('rev'): - brev = opts['rev'][0] - elif opts.get('branch'): - brev = opts['branch'][0] - else: - brev = branches[0] - repo._subtoppath = source - try: - ret = postincoming(ui, repo, modheads, opts.get('update'), - checkout, brev) - - finally: - del repo._subtoppath + wlock = util.nullcontextmanager() + if opts.get('update'): + wlock = repo.wlock() + with wlock: + pullopargs.update(opts.get('opargs', {})) + modheads = exchange.pull(repo, other, heads=revs, + force=opts.get('force'), + bookmarks=opts.get('bookmark', ()), + opargs=pullopargs).cgresult + + # brev is a name, which might be a bookmark to be activated at + # the end of the update. In other words, it is an explicit + # destination of the update + brev = None + + if checkout: + checkout = str(repo.changelog.rev(checkout)) + + # order below depends on implementation of + # hg.addbranchrevs(). opts['bookmark'] is ignored, + # because 'checkout' is determined without it. + if opts.get('rev'): + brev = opts['rev'][0] + elif opts.get('branch'): + brev = opts['branch'][0] + else: + brev = branches[0] + repo._subtoppath = source + try: + ret = postincoming(ui, repo, modheads, opts.get('update'), + checkout, brev) + + finally: + del repo._subtoppath finally: other.close() diff --git a/tests/test-keyword.t b/tests/test-keyword.t --- a/tests/test-keyword.t +++ b/tests/test-keyword.t @@ -262,6 +262,7 @@ Pull from bundle and trigger notify adding file changes added 2 changesets with 3 changes to 3 files new changesets a2392c293916:ef63ca68695b + 3 files updated, 0 files merged, 0 files removed, 0 files unresolved MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit @@ -314,7 +315,6 @@ Pull from bundle and trigger notify +++ b/b Thu Jan 01 00:00:00 1970 +0000 @@ -0,0 +1,1 @@ +ignore $Id$ - 3 files updated, 0 files merged, 0 files removed, 0 files unresolved $ cp $HGRCPATH.nohooks $HGRCPATH