Mercurial > hg
changeset 37107:71543b942eea
merge: return an attrs class from update() and applyupdates()
Previously, we returned a tuple containing counts. The result of an
update is kind of complex and the use of tuples with nameless fields
made the code a bit harder to read and constrained future expansion
of the return value.
Let's invent an attrs-defined class for representing the result of
an update operation.
We provide __getitem__ and __len__ implementations for backwards
compatibility as a container type to minimize code churn.
In (at least) Python 2, the % operator seems to insist on using
tuples. So we had to update a consumer using the % operator.
.. api::
merge.update() and merge.applyupdates() now return a class
with named attributes instead of a tuple. Switch consumers
to access elements by name instead of by offset.
Differential Revision: https://phab.mercurial-scm.org/D2692
author | Gregory Szorc <gregory.szorc@gmail.com> |
---|---|
date | Mon, 05 Mar 2018 00:02:13 -0500 |
parents | 3d3cff1f6bde |
children | 0351fb0153ba |
files | mercurial/hg.py mercurial/merge.py |
diffstat | 2 files changed, 34 insertions(+), 5 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/hg.py Fri Feb 23 11:48:58 2018 +0530 +++ b/mercurial/hg.py Mon Mar 05 00:02:13 2018 -0500 @@ -752,7 +752,9 @@ if quietempty and not any(stats): return repo.ui.status(_("%d files updated, %d files merged, " - "%d files removed, %d files unresolved\n") % stats) + "%d files removed, %d files unresolved\n") % ( + stats.updatedcount, stats.mergedcount, + stats.removedcount, stats.unresolvedcount)) def updaterepo(repo, node, overwrite, updatecheck=None): """Update the working directory to node.
--- a/mercurial/merge.py Fri Feb 23 11:48:58 2018 +0530 +++ b/mercurial/merge.py Mon Mar 05 00:02:13 2018 -0500 @@ -22,6 +22,9 @@ nullid, nullrev, ) +from .thirdparty import ( + attr, +) from . import ( copies, error, @@ -1398,6 +1401,30 @@ prefetch = scmutil.fileprefetchhooks prefetch(repo, ctx, [f for sublist in oplist for f, args, msg in sublist]) +@attr.s(frozen=True) +class updateresult(object): + updatedcount = attr.ib() + mergedcount = attr.ib() + removedcount = attr.ib() + unresolvedcount = attr.ib() + + # TODO remove container emulation once consumers switch to new API. + + def __getitem__(self, x): + if x == 0: + return self.updatedcount + elif x == 1: + return self.mergedcount + elif x == 2: + return self.removedcount + elif x == 3: + return self.unresolvedcount + else: + raise IndexError('can only access items 0-3') + + def __len__(self): + return 4 + def applyupdates(repo, actions, wctx, mctx, overwrite, labels=None): """apply the merge action list to the working directory @@ -1581,7 +1608,8 @@ if not proceed: # XXX setting unresolved to at least 1 is a hack to make sure we # error out - return updated, merged, removed, max(len(unresolvedf), 1) + return updateresult(updated, merged, removed, + max(len(unresolvedf), 1)) newactions = [] for f, args, msg in mergeactions: if f in unresolvedf: @@ -1656,8 +1684,7 @@ actions['m'] = [a for a in actions['m'] if a[0] in mfiles] progress(_updating, None, total=numupdates, unit=_files) - - return updated, merged, removed, unresolved + return updateresult(updated, merged, removed, unresolved) def recordupdates(repo, actions, branchmerge): "record merge actions to the dirstate" @@ -1878,7 +1905,7 @@ # call the hooks and exit early repo.hook('preupdate', throw=True, parent1=xp2, parent2='') repo.hook('update', parent1=xp2, parent2='', error=0) - return 0, 0, 0, 0 + return updateresult(0, 0, 0, 0) if (updatecheck == 'linear' and pas not in ([p1], [p2])): # nonlinear