##// END OF EJS Templates
copies: split up _chain() in naive chaining and filtering steps...
Martin von Zweigbergk -
r42565:f3d06d37 default
parent child Browse files
Show More
@@ -107,8 +107,8 b' def _findlimit(repo, ctxa, ctxb):'
107 107 # This only occurs when a is a descendent of b or visa-versa.
108 108 return min(limit, a, b)
109 109
110 def _chain(src, dst, a, b):
111 """chain two sets of copies 'a' and 'b'"""
110 def _chainandfilter(src, dst, a, b):
111 """chain two sets of copies 'a' and 'b' and filter result"""
112 112
113 113 # When chaining copies in 'a' (from 'src' via some other commit 'mid') with
114 114 # copies in 'b' (from 'mid' to 'dst'), we can get the different cases in the
@@ -123,31 +123,37 b' def _chain(src, dst, a, b):'
123 123 # 4 x y z x->z
124 124 # 5 - x y -
125 125 # 6 x x y x->y
126 #
127 # _chain() takes care of chaining the copies in 'a' and 'b', but it
128 # cannot tell the difference between cases 1 and 2, between 3 and 4, or
129 # between 5 and 6, so it includes all cases in its result.
130 # Cases 1, 3, and 5 are then removed by _filter().
126 131
127 # Initialize result ('t') from 'a'. This catches cases 1 & 2. We'll remove
128 # case 1 later. We'll also catch cases 3 & 4 here. Case 4 will be
129 # overwritten later, and case 3 will be removed later.
132 t = _chain(a, b)
133 _filter(src, dst, t)
134 return t
135
136 def _filter(src, dst, t):
137 """filters out invalid copies after chaining"""
138 for k, v in list(t.items()):
139 # remove copies from files that didn't exist
140 if v not in src:
141 del t[k]
142 # remove criss-crossed copies
143 elif k in src and v in dst:
144 del t[k]
145 # remove copies to files that were then removed
146 elif k not in dst:
147 del t[k]
148
149 def _chain(a, b):
150 """chain two sets of copies 'a' and 'b'"""
130 151 t = a.copy()
131 152 for k, v in b.iteritems():
132 153 if v in t:
133 # Found a chain, i.e. cases 3 & 4. We'll remove case 3 later.
134 154 t[k] = t[v]
135 155 else:
136 # Renamed only in 'b', i.e. cases 5 & 6. We'll remove case 5 later.
137 156 t[k] = v
138
139 for k, v in list(t.items()):
140 # remove copies from files that didn't exist, i.e. case 5
141 if v not in src:
142 del t[k]
143 # remove criss-crossed copies, i.e. case 3
144 elif k in src and v in dst:
145 del t[k]
146 # remove copies to files that were then removed, i.e. case 1
147 # and file 'y' in cases 3 & 4 (in case of rename)
148 elif k not in dst:
149 del t[k]
150
151 157 return t
152 158
153 159 def _tracefile(fctx, am, limit):
@@ -307,7 +313,7 b' def _changesetforwardcopies(a, b, match)'
307 313 if not match.always():
308 314 childcopies = {dst: src for dst, src in childcopies.items()
309 315 if match(dst)}
310 childcopies = _chain(a, childctx, copies, childcopies)
316 childcopies = _chainandfilter(a, childctx, copies, childcopies)
311 317 heapq.heappush(work, (c, parent, childcopies))
312 318 assert False
313 319
@@ -323,7 +329,7 b' def _forwardcopies(a, b, match=None):'
323 329
324 330 cm = _committedforwardcopies(a, b.p1(), match)
325 331 # combine copies from dirstate if necessary
326 return _chain(a, b, cm, _dirstatecopies(b._repo, match))
332 return _chainandfilter(a, b, cm, _dirstatecopies(b._repo, match))
327 333 return _committedforwardcopies(a, b, match)
328 334
329 335 def _backwardrenames(a, b, match):
@@ -367,7 +373,7 b' def pathcopies(x, y, match=None):'
367 373 return _backwardrenames(x, y, match=match)
368 374 if debug:
369 375 repo.ui.debug('debug.copies: search mode: combined\n')
370 return _chain(x, y, _backwardrenames(x, a, match=match),
376 return _chainandfilter(x, y, _backwardrenames(x, a, match=match),
371 377 _forwardcopies(a, y, match=match))
372 378
373 379 def mergecopies(repo, c1, c2, base):
General Comments 0
You need to be logged in to leave comments. Login now