# HG changeset patch # User Pierre-Yves David # Date 1391159045 28800 # Node ID 2607a21bb40b251fa317b4821d9451534a871038 # Parent 1180c6ec5695ad1643db4201afd58b8eb6b74e0c pull: move transaction logic into the pull object Most local change that occurs during a pull are doing within a `transaction`. Currently this mean (1) adding new changeset (2) adding obsolescence markers. We want the two operations to be done in the same transaction. However we do not want to create a transaction if nothing is added to the repo. Creating an empty transaction would drop the previous transaction data and confuse tool and people who are still using rollback. So the current pull code has some logic to create and handle this transaction on demand. We are moving this logic in to the `pulloperation` object itself to simplify this lazy creation logic through all different par of the push. Note that, in the future, other part of pull (phases, bookmark) will probably want to be part of the transaction too. diff -r 1180c6ec5695 -r 2607a21bb40b mercurial/exchange.py --- a/mercurial/exchange.py Thu Jan 30 17:38:41 2014 -0800 +++ b/mercurial/exchange.py Fri Jan 31 01:04:05 2014 -0800 @@ -391,6 +391,26 @@ self.heads = heads # do we force pull? self.force = force + # the name the pull transaction + self._trname = 'pull\n' + util.hidepassword(remote.url()) + # hold the transaction once created + self._tr = None + + def gettransaction(self): + """get appropriate pull transaction, creating it if needed""" + if self._tr is None: + self._tr = self.repo.transaction(self._trname) + return self._tr + + def closetransaction(self): + """close transaction if created""" + if self._tr is not None: + self._tr.close() + + def releasetransaction(self): + """release transaction if created""" + if self._tr is not None: + self._tr.release() def pull(repo, remote, heads=None, force=False): pullop = pulloperation(repo, remote, heads, force) @@ -402,10 +422,6 @@ " %s") % (', '.join(sorted(missing))) raise util.Abort(msg) - # don't open transaction for nothing or you break future useful - # rollback call - tr = None - trname = 'pull\n' + util.hidepassword(pullop.remote.url()) lock = pullop.repo.lock() try: tmp = discovery.findcommonincoming(pullop.repo.unfiltered(), @@ -417,7 +433,10 @@ pullop.repo.ui.status(_("no changes found\n")) result = 0 else: - tr = pullop.repo.transaction(trname) + # We delay the open of the transaction as late as possible so we + # don't open transaction for nothing or you break future useful + # rollback call + pullop.gettransaction() if pullop.heads is None and list(common) == [nullid]: pullop.repo.ui.status(_("requesting all changes\n")) elif (pullop.heads is None @@ -465,20 +484,11 @@ # should be seen as public phases.advanceboundary(pullop.repo, phases.public, subset) - def gettransaction(): - if tr is None: - return pullop.repo.transaction(trname) - return tr - - obstr = _pullobsolete(pullop.repo, pullop.remote, gettransaction) - if obstr is not None: - tr = obstr - - if tr is not None: - tr.close() + _pullobsolete(pullop.repo, pullop.remote, + pullop.gettransaction) + pullop.closetransaction() finally: - if tr is not None: - tr.release() + pullop.releasetransaction() lock.release() return result