Show More
@@ -30,91 +30,6 b' from .revlogutils import sidedata as sid' | |||
|
30 | 30 | from .utils import stringutil |
|
31 | 31 | |
|
32 | 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 | ||
|
117 | ||
|
118 | 33 | def _filter(src, dst, t): |
|
119 | 34 | """filters out invalid copies after chaining""" |
|
120 | 35 | |
@@ -160,7 +75,7 b' def _chain(a, b):' | |||
|
160 | 75 | return t |
|
161 | 76 | |
|
162 | 77 | |
|
163 |
def _tracefile(fctx, am, basemf |
|
|
78 | def _tracefile(fctx, am, basemf): | |
|
164 | 79 | """return file context that is the ancestor of fctx present in ancestor |
|
165 | 80 | manifest am |
|
166 | 81 | |
@@ -217,9 +132,6 b' def _committedforwardcopies(a, b, base, ' | |||
|
217 | 132 | dbg = repo.ui.debug |
|
218 | 133 | if debug: |
|
219 | 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 | 135 | am = a.manifest() |
|
224 | 136 | basemf = None if base is None else base.manifest() |
|
225 | 137 | |
@@ -253,7 +165,7 b' def _committedforwardcopies(a, b, base, ' | |||
|
253 | 165 | |
|
254 | 166 | if debug: |
|
255 | 167 | start = util.timer() |
|
256 |
opath = _tracefile(fctx, am, basemf |
|
|
168 | opath = _tracefile(fctx, am, basemf) | |
|
257 | 169 | if opath: |
|
258 | 170 | if debug: |
|
259 | 171 | dbg(b'debug.copies: rename of: %s\n' % opath) |
@@ -1676,7 +1676,6 b' Check debug output for copy tracing' | |||
|
1676 | 1676 | debug.copies: searching copies from a51f36ab1704 to 1f4aa1fd627b |
|
1677 | 1677 | debug.copies: search mode: forward |
|
1678 | 1678 | debug.copies: looking into rename from a51f36ab1704 to 1f4aa1fd627b |
|
1679 | debug.copies: search limit: 3 | |
|
1680 | 1679 | debug.copies: missing files to search: 1 |
|
1681 | 1680 | debug.copies: tracing file: renamed |
|
1682 | 1681 | debug.copies: rename of: f |
General Comments 0
You need to be logged in to leave comments.
Login now