##// END OF EJS Templates
copytrace: move fast heuristic copytracing algorithm to core...
Pulkit Goyal -
r34180:036d47d7 default
parent child Browse files
Show More
This diff has been collapsed as it changes many lines, (591 lines changed) Show them Hide them
@@ -0,0 +1,591 b''
1 Test for the heuristic copytracing algorithm
2 ============================================
3
4 $ cat >> $TESTTMP/copytrace.sh << '__EOF__'
5 > initclient() {
6 > cat >> $1/.hg/hgrc <<EOF
7 > [experimental]
8 > copytrace = heuristics
9 > EOF
10 > }
11 > __EOF__
12 $ . "$TESTTMP/copytrace.sh"
13
14 $ cat >> $HGRCPATH << EOF
15 > [extensions]
16 > rebase=
17 > shelve=
18 > EOF
19
20 Check filename heuristics (same dirname and same basename)
21 $ hg init server
22 $ cd server
23 $ echo a > a
24 $ mkdir dir
25 $ echo a > dir/file.txt
26 $ hg addremove
27 adding a
28 adding dir/file.txt
29 $ hg ci -m initial
30 $ hg mv a b
31 $ hg mv -q dir dir2
32 $ hg ci -m 'mv a b, mv dir/ dir2/'
33 $ cd ..
34 $ hg clone -q server repo
35 $ initclient repo
36 $ cd repo
37 $ hg up -q 0
38 $ echo b > a
39 $ echo b > dir/file.txt
40 $ hg ci -qm 'mod a, mod dir/file.txt'
41
42 $ hg log -G -T 'changeset: {node}\n desc: {desc}, phase: {phase}\n'
43 @ changeset: 557f403c0afd2a3cf15d7e2fb1f1001a8b85e081
44 | desc: mod a, mod dir/file.txt, phase: draft
45 | o changeset: 928d74bc9110681920854d845c06959f6dfc9547
46 |/ desc: mv a b, mv dir/ dir2/, phase: public
47 o changeset: 3c482b16e54596fed340d05ffaf155f156cda7ee
48 desc: initial, phase: public
49
50 $ hg rebase -s . -d 1
51 rebasing 2:557f403c0afd "mod a, mod dir/file.txt" (tip)
52 merging b and a to b
53 merging dir2/file.txt and dir/file.txt to dir2/file.txt
54 saved backup bundle to $TESTTMP/repo/.hg/strip-backup/557f403c0afd-9926eeff-rebase.hg (glob)
55 $ cd ..
56 $ rm -rf server
57 $ rm -rf repo
58
59 Make sure filename heuristics do not when they are not related
60 $ hg init server
61 $ cd server
62 $ echo 'somecontent' > a
63 $ hg add a
64 $ hg ci -m initial
65 $ hg rm a
66 $ echo 'completelydifferentcontext' > b
67 $ hg add b
68 $ hg ci -m 'rm a, add b'
69 $ cd ..
70 $ hg clone -q server repo
71 $ initclient repo
72 $ cd repo
73 $ hg up -q 0
74 $ printf 'somecontent\nmoarcontent' > a
75 $ hg ci -qm 'mode a'
76
77 $ hg log -G -T 'changeset: {node}\n desc: {desc}, phase: {phase}\n'
78 @ changeset: d526312210b9e8f795d576a77dc643796384d86e
79 | desc: mode a, phase: draft
80 | o changeset: 46985f76c7e5e5123433527f5c8526806145650b
81 |/ desc: rm a, add b, phase: public
82 o changeset: e5b71fb099c29d9172ef4a23485aaffd497e4cc0
83 desc: initial, phase: public
84
85 $ hg rebase -s . -d 1
86 rebasing 2:d526312210b9 "mode a" (tip)
87 other [source] changed a which local [dest] deleted
88 use (c)hanged version, leave (d)eleted, or leave (u)nresolved? u
89 unresolved conflicts (see hg resolve, then hg rebase --continue)
90 [1]
91
92 $ cd ..
93 $ rm -rf server
94 $ rm -rf repo
95
96 Test when lca didn't modified the file that was moved
97 $ hg init server
98 $ cd server
99 $ echo 'somecontent' > a
100 $ hg add a
101 $ hg ci -m initial
102 $ echo c > c
103 $ hg add c
104 $ hg ci -m randomcommit
105 $ hg mv a b
106 $ hg ci -m 'mv a b'
107 $ cd ..
108 $ hg clone -q server repo
109 $ initclient repo
110 $ cd repo
111 $ hg up -q 1
112 $ echo b > a
113 $ hg ci -qm 'mod a'
114
115 $ hg log -G -T 'changeset: {node}\n desc: {desc}, phase: {phase}\n'
116 @ changeset: 9d5cf99c3d9f8e8b05ba55421f7f56530cfcf3bc
117 | desc: mod a, phase: draft
118 | o changeset: d760186dd240fc47b91eb9f0b58b0002aaeef95d
119 |/ desc: mv a b, phase: public
120 o changeset: 48e1b6ba639d5d7fb313fa7989eebabf99c9eb83
121 | desc: randomcommit, phase: public
122 o changeset: e5b71fb099c29d9172ef4a23485aaffd497e4cc0
123 desc: initial, phase: public
124
125 $ hg rebase -s . -d 2
126 rebasing 3:9d5cf99c3d9f "mod a" (tip)
127 merging b and a to b
128 saved backup bundle to $TESTTMP/repo/.hg/strip-backup/9d5cf99c3d9f-f02358cc-rebase.hg (glob)
129 $ cd ..
130 $ rm -rf server
131 $ rm -rf repo
132
133 Rebase "backwards"
134 $ hg init server
135 $ cd server
136 $ echo 'somecontent' > a
137 $ hg add a
138 $ hg ci -m initial
139 $ echo c > c
140 $ hg add c
141 $ hg ci -m randomcommit
142 $ hg mv a b
143 $ hg ci -m 'mv a b'
144 $ cd ..
145 $ hg clone -q server repo
146 $ initclient repo
147 $ cd repo
148 $ hg up -q 2
149 $ echo b > b
150 $ hg ci -qm 'mod b'
151
152 $ hg log -G -T 'changeset: {node}\n desc: {desc}, phase: {phase}\n'
153 @ changeset: fbe97126b3969056795c462a67d93faf13e4d298
154 | desc: mod b, phase: draft
155 o changeset: d760186dd240fc47b91eb9f0b58b0002aaeef95d
156 | desc: mv a b, phase: public
157 o changeset: 48e1b6ba639d5d7fb313fa7989eebabf99c9eb83
158 | desc: randomcommit, phase: public
159 o changeset: e5b71fb099c29d9172ef4a23485aaffd497e4cc0
160 desc: initial, phase: public
161
162 $ hg rebase -s . -d 0
163 rebasing 3:fbe97126b396 "mod b" (tip)
164 merging a and b to a
165 saved backup bundle to $TESTTMP/repo/.hg/strip-backup/fbe97126b396-cf5452a1-rebase.hg (glob)
166 $ cd ..
167 $ rm -rf server
168 $ rm -rf repo
169
170 Rebase draft commit on top of draft commit
171 $ hg init repo
172 $ initclient repo
173 $ cd repo
174 $ echo 'somecontent' > a
175 $ hg add a
176 $ hg ci -m initial
177 $ hg mv a b
178 $ hg ci -m 'mv a b'
179 $ hg up -q ".^"
180 $ echo b > a
181 $ hg ci -qm 'mod a'
182
183 $ hg log -G -T 'changeset: {node}\n desc: {desc}, phase: {phase}\n'
184 @ changeset: 5268f05aa1684cfb5741e9eb05eddcc1c5ee7508
185 | desc: mod a, phase: draft
186 | o changeset: 542cb58df733ee48fa74729bd2cdb94c9310d362
187 |/ desc: mv a b, phase: draft
188 o changeset: e5b71fb099c29d9172ef4a23485aaffd497e4cc0
189 desc: initial, phase: draft
190
191 $ hg rebase -s . -d 1
192 rebasing 2:5268f05aa168 "mod a" (tip)
193 merging b and a to b
194 saved backup bundle to $TESTTMP/repo/.hg/strip-backup/5268f05aa168-284f6515-rebase.hg (glob)
195 $ cd ..
196 $ rm -rf server
197 $ rm -rf repo
198
199 Check a few potential move candidates
200 $ hg init server
201 $ initclient server
202 $ cd server
203 $ mkdir dir
204 $ echo a > dir/a
205 $ hg add dir/a
206 $ hg ci -qm initial
207 $ hg mv dir/a dir/b
208 $ hg ci -qm 'mv dir/a dir/b'
209 $ mkdir dir2
210 $ echo b > dir2/a
211 $ hg add dir2/a
212 $ hg ci -qm 'create dir2/a'
213 $ cd ..
214 $ hg clone -q server repo
215 $ initclient repo
216 $ cd repo
217 $ hg up -q 0
218 $ echo b > dir/a
219 $ hg ci -qm 'mod dir/a'
220
221 $ hg log -G -T 'changeset: {node}\n desc: {desc}, phase: {phase}\n'
222 @ changeset: 6b2f4cece40fd320f41229f23821256ffc08efea
223 | desc: mod dir/a, phase: draft
224 | o changeset: 4494bf7efd2e0dfdd388e767fb913a8a3731e3fa
225 | | desc: create dir2/a, phase: public
226 | o changeset: b1784dfab6ea6bfafeb11c0ac50a2981b0fe6ade
227 |/ desc: mv dir/a dir/b, phase: public
228 o changeset: 36859b8907c513a3a87ae34ba5b1e7eea8c20944
229 desc: initial, phase: public
230
231 $ hg rebase -s . -d 2
232 rebasing 3:6b2f4cece40f "mod dir/a" (tip)
233 merging dir/b and dir/a to dir/b
234 saved backup bundle to $TESTTMP/repo/.hg/strip-backup/6b2f4cece40f-503efe60-rebase.hg (glob)
235 $ cd ..
236 $ rm -rf server
237 $ rm -rf repo
238
239 Move file in one branch and delete it in another
240 $ hg init server
241 $ initclient server
242 $ cd server
243 $ echo a > a
244 $ hg add a
245 $ hg ci -m initial
246 $ cd ..
247 $ hg clone -q server repo
248 $ initclient repo
249 $ cd repo
250 $ hg mv a b
251 $ hg ci -m 'mv a b'
252 $ hg up -q ".^"
253 $ hg rm a
254 $ hg ci -m 'del a'
255 created new head
256
257 $ hg log -G -T 'changeset: {node}\n desc: {desc}, phase: {phase}\n'
258 @ changeset: 7d61ee3b1e48577891a072024968428ba465c47b
259 | desc: del a, phase: draft
260 | o changeset: 472e38d57782172f6c6abed82a94ca0d998c3a22
261 |/ desc: mv a b, phase: draft
262 o changeset: 1451231c87572a7d3f92fc210b4b35711c949a98
263 desc: initial, phase: public
264
265 $ hg rebase -s 1 -d 2
266 rebasing 1:472e38d57782 "mv a b"
267 saved backup bundle to $TESTTMP/repo/.hg/strip-backup/472e38d57782-17d50e29-rebase.hg (glob)
268 $ hg up -q c492ed3c7e35dcd1dc938053b8adf56e2cfbd062
269 $ ls
270 b
271 $ cd ..
272 $ rm -rf server
273 $ rm -rf repo
274
275 Move a directory in draft branch
276 $ hg init server
277 $ initclient server
278 $ cd server
279 $ mkdir dir
280 $ echo a > dir/a
281 $ hg add dir/a
282 $ hg ci -qm initial
283 $ cd ..
284 $ hg clone -q server repo
285 $ initclient repo
286 $ cd repo
287 $ echo b > dir/a
288 $ hg ci -qm 'mod dir/a'
289 $ hg up -q ".^"
290 $ hg mv -q dir/ dir2
291 $ hg ci -qm 'mv dir/ dir2/'
292
293 $ hg log -G -T 'changeset: {node}\n desc: {desc}, phase: {phase}\n'
294 @ changeset: a33d80b6e352591dfd82784e1ad6cdd86b25a239
295 | desc: mv dir/ dir2/, phase: draft
296 | o changeset: 6b2f4cece40fd320f41229f23821256ffc08efea
297 |/ desc: mod dir/a, phase: draft
298 o changeset: 36859b8907c513a3a87ae34ba5b1e7eea8c20944
299 desc: initial, phase: public
300
301 $ hg rebase -s . -d 1
302 rebasing 2:a33d80b6e352 "mv dir/ dir2/" (tip)
303 merging dir/a and dir2/a to dir2/a
304 saved backup bundle to $TESTTMP/repo/.hg/strip-backup/a33d80b6e352-fecb9ada-rebase.hg (glob)
305 $ cd ..
306 $ rm -rf server
307 $ rm -rf repo
308
309 Move file twice and rebase mod on top of moves
310 $ hg init server
311 $ initclient server
312 $ cd server
313 $ echo a > a
314 $ hg add a
315 $ hg ci -m initial
316 $ hg mv a b
317 $ hg ci -m 'mv a b'
318 $ hg mv b c
319 $ hg ci -m 'mv b c'
320 $ cd ..
321 $ hg clone -q server repo
322 $ initclient repo
323 $ cd repo
324 $ hg up -q 0
325 $ echo c > a
326 $ hg ci -m 'mod a'
327 created new head
328 $ hg log -G -T 'changeset: {node}\n desc: {desc}, phase: {phase}\n'
329 @ changeset: d413169422167a3fa5275fc5d71f7dea9f5775f3
330 | desc: mod a, phase: draft
331 | o changeset: d3efd280421d24f9f229997c19e654761c942a71
332 | | desc: mv b c, phase: public
333 | o changeset: 472e38d57782172f6c6abed82a94ca0d998c3a22
334 |/ desc: mv a b, phase: public
335 o changeset: 1451231c87572a7d3f92fc210b4b35711c949a98
336 desc: initial, phase: public
337 $ hg rebase -s . -d 2
338 rebasing 3:d41316942216 "mod a" (tip)
339 merging c and a to c
340 saved backup bundle to $TESTTMP/repo/.hg/strip-backup/d41316942216-2b5949bc-rebase.hg (glob)
341
342 $ cd ..
343 $ rm -rf server
344 $ rm -rf repo
345
346 Move file twice and rebase moves on top of mods
347 $ hg init server
348 $ initclient server
349 $ cd server
350 $ echo a > a
351 $ hg add a
352 $ hg ci -m initial
353 $ cd ..
354 $ hg clone -q server repo
355 $ initclient repo
356 $ cd repo
357 $ hg mv a b
358 $ hg ci -m 'mv a b'
359 $ hg mv b c
360 $ hg ci -m 'mv b c'
361 $ hg up -q 0
362 $ echo c > a
363 $ hg ci -m 'mod a'
364 created new head
365 $ hg log -G -T 'changeset: {node}\n desc: {desc}, phase: {phase}\n'
366 @ changeset: d413169422167a3fa5275fc5d71f7dea9f5775f3
367 | desc: mod a, phase: draft
368 | o changeset: d3efd280421d24f9f229997c19e654761c942a71
369 | | desc: mv b c, phase: draft
370 | o changeset: 472e38d57782172f6c6abed82a94ca0d998c3a22
371 |/ desc: mv a b, phase: draft
372 o changeset: 1451231c87572a7d3f92fc210b4b35711c949a98
373 desc: initial, phase: public
374 $ hg rebase -s 1 -d .
375 rebasing 1:472e38d57782 "mv a b"
376 merging a and b to b
377 rebasing 2:d3efd280421d "mv b c"
378 merging b and c to c
379 saved backup bundle to $TESTTMP/repo/.hg/strip-backup/472e38d57782-ab8d3c58-rebase.hg (glob)
380
381 $ cd ..
382 $ rm -rf server
383 $ rm -rf repo
384
385 Move one file and add another file in the same folder in one branch, modify file in another branch
386 $ hg init server
387 $ initclient server
388 $ cd server
389 $ echo a > a
390 $ hg add a
391 $ hg ci -m initial
392 $ hg mv a b
393 $ hg ci -m 'mv a b'
394 $ echo c > c
395 $ hg add c
396 $ hg ci -m 'add c'
397 $ cd ..
398 $ hg clone -q server repo
399 $ initclient repo
400 $ cd repo
401 $ hg up -q 0
402 $ echo b > a
403 $ hg ci -m 'mod a'
404 created new head
405
406 $ hg log -G -T 'changeset: {node}\n desc: {desc}, phase: {phase}\n'
407 @ changeset: ef716627c70bf4ca0bdb623cfb0d6fe5b9acc51e
408 | desc: mod a, phase: draft
409 | o changeset: b1a6187e79fbce851bb584eadcb0cc4a80290fd9
410 | | desc: add c, phase: public
411 | o changeset: 472e38d57782172f6c6abed82a94ca0d998c3a22
412 |/ desc: mv a b, phase: public
413 o changeset: 1451231c87572a7d3f92fc210b4b35711c949a98
414 desc: initial, phase: public
415
416 $ hg rebase -s . -d 2
417 rebasing 3:ef716627c70b "mod a" (tip)
418 merging b and a to b
419 saved backup bundle to $TESTTMP/repo/.hg/strip-backup/ef716627c70b-24681561-rebase.hg (glob)
420 $ ls
421 b
422 c
423 $ cat b
424 b
425
426 Merge test
427 $ hg init server
428 $ cd server
429 $ echo a > a
430 $ hg add a
431 $ hg ci -m initial
432 $ echo b > a
433 $ hg ci -m 'modify a'
434 $ hg up -q 0
435 $ hg mv a b
436 $ hg ci -m 'mv a b'
437 created new head
438 $ cd ..
439 $ hg clone -q server repo
440 $ initclient repo
441 $ cd repo
442 $ hg up -q 2
443
444 $ hg log -G -T 'changeset: {node}\n desc: {desc}, phase: {phase}\n'
445 @ changeset: 472e38d57782172f6c6abed82a94ca0d998c3a22
446 | desc: mv a b, phase: public
447 | o changeset: b0357b07f79129a3d08a68621271ca1352ae8a09
448 |/ desc: modify a, phase: public
449 o changeset: 1451231c87572a7d3f92fc210b4b35711c949a98
450 desc: initial, phase: public
451
452 $ hg merge 1
453 merging b and a to b
454 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
455 (branch merge, don't forget to commit)
456 $ hg ci -m merge
457 $ ls
458 b
459 $ cd ..
460 $ rm -rf server
461 $ rm -rf repo
462
463 Copy and move file
464 $ hg init server
465 $ initclient server
466 $ cd server
467 $ echo a > a
468 $ hg add a
469 $ hg ci -m initial
470 $ hg cp a c
471 $ hg mv a b
472 $ hg ci -m 'cp a c, mv a b'
473 $ cd ..
474 $ hg clone -q server repo
475 $ initclient repo
476 $ cd repo
477 $ hg up -q 0
478 $ echo b > a
479 $ hg ci -m 'mod a'
480 created new head
481
482 $ hg log -G -T 'changeset: {node}\n desc: {desc}, phase: {phase}\n'
483 @ changeset: ef716627c70bf4ca0bdb623cfb0d6fe5b9acc51e
484 | desc: mod a, phase: draft
485 | o changeset: 4fc3fd13fbdb89ada6b75bfcef3911a689a0dde8
486 |/ desc: cp a c, mv a b, phase: public
487 o changeset: 1451231c87572a7d3f92fc210b4b35711c949a98
488 desc: initial, phase: public
489
490 $ hg rebase -s . -d 1
491 rebasing 2:ef716627c70b "mod a" (tip)
492 merging b and a to b
493 merging c and a to c
494 saved backup bundle to $TESTTMP/repo/repo/.hg/strip-backup/ef716627c70b-24681561-rebase.hg (glob)
495 $ ls
496 b
497 c
498 $ cat b
499 b
500 $ cat c
501 b
502 $ cd ..
503 $ rm -rf server
504 $ rm -rf repo
505
506 Do a merge commit with many consequent moves in one branch
507 $ hg init server
508 $ initclient server
509 $ cd server
510 $ echo a > a
511 $ hg add a
512 $ hg ci -m initial
513 $ echo b > a
514 $ hg ci -qm 'mod a'
515 $ cd ..
516 $ hg clone -q server repo
517 $ initclient repo
518 $ cd repo
519 $ hg up -q ".^"
520 $ hg mv a b
521 $ hg ci -qm 'mv a b'
522 $ hg mv b c
523 $ hg ci -qm 'mv b c'
524 $ hg up -q 1
525 $ hg log -G -T 'changeset: {node}\n desc: {desc}, phase: {phase}\n'
526 o changeset: d3efd280421d24f9f229997c19e654761c942a71
527 | desc: mv b c, phase: draft
528 o changeset: 472e38d57782172f6c6abed82a94ca0d998c3a22
529 | desc: mv a b, phase: draft
530 | @ changeset: ef716627c70bf4ca0bdb623cfb0d6fe5b9acc51e
531 |/ desc: mod a, phase: public
532 o changeset: 1451231c87572a7d3f92fc210b4b35711c949a98
533 desc: initial, phase: public
534
535 $ hg merge 3
536 merging a and c to c
537 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
538 (branch merge, don't forget to commit)
539 $ hg ci -qm 'merge'
540 $ hg log -G -T 'changeset: {node}\n desc: {desc}, phase: {phase}\n'
541 @ changeset: cd29b0d08c0f39bfed4cde1b40e30f419db0c825
542 |\ desc: merge, phase: draft
543 | o changeset: d3efd280421d24f9f229997c19e654761c942a71
544 | | desc: mv b c, phase: draft
545 | o changeset: 472e38d57782172f6c6abed82a94ca0d998c3a22
546 | | desc: mv a b, phase: draft
547 o | changeset: ef716627c70bf4ca0bdb623cfb0d6fe5b9acc51e
548 |/ desc: mod a, phase: public
549 o changeset: 1451231c87572a7d3f92fc210b4b35711c949a98
550 desc: initial, phase: public
551 $ ls
552 c
553 $ cd ..
554 $ rm -rf server
555 $ rm -rf repo
556
557 Test shelve/unshelve
558 $ hg init server
559 $ initclient server
560 $ cd server
561 $ echo a > a
562 $ hg add a
563 $ hg ci -m initial
564 $ cd ..
565 $ hg clone -q server repo
566 $ initclient repo
567 $ cd repo
568 $ echo b > a
569 $ hg shelve
570 shelved as default
571 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
572 $ hg mv a b
573 $ hg ci -m 'mv a b'
574
575 $ hg log -G -T 'changeset: {node}\n desc: {desc}, phase: {phase}\n'
576 @ changeset: 472e38d57782172f6c6abed82a94ca0d998c3a22
577 | desc: mv a b, phase: draft
578 o changeset: 1451231c87572a7d3f92fc210b4b35711c949a98
579 desc: initial, phase: public
580 $ hg unshelve
581 unshelving change 'default'
582 rebasing shelved changes
583 rebasing 2:45f63161acea "changes to: initial" (tip)
584 merging b and a to b
585 $ ls
586 b
587 $ cat b
588 b
589 $ cd ..
590 $ rm -rf server
591 $ rm -rf repo
@@ -7,7 +7,9 b''
7
7
8 from __future__ import absolute_import
8 from __future__ import absolute_import
9
9
10 import collections
10 import heapq
11 import heapq
12 import os
11
13
12 from . import (
14 from . import (
13 match as matchmod,
15 match as matchmod,
@@ -364,6 +366,8 b' def mergecopies(repo, c1, c2, base):'
364 # rebase.
366 # rebase.
365 if copytracing == 'off':
367 if copytracing == 'off':
366 return {}, {}, {}, {}, {}
368 return {}, {}, {}, {}, {}
369 elif copytracing == 'heuristics':
370 return _heuristicscopytracing(repo, c1, c2, base)
367 else:
371 else:
368 return _fullcopytracing(repo, c1, c2, base)
372 return _fullcopytracing(repo, c1, c2, base)
369
373
@@ -599,6 +603,94 b' def _fullcopytracing(repo, c1, c2, base)'
599
603
600 return copy, movewithdir, diverge, renamedelete, dirmove
604 return copy, movewithdir, diverge, renamedelete, dirmove
601
605
606 def _heuristicscopytracing(repo, c1, c2, base):
607 """ Fast copytracing using filename heuristics
608
609 Assumes that moves or renames are of following two types:
610
611 1) Inside a directory only (same directory name but different filenames)
612 2) Move from one directory to another
613 (same filenames but different directory names)
614
615 Works only when there are no merge commits in the "source branch".
616 Source branch is commits from base up to c2 not including base.
617
618 If merge is involved it fallbacks to _fullcopytracing().
619
620 Can be used by setting the following config:
621
622 [experimental]
623 copytrace = heuristics
624 """
625
626 if c1.rev() is None:
627 c1 = c1.p1()
628 if c2.rev() is None:
629 c2 = c2.p1()
630
631 copies = {}
632
633 changedfiles = set()
634 m1 = c1.manifest()
635 if not repo.revs('%d::%d', base.rev(), c2.rev()):
636 # If base is not in c2 branch, we switch to fullcopytracing
637 repo.ui.debug("switching to full copytracing as base is not "
638 "an ancestor of c2\n")
639 return _fullcopytracing(repo, c1, c2, base)
640
641 ctx = c2
642 while ctx != base:
643 if len(ctx.parents()) == 2:
644 # To keep things simple let's not handle merges
645 repo.ui.debug("switching to full copytracing because of merges\n")
646 return _fullcopytracing(repo, c1, c2, base)
647 changedfiles.update(ctx.files())
648 ctx = ctx.p1()
649
650 cp = _forwardcopies(base, c2)
651 for dst, src in cp.iteritems():
652 if src in m1:
653 copies[dst] = src
654
655 # file is missing if it isn't present in the destination, but is present in
656 # the base and present in the source.
657 # Presence in the base is important to exclude added files, presence in the
658 # source is important to exclude removed files.
659 missingfiles = filter(lambda f: f not in m1 and f in base and f in c2,
660 changedfiles)
661
662 if missingfiles:
663 basenametofilename = collections.defaultdict(list)
664 dirnametofilename = collections.defaultdict(list)
665
666 for f in m1.filesnotin(base.manifest()):
667 basename = os.path.basename(f)
668 dirname = os.path.dirname(f)
669 basenametofilename[basename].append(f)
670 dirnametofilename[dirname].append(f)
671
672 # in case of a rebase/graft, base may not be a common ancestor
673 anc = c1.ancestor(c2)
674
675 for f in missingfiles:
676 basename = os.path.basename(f)
677 dirname = os.path.dirname(f)
678 samebasename = basenametofilename[basename]
679 samedirname = dirnametofilename[dirname]
680 movecandidates = samebasename + samedirname
681 # f is guaranteed to be present in c2, that's why
682 # c2.filectx(f) won't fail
683 f2 = c2.filectx(f)
684 for candidate in movecandidates:
685 f1 = c1.filectx(candidate)
686 if _related(f1, f2, anc.rev()):
687 # if there are a few related copies then we'll merge
688 # changes into all of them. This matches the behaviour
689 # of upstream copytracing
690 copies[candidate] = f
691
692 return copies, {}, {}, {}, {}
693
602 def _related(f1, f2, limit):
694 def _related(f1, f2, limit):
603 """return True if f1 and f2 filectx have a common ancestor
695 """return True if f1 and f2 filectx have a common ancestor
604
696
General Comments 0
You need to be logged in to leave comments. Login now