diff --git a/hgext3rd/copytrace.py b/hgext3rd/copytrace.py --- a/hgext3rd/copytrace.py +++ b/hgext3rd/copytrace.py @@ -23,8 +23,8 @@ # limits the number of heuristically found move candidates to check maxmovescandidatestocheck = 5 - # whether to enable fast copytracing during amends (requires fastcopytrace) - # to be enabled. + # whether to enable fast copytracing during amends (requires fastcopytrace + # to be enabled.) enableamendcopytrace = True # how many previous commits to search through when looking for amend @@ -344,8 +344,11 @@ if not _fastcopytraceenabled(repo.ui): return orig(repo, cdst, csrc, base) - if not cdst or not csrc or cdst == csrc: - return {}, {}, {}, {}, {} + if _isfullcopytraceable(cdst, base): + configoverrides = {('experimental', 'disablecopytrace'): False} + with repo.ui.configoverride(configoverrides, 'mergecopies'): + result = orig(repo, cdst, csrc, base) + return result # avoid silly behavior for parent -> working dir if csrc.node() is None and cdst.node() == repo.dirstate.p1(): @@ -452,3 +455,13 @@ def _gethex(ctx): # for workingctx return p1 hex return ctx.hex() if ctx.hex() != node.wdirhex else ctx.p1().hex() + +def _isfullcopytraceable(cdst, base): + if cdst.phase() == phases.draft and base.phase() == phases.draft: + # draft branch: Use traditional copytracing if < 100 commits + ctx = cdst + commits = 0 + while ctx != base and commits != 100: + ctx = ctx.p1() + commits += 1 + return commits < 100 diff --git a/tests/test-copytrace.t b/tests/test-copytrace.t --- a/tests/test-copytrace.t +++ b/tests/test-copytrace.t @@ -189,9 +189,9 @@ $ rm -rf repo Check a few potential move candidates - $ hg init repo - $ initclient repo - $ cd repo + $ hg init server + $ initclient server + $ cd server $ mkdir dir $ echo a > dir/a $ hg add dir/a @@ -202,6 +202,10 @@ $ echo b > dir2/a $ hg add dir2/a $ hg ci -qm 'create dir2/a' + $ cd .. + $ hg clone -q server repo + $ initclient repo + $ cd repo $ hg up -q 0 $ echo b > dir/a $ hg ci -qm 'mod dir/a' @@ -210,11 +214,11 @@ @ changeset: 6b2f4cece40fd320f41229f23821256ffc08efea | desc: mod dir/a, phase: draft | o changeset: 4494bf7efd2e0dfdd388e767fb913a8a3731e3fa - | | desc: create dir2/a, phase: draft + | | desc: create dir2/a, phase: public | o changeset: b1784dfab6ea6bfafeb11c0ac50a2981b0fe6ade - |/ desc: mv dir/a dir/b, phase: draft + |/ desc: mv dir/a dir/b, phase: public o changeset: 36859b8907c513a3a87ae34ba5b1e7eea8c20944 - desc: initial, phase: draft + desc: initial, phase: public $ hg rebase -s . -d 2 rebasing 3:6b2f4cece40f "mod dir/a" (tip) @@ -248,6 +252,8 @@ $ hg rebase -s 1 -d 2 rebasing 1:472e38d57782 "mv a b" + note: possible conflict - a was deleted and renamed to: + b saved backup bundle to $TESTTMP/repo/.hg/strip-backup/472e38d57782-17d50e29-rebase.hg (glob) $ hg up -q c492ed3c7e35dcd1dc938053b8adf56e2cfbd062 $ ls @@ -257,9 +263,9 @@ $ rm -rf repo Too many move candidates - $ hg init repo - $ initclient repo - $ cd repo + $ hg init server + $ initclient server + $ cd server $ echo a > a $ hg add a $ hg ci -m initial @@ -277,6 +283,10 @@ $ hg add f $ hg add g $ hg ci -m 'rm a, add many files' + $ cd .. + $ hg clone -q server repo + $ initclient repo + $ cd repo $ hg up -q ".^" $ echo b > a $ hg ci -m 'mod a' @@ -286,9 +296,9 @@ @ changeset: ef716627c70bf4ca0bdb623cfb0d6fe5b9acc51e | desc: mod a, phase: draft | o changeset: d133babe0b735059c360d36b4b47200cdd6bcef5 - |/ desc: rm a, add many files, phase: draft + |/ desc: rm a, add many files, phase: public o changeset: 1451231c87572a7d3f92fc210b4b35711c949a98 - desc: initial, phase: draft + desc: initial, phase: public $ hg rebase -s 2 -d 1 rebasing 2:ef716627c70b "mod a" (tip) @@ -333,9 +343,9 @@ $ rm -rf repo Move file twice and rebase mod on top of moves - $ hg init repo - $ initclient repo - $ cd repo + $ hg init server + $ initclient server + $ cd server $ echo a > a $ hg add a $ hg ci -m initial @@ -343,6 +353,10 @@ $ hg ci -m 'mv a b' $ hg mv b c $ hg ci -m 'mv b c' + $ cd .. + $ hg clone -q server repo + $ initclient repo + $ cd repo $ hg up -q 0 $ echo c > a $ hg ci -m 'mod a' @@ -351,11 +365,11 @@ @ changeset: d413169422167a3fa5275fc5d71f7dea9f5775f3 | desc: mod a, phase: draft | o changeset: d3efd280421d24f9f229997c19e654761c942a71 - | | desc: mv b c, phase: draft + | | desc: mv b c, phase: public | o changeset: 472e38d57782172f6c6abed82a94ca0d998c3a22 - |/ desc: mv a b, phase: draft + |/ desc: mv a b, phase: public o changeset: 1451231c87572a7d3f92fc210b4b35711c949a98 - desc: initial, phase: draft + desc: initial, phase: public $ hg rebase -s . -d 2 rebasing 3:d41316942216 "mod a" (tip) merging c and a to c @@ -401,9 +415,9 @@ $ rm -rf repo Move one file and add another file in the same folder in one branch, modify file in another branch - $ hg init repo - $ initclient repo - $ cd repo + $ hg init server + $ initclient server + $ cd server $ echo a > a $ hg add a $ hg ci -m initial @@ -412,6 +426,10 @@ $ echo c > c $ hg add c $ hg ci -m 'add c' + $ cd .. + $ hg clone -q server repo + $ initclient repo + $ cd repo $ hg up -q 0 $ echo b > a $ hg ci -m 'mod a' @@ -421,11 +439,11 @@ @ changeset: ef716627c70bf4ca0bdb623cfb0d6fe5b9acc51e | desc: mod a, phase: draft | o changeset: b1a6187e79fbce851bb584eadcb0cc4a80290fd9 - | | desc: add c, phase: draft + | | desc: add c, phase: public | o changeset: 472e38d57782172f6c6abed82a94ca0d998c3a22 - |/ desc: mv a b, phase: draft + |/ desc: mv a b, phase: public o changeset: 1451231c87572a7d3f92fc210b4b35711c949a98 - desc: initial, phase: draft + desc: initial, phase: public $ hg rebase -s . -d 2 rebasing 3:ef716627c70b "mod a" (tip) @@ -475,15 +493,19 @@ $ rm -rf repo Copy and move file - $ hg init repo - $ initclient repo - $ cd repo + $ hg init server + $ initclient server + $ cd server $ echo a > a $ hg add a $ hg ci -m initial $ hg cp a c $ hg mv a b $ hg ci -m 'cp a c, mv a b' + $ cd .. + $ hg clone -q server repo + $ initclient repo + $ cd repo $ hg up -q 0 $ echo b > a $ hg ci -m 'mod a' @@ -493,9 +515,9 @@ @ changeset: ef716627c70bf4ca0bdb623cfb0d6fe5b9acc51e | desc: mod a, phase: draft | o changeset: 4fc3fd13fbdb89ada6b75bfcef3911a689a0dde8 - |/ desc: cp a c, mv a b, phase: draft + |/ desc: cp a c, mv a b, phase: public o changeset: 1451231c87572a7d3f92fc210b4b35711c949a98 - desc: initial, phase: draft + desc: initial, phase: public $ hg rebase -s . -d 1 rebasing 2:ef716627c70b "mod a" (tip) @@ -514,14 +536,18 @@ $ rm -rf repo Do a merge commit with many consequent moves in one branch - $ hg init repo - $ initclient repo - $ cd repo + $ hg init server + $ initclient server + $ cd server $ echo a > a $ hg add a $ hg ci -m initial $ echo b > a $ hg ci -qm 'mod a' + $ cd .. + $ hg clone -q server repo + $ initclient repo + $ cd repo $ hg up -q ".^" $ hg mv a b $ hg ci -qm 'mv a b' @@ -534,9 +560,9 @@ o changeset: 472e38d57782172f6c6abed82a94ca0d998c3a22 | desc: mv a b, phase: draft | @ changeset: ef716627c70bf4ca0bdb623cfb0d6fe5b9acc51e - |/ desc: mod a, phase: draft + |/ desc: mod a, phase: public o changeset: 1451231c87572a7d3f92fc210b4b35711c949a98 - desc: initial, phase: draft + desc: initial, phase: public $ hg merge 3 merging a and c to c @@ -551,9 +577,9 @@ | o changeset: 472e38d57782172f6c6abed82a94ca0d998c3a22 | | desc: mv a b, phase: draft o | changeset: ef716627c70bf4ca0bdb623cfb0d6fe5b9acc51e - |/ desc: mod a, phase: draft + |/ desc: mod a, phase: public o changeset: 1451231c87572a7d3f92fc210b4b35711c949a98 - desc: initial, phase: draft + desc: initial, phase: public $ ls c $ cd .. @@ -561,12 +587,16 @@ $ rm -rf repo Test shelve/unshelve - $ hg init repo - $ initclient repo - $ cd repo + $ hg init server + $ initclient server + $ cd server $ echo a > a $ hg add a $ hg ci -m initial + $ cd .. + $ hg clone -q server repo + $ initclient repo + $ cd repo $ echo b > a $ hg shelve shelved as default @@ -578,7 +608,7 @@ @ changeset: 472e38d57782172f6c6abed82a94ca0d998c3a22 | desc: mv a b, phase: draft o changeset: 1451231c87572a7d3f92fc210b4b35711c949a98 - desc: initial, phase: draft + desc: initial, phase: public $ hg unshelve unshelving change 'default' rebasing shelved changes @@ -591,3 +621,77 @@ $ cd .. $ rm -rf server $ rm -rf repo + +Test full copytrace ability on draft branch: File directory and base name +changed in same move + $ hg init repo + $ initclient repo + $ mkdir repo/dir1 + $ cd repo/dir1 + $ echo a > a + $ hg add a + $ hg ci -qm initial + $ cd .. + $ hg mv -q dir1 dir2 + $ hg mv dir2/a dir2/b + $ hg ci -qm 'mv a b; mv dir1 dir2' + $ hg up -q '.^' + $ cd dir1 + $ echo b >> a + $ cd .. + $ hg ci -qm 'mod a' + + $ hg log -G -T 'changeset {node}\n desc {desc}, phase: {phase}\n' + @ changeset 6207d2d318e710b882e3d5ada2a89770efc42c96 + | desc mod a, phase: draft + | o changeset abffdd4e3dfc04bc375034b970299b2a309a1cce + |/ desc mv a b; mv dir1 dir2, phase: draft + o changeset 81973cd24b58db2fdf18ce3d64fb2cc3284e9ab3 + desc initial, phase: draft + + $ hg rebase -s . -d 1 + rebasing 2:6207d2d318e7 "mod a" (tip) + merging dir2/b and dir1/a to dir2/b + saved backup bundle to $TESTTMP/repo/repo/.hg/strip-backup/6207d2d318e7-1c9779ad-rebase.hg (glob) + $ cat dir2/b + a + b + $ cd .. + $ rm -rf server + $ rm -rf repo + +Test full copytrace ability on draft branch: Move directory in one merge parent, +while adding file to original directory in other merge parent. File moved on rebase. + $ hg init repo + $ initclient repo + $ mkdir repo/dir1 + $ cd repo/dir1 + $ echo dummy > dummy + $ hg add dummy + $ cd .. + $ hg ci -qm initial + $ cd dir1 + $ echo a > a + $ hg add a + $ cd .. + $ hg ci -qm 'hg add dir1/a' + $ hg up -q '.^' + $ hg mv -q dir1 dir2 + $ hg ci -qm 'mv dir1 dir2' + + $ hg log -G -T 'changeset {node}\n desc {desc}, phase: {phase}\n' + @ changeset e8919e7df8d036e07b906045eddcd4a42ff1915f + | desc mv dir1 dir2, phase: draft + | o changeset 7c7c6f339be00f849c3cb2df738ca91db78b32c8 + |/ desc hg add dir1/a, phase: draft + o changeset a235dcce55dcf42034c4e374cb200662d0bb4a13 + desc initial, phase: draft + + $ hg rebase -s . -d 1 + rebasing 2:e8919e7df8d0 "mv dir1 dir2" (tip) + saved backup bundle to $TESTTMP/repo/repo/.hg/strip-backup/e8919e7df8d0-f62fab62-rebase.hg (glob) + $ ls dir2 + a + dummy + $ rm -rf server + $ rm -rf repo