Show More
@@ -495,6 +495,17 b' class filectx(object):' | |||
|
495 | 495 | |
|
496 | 496 | return None |
|
497 | 497 | |
|
498 | def ancestors(self): | |
|
499 | seen = set(str(self)) | |
|
500 | visit = [self] | |
|
501 | while visit: | |
|
502 | for parent in visit.pop(0).parents(): | |
|
503 | s = str(parent) | |
|
504 | if s not in seen: | |
|
505 | visit.append(parent) | |
|
506 | seen.add(s) | |
|
507 | yield parent | |
|
508 | ||
|
498 | 509 | class workingctx(changectx): |
|
499 | 510 | """A workingctx object makes access to data related to |
|
500 | 511 | the current working directory convenient. |
@@ -28,27 +28,6 b' def _dirs(files):' | |||
|
28 | 28 | f = _dirname(f) |
|
29 | 29 | return d |
|
30 | 30 | |
|
31 | def _findoldnames(fctx, limit): | |
|
32 | "find files that path was copied from, back to linkrev limit" | |
|
33 | old = {} | |
|
34 | seen = set() | |
|
35 | orig = fctx.path() | |
|
36 | visit = [(fctx, 0)] | |
|
37 | while visit: | |
|
38 | fc, depth = visit.pop() | |
|
39 | s = str(fc) | |
|
40 | if s in seen: | |
|
41 | continue | |
|
42 | seen.add(s) | |
|
43 | if fc.path() != orig and fc.path() not in old: | |
|
44 | old[fc.path()] = (depth, fc.path()) # remember depth | |
|
45 | if fc.rev() is not None and fc.rev() < limit: | |
|
46 | continue | |
|
47 | visit += [(p, depth - 1) for p in fc.parents()] | |
|
48 | ||
|
49 | # return old names sorted by depth | |
|
50 | return [o[1] for o in sorted(old.values())] | |
|
51 | ||
|
52 | 31 | def _findlimit(repo, a, b): |
|
53 | 32 | """Find the earliest revision that's an ancestor of a or b but not both, |
|
54 | 33 | None if no such revision exists. |
@@ -138,23 +117,50 b' def copies(repo, c1, c2, ca, checkdirs=F' | |||
|
138 | 117 | fullcopy = {} |
|
139 | 118 | diverge = {} |
|
140 | 119 | |
|
120 | def related(f1, f2, limit): | |
|
121 | g1, g2 = f1.ancestors(), f2.ancestors() | |
|
122 | try: | |
|
123 | while 1: | |
|
124 | f1r, f2r = f1.rev(), f2.rev() | |
|
125 | if f1r > f2r: | |
|
126 | f1 = g1.next() | |
|
127 | elif f2r > f1r: | |
|
128 | f2 = g2.next() | |
|
129 | elif f1 == f2: | |
|
130 | return f1 # a match | |
|
131 | elif f1r == f2r or f1r < limit or f2r < limit: | |
|
132 | return False # copy no longer relevant | |
|
133 | except StopIteration: | |
|
134 | return False | |
|
135 | ||
|
141 | 136 | def checkcopies(f, m1, m2): |
|
142 | 137 | '''check possible copies of f from m1 to m2''' |
|
143 | c1 = ctx(f, m1[f]) | |
|
144 | for of in _findoldnames(c1, limit): | |
|
138 | of = None | |
|
139 | seen = set([f]) | |
|
140 | for oc in ctx(f, m1[f]).ancestors(): | |
|
141 | ocr = oc.rev() | |
|
142 | of = oc.path() | |
|
143 | if of in seen: | |
|
144 | # check limit late - grab last rename before | |
|
145 | if ocr < limit: | |
|
146 | break | |
|
147 | continue | |
|
148 | seen.add(of) | |
|
149 | ||
|
145 | 150 | fullcopy[f] = of # remember for dir rename detection |
|
146 | if of in m2: # original file not in other manifest? | |
|
147 | # if the original file is unchanged on the other branch, | |
|
148 | # no merge needed | |
|
149 | if m2[of] != ma.get(of): | |
|
150 |
|
|
|
151 | ca = c1.ancestor(c2) | |
|
152 | # related and named changed on only one side? | |
|
153 | if ca and (ca.path() == f or ca.path() == c2.path()): | |
|
154 | if c1 != ca or c2 != ca: # merge needed? | |
|
155 | copy[f] = of | |
|
156 | elif of in ma: | |
|
157 | diverge.setdefault(of, []).append(f) | |
|
151 | if of not in m2: | |
|
152 | continue # no match, keep looking | |
|
153 | if m2[of] == ma.get(of): | |
|
154 | break # no merge needed, quit early | |
|
155 | c2 = ctx(of, m2[of]) | |
|
156 | cr = related(oc, c2, ca.rev()) | |
|
157 | if of == f or of == c2.path(): # non-divergent | |
|
158 | copy[f] = of | |
|
159 | of = None | |
|
160 | break | |
|
161 | ||
|
162 | if of in ma: | |
|
163 | diverge.setdefault(of, []).append(f) | |
|
158 | 164 | |
|
159 | 165 | repo.ui.debug(" searching for copies back to rev %d\n" % limit) |
|
160 | 166 |
General Comments 0
You need to be logged in to leave comments.
Login now