Mercurial > hg
comparison mercurial/metadata.py @ 44941:edd08aa193fb
files: extract code for extra filtering of the `removed` entry into copies
We want to reduce the set of `removed` files that to the set of files actually
removed. That `removed` set is used as of the changeset centric algorithm,
having smaller sets means less processing and faster computation.
In this changeset we extract the code to be a function of it own. We will make
use of it in the next changesets.
Differential Revision: https://phab.mercurial-scm.org/D8588
author | Pierre-Yves David <pierre-yves.david@octobus.net> |
---|---|
date | Wed, 27 May 2020 12:45:39 +0200 |
parents | 4c1d39215034 |
children | 25512a65cefd |
comparison
equal
deleted
inserted
replaced
44940:4c1d39215034 | 44941:edd08aa193fb |
---|---|
9 | 9 |
10 import multiprocessing | 10 import multiprocessing |
11 | 11 |
12 from . import ( | 12 from . import ( |
13 error, | 13 error, |
14 node, | |
14 pycompat, | 15 pycompat, |
15 util, | 16 util, |
16 ) | 17 ) |
17 | 18 |
18 from .revlogutils import ( | 19 from .revlogutils import ( |
27 added = [] | 28 added = [] |
28 for f in ctx.files(): | 29 for f in ctx.files(): |
29 if not any(f in p for p in ctx.parents()): | 30 if not any(f in p for p in ctx.parents()): |
30 added.append(f) | 31 added.append(f) |
31 return added | 32 return added |
33 | |
34 | |
35 def get_removal_filter(ctx, x=None): | |
36 """return a function to detect files "wrongly" detected as `removed` | |
37 | |
38 When a file is removed relative to p1 in a merge, this | |
39 function determines whether the absence is due to a | |
40 deletion from a parent, or whether the merge commit | |
41 itself deletes the file. We decide this by doing a | |
42 simplified three way merge of the manifest entry for | |
43 the file. There are two ways we decide the merge | |
44 itself didn't delete a file: | |
45 - neither parent (nor the merge) contain the file | |
46 - exactly one parent contains the file, and that | |
47 parent has the same filelog entry as the merge | |
48 ancestor (or all of them if there two). In other | |
49 words, that parent left the file unchanged while the | |
50 other one deleted it. | |
51 One way to think about this is that deleting a file is | |
52 similar to emptying it, so the list of changed files | |
53 should be similar either way. The computation | |
54 described above is not done directly in _filecommit | |
55 when creating the list of changed files, however | |
56 it does something very similar by comparing filelog | |
57 nodes. | |
58 """ | |
59 | |
60 if x is not None: | |
61 p1, p2, m1, m2 = x | |
62 else: | |
63 p1 = ctx.p1() | |
64 p2 = ctx.p2() | |
65 m1 = p1.manifest() | |
66 m2 = p2.manifest() | |
67 | |
68 @util.cachefunc | |
69 def mas(): | |
70 p1n = p1.node() | |
71 p2n = p2.node() | |
72 cahs = ctx.repo().changelog.commonancestorsheads(p1n, p2n) | |
73 if not cahs: | |
74 cahs = [node.nullrev] | |
75 return [ctx.repo()[r].manifest() for r in cahs] | |
76 | |
77 def deletionfromparent(f): | |
78 if f in m1: | |
79 return f not in m2 and all( | |
80 f in ma and ma.find(f) == m1.find(f) for ma in mas() | |
81 ) | |
82 elif f in m2: | |
83 return all(f in ma and ma.find(f) == m2.find(f) for ma in mas()) | |
84 else: | |
85 return True | |
86 | |
87 return deletionfromparent | |
32 | 88 |
33 | 89 |
34 def computechangesetfilesremoved(ctx): | 90 def computechangesetfilesremoved(ctx): |
35 """return the list of files removed in a changeset | 91 """return the list of files removed in a changeset |
36 """ | 92 """ |