Mercurial > hg
comparison mercurial/merge.py @ 45345:e5b4061f32be
mergeresult: add `files()` and use it
`files()` will return a list of files on which an action needs to be performed.
This is a step to stop exposing the underlying map to the user of this object.
Differential Revision: https://phab.mercurial-scm.org/D8887
author | Pulkit Goyal <7895pulkit@gmail.com> |
---|---|
date | Wed, 05 Aug 2020 15:41:23 +0530 |
parents | 4c6004afd836 |
children | 3c783ff08d40 |
comparison
equal
deleted
inserted
replaced
45344:4c6004afd836 | 45345:e5b4061f32be |
---|---|
149 abortconflicts.update(conflicts) | 149 abortconflicts.update(conflicts) |
150 elif config == b'warn': | 150 elif config == b'warn': |
151 warnconflicts.update(conflicts) | 151 warnconflicts.update(conflicts) |
152 | 152 |
153 checkunknowndirs = _unknowndirschecker() | 153 checkunknowndirs = _unknowndirschecker() |
154 for f, args, msg in mresult.getactions( | 154 for f in mresult.files( |
155 [ | 155 ( |
156 mergestatemod.ACTION_CREATED, | 156 mergestatemod.ACTION_CREATED, |
157 mergestatemod.ACTION_DELETED_CHANGED, | 157 mergestatemod.ACTION_DELETED_CHANGED, |
158 ] | 158 ) |
159 ): | 159 ): |
160 if _checkunknownfile(repo, wctx, mctx, f): | 160 if _checkunknownfile(repo, wctx, mctx, f): |
161 fileconflicts.add(f) | 161 fileconflicts.add(f) |
162 elif pathconfig and f not in wctx: | 162 elif pathconfig and f not in wctx: |
163 path = checkunknowndirs(repo, wctx, f) | 163 path = checkunknowndirs(repo, wctx, f) |
297 # If the repo is narrowed, filter out files outside the narrowspec. | 297 # If the repo is narrowed, filter out files outside the narrowspec. |
298 narrowmatch = repo.narrowmatch() | 298 narrowmatch = repo.narrowmatch() |
299 if not narrowmatch.always(): | 299 if not narrowmatch.always(): |
300 pmmf = set(wmf.walk(narrowmatch)) | 300 pmmf = set(wmf.walk(narrowmatch)) |
301 if mresult: | 301 if mresult: |
302 for f, actionsfortype in pycompat.iteritems(mresult.actions): | 302 for f in list(mresult.files()): |
303 if not narrowmatch(f): | 303 if not narrowmatch(f): |
304 mresult.removefile(f) | 304 mresult.removefile(f) |
305 else: | 305 else: |
306 # build provisional merged manifest up | 306 # build provisional merged manifest up |
307 pmmf = set(wmf) | 307 pmmf = set(wmf) |
308 | 308 |
309 if mresult: | 309 if mresult: |
310 # KEEP and EXEC are no-op | 310 # KEEP and EXEC are no-op |
311 for f, args, msg in mresult.getactions( | 311 for f in mresult.files( |
312 ( | 312 ( |
313 mergestatemod.ACTION_ADD, | 313 mergestatemod.ACTION_ADD, |
314 mergestatemod.ACTION_ADD_MODIFIED, | 314 mergestatemod.ACTION_ADD_MODIFIED, |
315 mergestatemod.ACTION_FORGET, | 315 mergestatemod.ACTION_FORGET, |
316 mergestatemod.ACTION_GET, | 316 mergestatemod.ACTION_GET, |
317 mergestatemod.ACTION_CHANGED_DELETED, | 317 mergestatemod.ACTION_CHANGED_DELETED, |
318 mergestatemod.ACTION_DELETED_CHANGED, | 318 mergestatemod.ACTION_DELETED_CHANGED, |
319 ) | 319 ) |
320 ): | 320 ): |
321 pmmf.add(f) | 321 pmmf.add(f) |
322 for f, args, msg in mresult.getactions([mergestatemod.ACTION_REMOVE]): | 322 for f in mresult.files((mergestatemod.ACTION_REMOVE,)): |
323 pmmf.discard(f) | 323 pmmf.discard(f) |
324 for f, args, msg in mresult.getactions( | 324 for f, args, msg in mresult.getactions( |
325 [mergestatemod.ACTION_DIR_RENAME_MOVE_LOCAL] | 325 [mergestatemod.ACTION_DIR_RENAME_MOVE_LOCAL] |
326 ): | 326 ): |
327 f2, flags = args | 327 f2, flags = args |
328 pmmf.discard(f2) | 328 pmmf.discard(f2) |
329 pmmf.add(f) | 329 pmmf.add(f) |
330 for f, args, msg in mresult.getactions( | 330 for f in mresult.files((mergestatemod.ACTION_LOCAL_DIR_RENAME_GET,)): |
331 [mergestatemod.ACTION_LOCAL_DIR_RENAME_GET] | |
332 ): | |
333 pmmf.add(f) | 331 pmmf.add(f) |
334 for f, args, msg in mresult.getactions([mergestatemod.ACTION_MERGE]): | 332 for f, args, msg in mresult.getactions([mergestatemod.ACTION_MERGE]): |
335 f1, f2, fa, move, anc = args | 333 f1, f2, fa, move, anc = args |
336 if move: | 334 if move: |
337 pmmf.discard(f1) | 335 pmmf.discard(f1) |
412 createdfiledirs = set() | 410 createdfiledirs = set() |
413 | 411 |
414 # The set of files deleted by all the actions. | 412 # The set of files deleted by all the actions. |
415 deletedfiles = set() | 413 deletedfiles = set() |
416 | 414 |
417 for (f, args, msg) in mresult.getactions( | 415 for f in mresult.files( |
418 ( | 416 ( |
419 mergestatemod.ACTION_CREATED, | 417 mergestatemod.ACTION_CREATED, |
420 mergestatemod.ACTION_DELETED_CHANGED, | 418 mergestatemod.ACTION_DELETED_CHANGED, |
421 mergestatemod.ACTION_MERGE, | 419 mergestatemod.ACTION_MERGE, |
422 mergestatemod.ACTION_CREATED_MERGE, | 420 mergestatemod.ACTION_CREATED_MERGE, |
428 # The file aliases a local directory. This might be ok if all | 426 # The file aliases a local directory. This might be ok if all |
429 # the files in the local directory are being deleted. This | 427 # the files in the local directory are being deleted. This |
430 # will be checked once we know what all the deleted files are. | 428 # will be checked once we know what all the deleted files are. |
431 remoteconflicts.add(f) | 429 remoteconflicts.add(f) |
432 # Track the names of all deleted files. | 430 # Track the names of all deleted files. |
433 for (f, args, msg) in mresult.getactions((mergestatemod.ACTION_REMOVE,)): | 431 for f in mresult.files((mergestatemod.ACTION_REMOVE,)): |
434 deletedfiles.add(f) | 432 deletedfiles.add(f) |
435 for (f, args, msg) in mresult.getactions((mergestatemod.ACTION_MERGE,)): | 433 for (f, args, msg) in mresult.getactions((mergestatemod.ACTION_MERGE,)): |
436 f1, f2, fa, move, anc = args | 434 f1, f2, fa, move, anc = args |
437 if move: | 435 if move: |
438 deletedfiles.add(f1) | 436 deletedfiles.add(f1) |
468 | 466 |
469 # Rename all local conflicting files that have not been deleted. | 467 # Rename all local conflicting files that have not been deleted. |
470 for p in localconflicts: | 468 for p in localconflicts: |
471 if p not in deletedfiles: | 469 if p not in deletedfiles: |
472 ctxname = bytes(wctx).rstrip(b'+') | 470 ctxname = bytes(wctx).rstrip(b'+') |
473 pnew = util.safename(p, ctxname, wctx, set(mresult.actions.keys())) | 471 pnew = util.safename(p, ctxname, wctx, set(mresult.files())) |
474 porig = wctx[p].copysource() or p | 472 porig = wctx[p].copysource() or p |
475 mresult.addfile( | 473 mresult.addfile( |
476 pnew, | 474 pnew, |
477 mergestatemod.ACTION_PATH_CONFLICT_RESOLVE, | 475 mergestatemod.ACTION_PATH_CONFLICT_RESOLVE, |
478 (p, porig), | 476 (p, porig), |
489 # Check if all files in the conflicting directories have been removed. | 487 # Check if all files in the conflicting directories have been removed. |
490 ctxname = bytes(mctx).rstrip(b'+') | 488 ctxname = bytes(mctx).rstrip(b'+') |
491 for f, p in _filesindirs(repo, mf, remoteconflicts): | 489 for f, p in _filesindirs(repo, mf, remoteconflicts): |
492 if f not in deletedfiles: | 490 if f not in deletedfiles: |
493 m, args, msg = mresult.getfile(p) | 491 m, args, msg = mresult.getfile(p) |
494 pnew = util.safename( | 492 pnew = util.safename(p, ctxname, wctx, set(mresult.files())) |
495 p, ctxname, wctx, set(mresult.actions.keys()) | |
496 ) | |
497 if m in ( | 493 if m in ( |
498 mergestatemod.ACTION_DELETED_CHANGED, | 494 mergestatemod.ACTION_DELETED_CHANGED, |
499 mergestatemod.ACTION_MERGE, | 495 mergestatemod.ACTION_MERGE, |
500 ): | 496 ): |
501 # Action was merge, just update target. | 497 # Action was merge, just update target. |
619 returns default_return if the file is not present """ | 615 returns default_return if the file is not present """ |
620 if filename in self._filemapping: | 616 if filename in self._filemapping: |
621 return self._filemapping[filename] | 617 return self._filemapping[filename] |
622 return default_return | 618 return default_return |
623 | 619 |
620 def files(self, actions=None): | |
621 """ returns files on which provided action needs to perfromed | |
622 | |
623 If actions is None, all files are returned | |
624 """ | |
625 # TODO: think whether we should return renamedelete and | |
626 # diverge filenames also | |
627 if actions is None: | |
628 for f in self._filemapping: | |
629 yield f | |
630 | |
631 else: | |
632 for a in actions: | |
633 for f in self._actionmapping[a]: | |
634 yield f | |
635 | |
624 def removefile(self, filename): | 636 def removefile(self, filename): |
625 """ removes a file from the mergeresult object as the file might | 637 """ removes a file from the mergeresult object as the file might |
626 not merging anymore """ | 638 not merging anymore """ |
627 action, data, message = self._filemapping[filename] | 639 action, data, message = self._filemapping[filename] |
628 del self._filemapping[filename] | 640 del self._filemapping[filename] |
1027 def _resolvetrivial(repo, wctx, mctx, ancestor, mresult): | 1039 def _resolvetrivial(repo, wctx, mctx, ancestor, mresult): |
1028 """Resolves false conflicts where the nodeid changed but the content | 1040 """Resolves false conflicts where the nodeid changed but the content |
1029 remained the same.""" | 1041 remained the same.""" |
1030 # We force a copy of actions.items() because we're going to mutate | 1042 # We force a copy of actions.items() because we're going to mutate |
1031 # actions as we resolve trivial conflicts. | 1043 # actions as we resolve trivial conflicts. |
1032 for f, args, msg in list( | 1044 for f in list(mresult.files((mergestatemod.ACTION_CHANGED_DELETED,))): |
1033 mresult.getactions([mergestatemod.ACTION_CHANGED_DELETED]) | |
1034 ): | |
1035 if f in ancestor and not wctx[f].cmp(ancestor[f]): | 1045 if f in ancestor and not wctx[f].cmp(ancestor[f]): |
1036 # local did change but ended up with same content | 1046 # local did change but ended up with same content |
1037 mresult.addfile( | 1047 mresult.addfile( |
1038 f, mergestatemod.ACTION_REMOVE, None, b'prompt same' | 1048 f, mergestatemod.ACTION_REMOVE, None, b'prompt same' |
1039 ) | 1049 ) |
1040 | 1050 |
1041 for f, args, msg in list( | 1051 for f in list(mresult.files((mergestatemod.ACTION_DELETED_CHANGED,))): |
1042 mresult.getactions([mergestatemod.ACTION_DELETED_CHANGED]) | |
1043 ): | |
1044 if f in ancestor and not mctx[f].cmp(ancestor[f]): | 1052 if f in ancestor and not mctx[f].cmp(ancestor[f]): |
1045 # remote did change but ended up with same content | 1053 # remote did change but ended up with same content |
1046 mresult.removefile(f) # don't get = keep local deleted | 1054 mresult.removefile(f) # don't get = keep local deleted |
1047 | 1055 |
1048 | 1056 |
1302 of merge actions. ``ctx`` is the context being merged in.""" | 1310 of merge actions. ``ctx`` is the context being merged in.""" |
1303 | 1311 |
1304 # Skipping 'a', 'am', 'f', 'r', 'dm', 'e', 'k', 'p' and 'pr', because they | 1312 # Skipping 'a', 'am', 'f', 'r', 'dm', 'e', 'k', 'p' and 'pr', because they |
1305 # don't touch the context to be merged in. 'cd' is skipped, because | 1313 # don't touch the context to be merged in. 'cd' is skipped, because |
1306 # changed/deleted never resolves to something from the remote side. | 1314 # changed/deleted never resolves to something from the remote side. |
1307 files = [] | 1315 files = mresult.files( |
1308 for f, args, msg in mresult.getactions( | |
1309 [ | 1316 [ |
1310 mergestatemod.ACTION_GET, | 1317 mergestatemod.ACTION_GET, |
1311 mergestatemod.ACTION_DELETED_CHANGED, | 1318 mergestatemod.ACTION_DELETED_CHANGED, |
1312 mergestatemod.ACTION_LOCAL_DIR_RENAME_GET, | 1319 mergestatemod.ACTION_LOCAL_DIR_RENAME_GET, |
1313 mergestatemod.ACTION_MERGE, | 1320 mergestatemod.ACTION_MERGE, |
1314 ] | 1321 ] |
1315 ): | 1322 ) |
1316 files.append(f) | |
1317 | 1323 |
1318 prefetch = scmutil.prefetchfiles | 1324 prefetch = scmutil.prefetchfiles |
1319 matchfiles = scmutil.matchfiles | 1325 matchfiles = scmutil.matchfiles |
1320 prefetch( | 1326 prefetch( |
1321 repo, [(ctx.rev(), matchfiles(repo, files),)], | 1327 repo, [(ctx.rev(), matchfiles(repo, files),)], |