Show More
@@ -30,91 +30,6 b' from .revlogutils import sidedata as sid' | |||||
30 | from .utils import stringutil |
|
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 | 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 | |||
@@ -160,7 +75,7 b' def _chain(a, b):' | |||||
160 | return t |
|
75 | return t | |
161 |
|
76 | |||
162 |
|
77 | |||
163 |
def _tracefile(fctx, am, basemf |
|
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 | |||
@@ -217,9 +132,6 b' def _committedforwardcopies(a, b, base, ' | |||||
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 | |||
@@ -253,7 +165,7 b' def _committedforwardcopies(a, b, base, ' | |||||
253 |
|
165 | |||
254 | if debug: |
|
166 | if debug: | |
255 | start = util.timer() |
|
167 | start = util.timer() | |
256 |
opath = _tracefile(fctx, am, basemf |
|
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) |
@@ -1676,7 +1676,6 b' Check debug output for copy tracing' | |||||
1676 | debug.copies: searching copies from a51f36ab1704 to 1f4aa1fd627b |
|
1676 | debug.copies: searching copies from a51f36ab1704 to 1f4aa1fd627b | |
1677 | debug.copies: search mode: forward |
|
1677 | debug.copies: search mode: forward | |
1678 | debug.copies: looking into rename from a51f36ab1704 to 1f4aa1fd627b |
|
1678 | debug.copies: looking into rename from a51f36ab1704 to 1f4aa1fd627b | |
1679 | debug.copies: search limit: 3 |
|
|||
1680 | debug.copies: missing files to search: 1 |
|
1679 | debug.copies: missing files to search: 1 | |
1681 | debug.copies: tracing file: renamed |
|
1680 | debug.copies: tracing file: renamed | |
1682 | debug.copies: rename of: f |
|
1681 | debug.copies: rename of: f |
General Comments 0
You need to be logged in to leave comments.
Login now