Show More
@@ -482,6 +482,9 b" coreconfigitem('experimental', 'copytrac" | |||
|
482 | 482 | coreconfigitem('experimental', 'copytrace.sourcecommitlimit', |
|
483 | 483 | default=100, |
|
484 | 484 | ) |
|
485 | coreconfigitem('experimental', 'copies.read-from', | |
|
486 | default="filelog-only", | |
|
487 | ) | |
|
485 | 488 | coreconfigitem('experimental', 'crecordtest', |
|
486 | 489 | default=None, |
|
487 | 490 | ) |
@@ -166,6 +166,10 b' def _committedforwardcopies(a, b, match)' | |||
|
166 | 166 | # files might have to be traced back to the fctx parent of the last |
|
167 | 167 | # one-side-only changeset, but not further back than that |
|
168 | 168 | repo = a._repo |
|
169 | ||
|
170 | if repo.ui.config('experimental', 'copies.read-from') == 'compatibility': | |
|
171 | return _changesetforwardcopies(a, b, match) | |
|
172 | ||
|
169 | 173 | debug = repo.ui.debugflag and repo.ui.configbool('devel', 'debug.copies') |
|
170 | 174 | dbg = repo.ui.debug |
|
171 | 175 | if debug: |
@@ -216,6 +220,76 b' def _committedforwardcopies(a, b, match)' | |||
|
216 | 220 | % (util.timer() - start)) |
|
217 | 221 | return cm |
|
218 | 222 | |
|
223 | def _changesetforwardcopies(a, b, match): | |
|
224 | if a.rev() == node.nullrev: | |
|
225 | return {} | |
|
226 | ||
|
227 | repo = a.repo() | |
|
228 | children = {} | |
|
229 | cl = repo.changelog | |
|
230 | missingrevs = cl.findmissingrevs(common=[a.rev()], heads=[b.rev()]) | |
|
231 | for r in missingrevs: | |
|
232 | for p in cl.parentrevs(r): | |
|
233 | if p == node.nullrev: | |
|
234 | continue | |
|
235 | if p not in children: | |
|
236 | children[p] = [r] | |
|
237 | else: | |
|
238 | children[p].append(r) | |
|
239 | ||
|
240 | roots = set(children) - set(missingrevs) | |
|
241 | # 'work' contains 3-tuples of a (revision number, parent number, copies). | |
|
242 | # The parent number is only used for knowing which parent the copies dict | |
|
243 | # came from. | |
|
244 | work = [(r, 1, {}) for r in roots] | |
|
245 | heapq.heapify(work) | |
|
246 | while work: | |
|
247 | r, i1, copies1 = heapq.heappop(work) | |
|
248 | if work and work[0][0] == r: | |
|
249 | # We are tracing copies from both parents | |
|
250 | r, i2, copies2 = heapq.heappop(work) | |
|
251 | copies = {} | |
|
252 | ctx = repo[r] | |
|
253 | p1man, p2man = ctx.p1().manifest(), ctx.p2().manifest() | |
|
254 | allcopies = set(copies1) | set(copies2) | |
|
255 | # TODO: perhaps this filtering should be done as long as ctx | |
|
256 | # is merge, whether or not we're tracing from both parent. | |
|
257 | for dst in allcopies: | |
|
258 | if not match(dst): | |
|
259 | continue | |
|
260 | if dst not in copies2: | |
|
261 | # Copied on p1 side: mark as copy from p1 side if it didn't | |
|
262 | # already exist on p2 side | |
|
263 | if dst not in p2man: | |
|
264 | copies[dst] = copies1[dst] | |
|
265 | elif dst not in copies1: | |
|
266 | # Copied on p2 side: mark as copy from p2 side if it didn't | |
|
267 | # already exist on p1 side | |
|
268 | if dst not in p1man: | |
|
269 | copies[dst] = copies2[dst] | |
|
270 | else: | |
|
271 | # Copied on both sides: mark as copy from p1 side | |
|
272 | copies[dst] = copies1[dst] | |
|
273 | else: | |
|
274 | copies = copies1 | |
|
275 | if r == b.rev(): | |
|
276 | return copies | |
|
277 | for c in children[r]: | |
|
278 | childctx = repo[c] | |
|
279 | if r == childctx.p1().rev(): | |
|
280 | parent = 1 | |
|
281 | childcopies = childctx.p1copies() | |
|
282 | else: | |
|
283 | assert r == childctx.p2().rev() | |
|
284 | parent = 2 | |
|
285 | childcopies = childctx.p2copies() | |
|
286 | if not match.always(): | |
|
287 | childcopies = {dst: src for dst, src in childcopies.items() | |
|
288 | if match(dst)} | |
|
289 | childcopies = _chain(a, childctx, copies, childcopies) | |
|
290 | heapq.heappush(work, (c, parent, childcopies)) | |
|
291 | assert False | |
|
292 | ||
|
219 | 293 | def _forwardcopies(a, b, match=None): |
|
220 | 294 | """find {dst@b: src@a} copy mapping where a is an ancestor of b""" |
|
221 | 295 |
@@ -1,9 +1,17 b'' | |||
|
1 | #testcases filelog compatibility | |
|
1 | 2 | |
|
2 | 3 | $ cat >> $HGRCPATH << EOF |
|
3 | 4 | > [alias] |
|
4 | 5 | > l = log -G -T '{rev} {desc}\n{files}\n' |
|
5 | 6 | > EOF |
|
6 | 7 | |
|
8 | #if compatibility | |
|
9 | $ cat >> $HGRCPATH << EOF | |
|
10 | > [experimental] | |
|
11 | > copies.read-from = compatibility | |
|
12 | > EOF | |
|
13 | #endif | |
|
14 | ||
|
7 | 15 | $ REPONUM=0 |
|
8 | 16 | $ newrepo() { |
|
9 | 17 | > cd $TESTTMP |
@@ -338,7 +346,7 b" It's a little weird that it shows up on " | |||
|
338 | 346 | $ hg debugpathcopies 1 2 |
|
339 | 347 | x -> z |
|
340 | 348 | $ hg debugpathcopies 0 2 |
|
341 | x -> z | |
|
349 | x -> z (filelog !) | |
|
342 | 350 | |
|
343 | 351 | Copy file that exists on both sides of the merge, different content |
|
344 | 352 | $ newrepo |
@@ -476,7 +484,8 b' Try merging the other direction too' | |||
|
476 | 484 | $ hg debugpathcopies 1 4 |
|
477 | 485 | $ hg debugpathcopies 2 4 |
|
478 | 486 | $ hg debugpathcopies 0 4 |
|
479 | x -> z | |
|
487 | x -> z (filelog !) | |
|
488 | y -> z (compatibility !) | |
|
480 | 489 | $ hg debugpathcopies 1 5 |
|
481 | 490 | $ hg debugpathcopies 2 5 |
|
482 | 491 | $ hg debugpathcopies 0 5 |
General Comments 0
You need to be logged in to leave comments.
Login now