# HG changeset patch # User Pulkit Goyal <7895pulkit@gmail.com> # Date 2020-08-03 08:42:13 # Node ID b9b055f150359b7970d434c43fc556c3b4cc72d0 # Parent f569ca3eb430edb494f2b79e576959445be3cd19 merge: pass mergeresult obj instead of actions in applyupdates() (API) This is similar to past 20 patches or so where we are replacing use of a bare actions dict with a dedicated mergeresult object. The goal is to have a dedicated powerful object instead of a dict while making the code more easier to understand. In past few patches, we have already simplified the code at some places using the newly introduced object. This patch does not updates applyupdates() to use the mergeresult object directly. That will be done in next patch to make things easier to review. Differential Revision: https://phab.mercurial-scm.org/D8876 diff --git a/hgext/remotefilelog/__init__.py b/hgext/remotefilelog/__init__.py --- a/hgext/remotefilelog/__init__.py +++ b/hgext/remotefilelog/__init__.py @@ -480,16 +480,16 @@ def storewrapper(orig, requirements, pat # prefetch files before update def applyupdates( - orig, repo, actions, wctx, mctx, overwrite, wantfiledata, **opts + orig, repo, mresult, wctx, mctx, overwrite, wantfiledata, **opts ): if isenabled(repo): manifest = mctx.manifest() files = [] - for f, args, msg in actions[mergestatemod.ACTION_GET]: + for f, args, msg in mresult.getactions([mergestatemod.ACTION_GET]): files.append((f, hex(manifest[f]))) # batch fetch the needed files from the server repo.fileservice.prefetch(files) - return orig(repo, actions, wctx, mctx, overwrite, wantfiledata, **opts) + return orig(repo, mresult, wctx, mctx, overwrite, wantfiledata, **opts) # Prefetch merge checkunknownfiles diff --git a/mercurial/merge.py b/mercurial/merge.py --- a/mercurial/merge.py +++ b/mercurial/merge.py @@ -1328,7 +1328,7 @@ def emptyactions(): def applyupdates( repo, - actions, + mresult, wctx, mctx, overwrite, @@ -1338,6 +1338,7 @@ def applyupdates( ): """apply the merge action list to the working directory + mresult is a mergeresult object representing result of the merge wctx is the working copy context mctx is the context to be merged into the working copy commitinfo is a mapping of information which needs to be stored somewhere @@ -1349,6 +1350,7 @@ def applyupdates( batchget. """ + actions = mresult.actionsdict _prefetchfiles(repo, mctx, actions) updated, merged, removed = 0, 0, 0 @@ -1613,6 +1615,8 @@ def applyupdates( mfiles = {a[0] for a in actions[mergestatemod.ACTION_MERGE]} for k, acts in pycompat.iteritems(extraactions): actions[k].extend(acts) + 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: @@ -1638,6 +1642,9 @@ def applyupdates( actions[mergestatemod.ACTION_MERGE] = [ a for a in actions[mergestatemod.ACTION_MERGE] if a[0] in mfiles ] + for a in mresult.getactions([mergestatemod.ACTION_MERGE]): + if a[0] not in mfiles: + mresult.removefile(a[0]) progress.complete() assert len(getfiledata) == ( @@ -2016,7 +2023,7 @@ def update( wantfiledata = updatedirstate and not branchmerge stats, getfiledata = applyupdates( repo, - actions, + mresult, wc, p2, overwrite, @@ -2029,7 +2036,7 @@ def update( with repo.dirstate.parentchange(): repo.setparents(fp1, fp2) mergestatemod.recordupdates( - repo, actions, branchmerge, getfiledata + repo, mresult.actionsdict, branchmerge, getfiledata ) # update completed, clear state util.unlink(repo.vfs.join(b'updatestate')) diff --git a/mercurial/narrowspec.py b/mercurial/narrowspec.py --- a/mercurial/narrowspec.py +++ b/mercurial/narrowspec.py @@ -272,15 +272,19 @@ def _deletecleanfiles(repo, files): def _writeaddedfiles(repo, pctx, files): - actions = merge.emptyactions() - addgaction = actions[mergestatemod.ACTION_GET].append + mresult = merge.mergeresult() mf = repo[b'.'].manifest() for f in files: if not repo.wvfs.exists(f): - addgaction((f, (mf.flags(f), False), b"narrowspec updated")) + mresult.addfile( + f, + mergestatemod.ACTION_GET, + (mf.flags(f), False), + b"narrowspec updated", + ) merge.applyupdates( repo, - actions, + mresult, wctx=repo[None], mctx=repo[b'.'], overwrite=False, diff --git a/mercurial/sparse.py b/mercurial/sparse.py --- a/mercurial/sparse.py +++ b/mercurial/sparse.py @@ -269,19 +269,17 @@ def prunetemporaryincludes(repo): sparsematch = matcher(repo, includetemp=False) dirstate = repo.dirstate - actions = [] + mresult = mergemod.mergeresult() dropped = [] tempincludes = readtemporaryincludes(repo) for file in tempincludes: if file in dirstate and not sparsematch(file): message = _(b'dropping temporarily included sparse files') - actions.append((file, None, message)) + mresult.addfile(file, b'r', None, message) dropped.append(file) - typeactions = mergemod.emptyactions() - typeactions[b'r'] = actions mergemod.applyupdates( - repo, typeactions, repo[None], repo[b'.'], False, wantfiledata=False + repo, mresult, repo[None], repo[b'.'], False, wantfiledata=False ) # Fix dirstate @@ -429,22 +427,25 @@ def filterupdatesactions(repo, wctx, mct addtemporaryincludes(repo, temporaryfiles) # Add the new files to the working copy so they can be merged, etc - actions = [] + tmresult = mergemod.mergeresult() message = b'temporarily adding to sparse checkout' wctxmanifest = repo[None].manifest() for file in temporaryfiles: if file in wctxmanifest: fctx = repo[None][file] - actions.append((file, (fctx.flags(), False), message)) + tmresult.addfile( + file, + mergestatemod.ACTION_GET, + (fctx.flags(), False), + message, + ) - typeactions = mergemod.emptyactions() - typeactions[mergestatemod.ACTION_GET] = actions mergemod.applyupdates( - repo, typeactions, repo[None], repo[b'.'], False, wantfiledata=False + repo, tmresult, repo[None], repo[b'.'], False, wantfiledata=False ) dirstate = repo.dirstate - for file, flags, msg in actions: + for file, flags, msg in tmresult.getactions([mergestatemod.ACTION_GET]): dirstate.normal(file) profiles = activeconfig(repo)[2] @@ -497,7 +498,7 @@ def refreshwdir(repo, origstatus, origsp _(b'could not update sparseness due to pending changes') ) - # Calculate actions + # Calculate merge result dirstate = repo.dirstate ctx = repo[b'.'] added = [] @@ -505,8 +506,7 @@ def refreshwdir(repo, origstatus, origsp dropped = [] mf = ctx.manifest() files = set(mf) - - actions = {} + mresult = mergemod.mergeresult() for file in files: old = origsparsematch(file) @@ -516,17 +516,17 @@ def refreshwdir(repo, origstatus, origsp if (new and not old) or (old and new and not file in dirstate): fl = mf.flags(file) if repo.wvfs.exists(file): - actions[file] = (b'e', (fl,), b'') + mresult.addfile(file, b'e', (fl,), b'') lookup.append(file) else: - actions[file] = (b'g', (fl, False), b'') + mresult.addfile(file, b'g', (fl, False), b'') added.append(file) # Drop files that are newly excluded, or that still exist in # the dirstate. elif (old and not new) or (not old and not new and file in dirstate): dropped.append(file) if file not in pending: - actions[file] = (b'r', [], b'') + mresult.addfile(file, b'r', [], b'') # Verify there are no pending changes in newly included files abort = False @@ -550,13 +550,8 @@ def refreshwdir(repo, origstatus, origsp if old and not new: dropped.append(file) - # Apply changes to disk - typeactions = mergemod.emptyactions() - for f, (m, args, msg) in pycompat.iteritems(actions): - typeactions[m].append((f, args, msg)) - mergemod.applyupdates( - repo, typeactions, repo[None], repo[b'.'], False, wantfiledata=False + repo, mresult, repo[None], repo[b'.'], False, wantfiledata=False ) # Fix dirstate