Patchwork D625: copytrace: use the full copytracing method if only drafts are involved

login
register
mail settings
Submitter phabricator
Date Sept. 9, 2017, 10:51 p.m.
Message ID <7cab2fca4632c0c3f1ff86b3447c19a5@localhost.localdomain>
Download mbox | patch
Permalink /patch/23744/
State Not Applicable
Headers show

Comments

phabricator - Sept. 9, 2017, 10:51 p.m.
pulkit updated this revision to Diff 1689.
pulkit edited the summary of this revision.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D625?vs=1605&id=1689

REVISION DETAIL
  https://phab.mercurial-scm.org/D625

AFFECTED FILES
  mercurial/copies.py
  tests/test-copytrace-heuristics.t

CHANGE DETAILS




To: pulkit, #hg-reviewers, yuja
Cc: yuja, mercurial-devel

Patch

diff --git a/tests/test-copytrace-heuristics.t b/tests/test-copytrace-heuristics.t
--- a/tests/test-copytrace-heuristics.t
+++ b/tests/test-copytrace-heuristics.t
@@ -589,3 +589,79 @@ 
   $ 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
+
+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
diff --git a/mercurial/copies.py b/mercurial/copies.py
--- a/mercurial/copies.py
+++ b/mercurial/copies.py
@@ -15,6 +15,7 @@ 
     match as matchmod,
     node,
     pathutil,
+    phases,
     scmutil,
     util,
 )
@@ -367,10 +368,27 @@ 
     if copytracing == 'off':
         return {}, {}, {}, {}, {}
     elif copytracing == 'heuristics':
+        # Do full copytracing if only drafts are involved as that will be fast
+        # enough and will also cover the copies which can be missed by
+        # heuristics
+        if _isfullcopytraceable(c1, base):
+            return _fullcopytracing(repo, c1, c2, base)
         return _heuristicscopytracing(repo, c1, c2, base)
     else:
         return _fullcopytracing(repo, c1, c2, base)
 
+def _isfullcopytraceable(c1, base):
+    """ Checks that if base, source and destination are all draft branches, if
+    yes let's use the full copytrace algorithm for increased capabilities since
+    it will be fast enough.
+    """
+
+    nonpublicphases = set([phases.draft, phases.secret])
+
+    if (c1.phase() in nonpublicphases) and (base.phase() in nonpublicphases):
+        return True
+    return False
+
 def _fullcopytracing(repo, c1, c2, base):
     """ The full copytracing algorithm which finds all the new files that were
     added from merge base up to the top commit and for each file it checks if