Mercurial > hg
changeset 47372:9e6e12e1a87e
merge: make applyupdates() not mutate mresult argument
We have an extension at work that overrides `merge.applyupdates()` to
make it skip some writes and instead instruct the virtual filesystem
we use to get a different version. That override doesn't work
correctly when doing `hg co -m` and there's a modified file in the
dirstate that's deleted in the destination. That's because
`applyupdates()` mutates its `mresult` argument and our extension had
passed in a modified copied of `mresult` to the overridden function,
which resulted in the mutation not having any effect. This patch fixes
that by letting the caller (i.e. `merge._update()`) update `mresult`
with the extra actions instead. Besides fixing our internal extension,
that seems cleaner to me anyway (better to not mutate `mresult` only
in some cases and we can skip some of the logic if we're not going to
update the dirstate anyway).
Differential Revision: https://phab.mercurial-scm.org/D10830
author | Martin von Zweigbergk <martinvonz@google.com> |
---|---|
date | Tue, 01 Jun 2021 15:19:08 -0700 |
parents | 298d4400ea68 |
children | d2fb8b4adcc3 |
files | mercurial/merge.py |
diffstat | 1 files changed, 17 insertions(+), 12 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/merge.py Thu Jun 03 16:12:03 2021 +0200 +++ b/mercurial/merge.py Tue Jun 01 15:19:08 2021 -0700 @@ -1724,20 +1724,13 @@ removed += msremoved extraactions = ms.actions() - if extraactions: - for k, acts in pycompat.iteritems(extraactions): - for a in acts: - mresult.addfile(a[0], k, *a[1:]) - if k == mergestatemod.ACTION_GET and wantfiledata: - # no filedata until mergestate is updated to provide it - for a in acts: - getfiledata[a[0]] = None progress.complete() - assert len(getfiledata) == ( - mresult.len((mergestatemod.ACTION_GET,)) if wantfiledata else 0 + return ( + updateresult(updated, merged, removed, unresolved), + getfiledata, + extraactions, ) - return updateresult(updated, merged, removed, unresolved), getfiledata def _advertisefsmonitor(repo, num_gets, p1node): @@ -2122,7 +2115,7 @@ ) wantfiledata = updatedirstate and not branchmerge - stats, getfiledata = applyupdates( + stats, getfiledata, extraactions = applyupdates( repo, mresult, wc, @@ -2133,6 +2126,18 @@ ) if updatedirstate: + if extraactions: + for k, acts in pycompat.iteritems(extraactions): + for a in acts: + mresult.addfile(a[0], k, *a[1:]) + if k == mergestatemod.ACTION_GET and wantfiledata: + # no filedata until mergestate is updated to provide it + for a in acts: + getfiledata[a[0]] = None + + assert len(getfiledata) == ( + mresult.len((mergestatemod.ACTION_GET,)) if wantfiledata else 0 + ) with repo.dirstate.parentchange(): repo.setparents(fp1, fp2) mergestatemod.recordupdates(