Show More
@@ -482,6 +482,9 b" coreconfigitem('experimental', 'copytrac" | |||||
482 | coreconfigitem('experimental', 'copytrace.sourcecommitlimit', |
|
482 | coreconfigitem('experimental', 'copytrace.sourcecommitlimit', | |
483 | default=100, |
|
483 | default=100, | |
484 | ) |
|
484 | ) | |
|
485 | coreconfigitem('experimental', 'copies.read-from', | |||
|
486 | default="filelog-only", | |||
|
487 | ) | |||
485 | coreconfigitem('experimental', 'crecordtest', |
|
488 | coreconfigitem('experimental', 'crecordtest', | |
486 | default=None, |
|
489 | default=None, | |
487 | ) |
|
490 | ) |
@@ -166,6 +166,10 b' def _committedforwardcopies(a, b, match)' | |||||
166 | # files might have to be traced back to the fctx parent of the last |
|
166 | # files might have to be traced back to the fctx parent of the last | |
167 | # one-side-only changeset, but not further back than that |
|
167 | # one-side-only changeset, but not further back than that | |
168 | repo = a._repo |
|
168 | repo = a._repo | |
|
169 | ||||
|
170 | if repo.ui.config('experimental', 'copies.read-from') == 'compatibility': | |||
|
171 | return _changesetforwardcopies(a, b, match) | |||
|
172 | ||||
169 | debug = repo.ui.debugflag and repo.ui.configbool('devel', 'debug.copies') |
|
173 | debug = repo.ui.debugflag and repo.ui.configbool('devel', 'debug.copies') | |
170 | dbg = repo.ui.debug |
|
174 | dbg = repo.ui.debug | |
171 | if debug: |
|
175 | if debug: | |
@@ -216,6 +220,76 b' def _committedforwardcopies(a, b, match)' | |||||
216 | % (util.timer() - start)) |
|
220 | % (util.timer() - start)) | |
217 | return cm |
|
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 | def _forwardcopies(a, b, match=None): |
|
293 | def _forwardcopies(a, b, match=None): | |
220 | """find {dst@b: src@a} copy mapping where a is an ancestor of b""" |
|
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 | $ cat >> $HGRCPATH << EOF |
|
3 | $ cat >> $HGRCPATH << EOF | |
3 | > [alias] |
|
4 | > [alias] | |
4 | > l = log -G -T '{rev} {desc}\n{files}\n' |
|
5 | > l = log -G -T '{rev} {desc}\n{files}\n' | |
5 | > EOF |
|
6 | > EOF | |
6 |
|
7 | |||
|
8 | #if compatibility | |||
|
9 | $ cat >> $HGRCPATH << EOF | |||
|
10 | > [experimental] | |||
|
11 | > copies.read-from = compatibility | |||
|
12 | > EOF | |||
|
13 | #endif | |||
|
14 | ||||
7 | $ REPONUM=0 |
|
15 | $ REPONUM=0 | |
8 | $ newrepo() { |
|
16 | $ newrepo() { | |
9 | > cd $TESTTMP |
|
17 | > cd $TESTTMP | |
@@ -338,7 +346,7 b" It's a little weird that it shows up on " | |||||
338 | $ hg debugpathcopies 1 2 |
|
346 | $ hg debugpathcopies 1 2 | |
339 | x -> z |
|
347 | x -> z | |
340 | $ hg debugpathcopies 0 2 |
|
348 | $ hg debugpathcopies 0 2 | |
341 | x -> z |
|
349 | x -> z (filelog !) | |
342 |
|
350 | |||
343 | Copy file that exists on both sides of the merge, different content |
|
351 | Copy file that exists on both sides of the merge, different content | |
344 | $ newrepo |
|
352 | $ newrepo | |
@@ -476,7 +484,8 b' Try merging the other direction too' | |||||
476 | $ hg debugpathcopies 1 4 |
|
484 | $ hg debugpathcopies 1 4 | |
477 | $ hg debugpathcopies 2 4 |
|
485 | $ hg debugpathcopies 2 4 | |
478 | $ hg debugpathcopies 0 4 |
|
486 | $ hg debugpathcopies 0 4 | |
479 | x -> z |
|
487 | x -> z (filelog !) | |
|
488 | y -> z (compatibility !) | |||
480 | $ hg debugpathcopies 1 5 |
|
489 | $ hg debugpathcopies 1 5 | |
481 | $ hg debugpathcopies 2 5 |
|
490 | $ hg debugpathcopies 2 5 | |
482 | $ hg debugpathcopies 0 5 |
|
491 | $ hg debugpathcopies 0 5 |
General Comments 0
You need to be logged in to leave comments.
Login now