Mercurial > hg
comparison mercurial/copies.py @ 43199:069cbbb53cdf
copies: drop the findlimit logic
We don't use the limit anymore so we should stop computing that limit.
I did not bother measuring the potential performance gain. I am assuming that
not running any code will be faster that doing some computation and not using
the result.
author | Pierre-Yves David <pierre-yves.david@octobus.net> |
---|---|
date | Thu, 10 Oct 2019 17:18:46 +0200 |
parents | c16fe77e340a |
children | 30570a056fa8 |
comparison
equal
deleted
inserted
replaced
43198:c16fe77e340a | 43199:069cbbb53cdf |
---|---|
26 ) | 26 ) |
27 | 27 |
28 from .revlogutils import sidedata as sidedatamod | 28 from .revlogutils import sidedata as sidedatamod |
29 | 29 |
30 from .utils import stringutil | 30 from .utils import stringutil |
31 | |
32 | |
33 def _findlimit(repo, ctxa, ctxb): | |
34 """ | |
35 Find the last revision that needs to be checked to ensure that a full | |
36 transitive closure for file copies can be properly calculated. | |
37 Generally, this means finding the earliest revision number that's an | |
38 ancestor of a or b but not both, except when a or b is a direct descendent | |
39 of the other, in which case we can return the minimum revnum of a and b. | |
40 """ | |
41 | |
42 # basic idea: | |
43 # - mark a and b with different sides | |
44 # - if a parent's children are all on the same side, the parent is | |
45 # on that side, otherwise it is on no side | |
46 # - walk the graph in topological order with the help of a heap; | |
47 # - add unseen parents to side map | |
48 # - clear side of any parent that has children on different sides | |
49 # - track number of interesting revs that might still be on a side | |
50 # - track the lowest interesting rev seen | |
51 # - quit when interesting revs is zero | |
52 | |
53 cl = repo.changelog | |
54 wdirparents = None | |
55 a = ctxa.rev() | |
56 b = ctxb.rev() | |
57 if a is None: | |
58 wdirparents = (ctxa.p1(), ctxa.p2()) | |
59 a = node.wdirrev | |
60 if b is None: | |
61 assert not wdirparents | |
62 wdirparents = (ctxb.p1(), ctxb.p2()) | |
63 b = node.wdirrev | |
64 | |
65 side = {a: -1, b: 1} | |
66 visit = [-a, -b] | |
67 heapq.heapify(visit) | |
68 interesting = len(visit) | |
69 limit = node.wdirrev | |
70 | |
71 while interesting: | |
72 r = -(heapq.heappop(visit)) | |
73 if r == node.wdirrev: | |
74 parents = [pctx.rev() for pctx in wdirparents] | |
75 else: | |
76 parents = cl.parentrevs(r) | |
77 if parents[1] == node.nullrev: | |
78 parents = parents[:1] | |
79 for p in parents: | |
80 if p not in side: | |
81 # first time we see p; add it to visit | |
82 side[p] = side[r] | |
83 if side[p]: | |
84 interesting += 1 | |
85 heapq.heappush(visit, -p) | |
86 elif side[p] and side[p] != side[r]: | |
87 # p was interesting but now we know better | |
88 side[p] = 0 | |
89 interesting -= 1 | |
90 if side[r]: | |
91 limit = r # lowest rev visited | |
92 interesting -= 1 | |
93 | |
94 # Consider the following flow (see test-commit-amend.t under issue4405): | |
95 # 1/ File 'a0' committed | |
96 # 2/ File renamed from 'a0' to 'a1' in a new commit (call it 'a1') | |
97 # 3/ Move back to first commit | |
98 # 4/ Create a new commit via revert to contents of 'a1' (call it 'a1-amend') | |
99 # 5/ Rename file from 'a1' to 'a2' and commit --amend 'a1-msg' | |
100 # | |
101 # During the amend in step five, we will be in this state: | |
102 # | |
103 # @ 3 temporary amend commit for a1-amend | |
104 # | | |
105 # o 2 a1-amend | |
106 # | | |
107 # | o 1 a1 | |
108 # |/ | |
109 # o 0 a0 | |
110 # | |
111 # When _findlimit is called, a and b are revs 3 and 0, so limit will be 2, | |
112 # yet the filelog has the copy information in rev 1 and we will not look | |
113 # back far enough unless we also look at the a and b as candidates. | |
114 # This only occurs when a is a descendent of b or visa-versa. | |
115 return min(limit, a, b) | |
116 | 31 |
117 | 32 |
118 def _filter(src, dst, t): | 33 def _filter(src, dst, t): |
119 """filters out invalid copies after chaining""" | 34 """filters out invalid copies after chaining""" |
120 | 35 |
158 else: | 73 else: |
159 t[k] = v | 74 t[k] = v |
160 return t | 75 return t |
161 | 76 |
162 | 77 |
163 def _tracefile(fctx, am, basemf, limit): | 78 def _tracefile(fctx, am, basemf): |
164 """return file context that is the ancestor of fctx present in ancestor | 79 """return file context that is the ancestor of fctx present in ancestor |
165 manifest am | 80 manifest am |
166 | 81 |
167 Note: we used to try and stop after a given limit, however checking if that | 82 Note: we used to try and stop after a given limit, however checking if that |
168 limit is reached turned out to be very expensive. we are better off | 83 limit is reached turned out to be very expensive. we are better off |
215 | 130 |
216 debug = repo.ui.debugflag and repo.ui.configbool(b'devel', b'debug.copies') | 131 debug = repo.ui.debugflag and repo.ui.configbool(b'devel', b'debug.copies') |
217 dbg = repo.ui.debug | 132 dbg = repo.ui.debug |
218 if debug: | 133 if debug: |
219 dbg(b'debug.copies: looking into rename from %s to %s\n' % (a, b)) | 134 dbg(b'debug.copies: looking into rename from %s to %s\n' % (a, b)) |
220 limit = _findlimit(repo, a, b) | |
221 if debug: | |
222 dbg(b'debug.copies: search limit: %d\n' % limit) | |
223 am = a.manifest() | 135 am = a.manifest() |
224 basemf = None if base is None else base.manifest() | 136 basemf = None if base is None else base.manifest() |
225 | 137 |
226 # find where new files came from | 138 # find where new files came from |
227 # we currently don't try to find where old files went, too expensive | 139 # we currently don't try to find where old files went, too expensive |
251 fctx = b[f] | 163 fctx = b[f] |
252 fctx._ancestrycontext = ancestrycontext | 164 fctx._ancestrycontext = ancestrycontext |
253 | 165 |
254 if debug: | 166 if debug: |
255 start = util.timer() | 167 start = util.timer() |
256 opath = _tracefile(fctx, am, basemf, limit) | 168 opath = _tracefile(fctx, am, basemf) |
257 if opath: | 169 if opath: |
258 if debug: | 170 if debug: |
259 dbg(b'debug.copies: rename of: %s\n' % opath) | 171 dbg(b'debug.copies: rename of: %s\n' % opath) |
260 cm[f] = opath | 172 cm[f] = opath |
261 if debug: | 173 if debug: |