[PATCH V4] copy: add flag for disabling copy tracing

Martin von Zweigbergk martinvonz at google.com
Tue Apr 14 17:53:46 CDT 2015


On Tue, Apr 14, 2015 at 6:56 AM Durham Goode <durham at fb.com> wrote:

> # HG changeset patch
> # User Durham Goode <durham at fb.com>
> # Date 1422386787 28800
> #      Tue Jan 27 11:26:27 2015 -0800
> # Node ID 5a39559f0caa07ca1a44ee67f7f917138b54198f
> # Parent  52ff737c63d2b2cb41185549aa9c35bc47317032
> copy: add flag for disabling copy tracing
>
> Copy tracing can be up to 80% of rebase time when rebasing stacks
> of commits in large repos (hundreds of thousands of files).
> This provides the option of turning off the majority of copy tracing. It
> does not turn off _forwardcopies() since that is used to carry copy
> information inside a commit across a rebase.
>
> This will affect the situation where a user edits a file, then rebases on
> top of
> commits that have moved that file. The move will not be detected and the
> user
> will have to manually resolve the issue (possibly by redoing the rebase
> with
> this flag off).
>
> This takes rebasing a 3 commit stack that's a couple weeks old from 65s to
> 12s.
>
> diff --git a/mercurial/copies.py b/mercurial/copies.py
> --- a/mercurial/copies.py
> +++ b/mercurial/copies.py
> @@ -186,6 +186,9 @@ def _forwardcopies(a, b):
>      return cm
>
>  def _backwardrenames(a, b):
> +    if a._repo.ui.configbool('experimental', 'disablecopytrace'):
> +        return {}
> +
>      # Even though we're not taking copies into account, 1:n rename
> situations
>      # can still exist (e.g. hg cp a b; hg mv a c). In those cases we
>      # arbitrarily pick one of the renames.
> @@ -258,6 +261,13 @@ def mergecopies(repo, c1, c2, ca):
>      if c2.node() is None and c1.node() == repo.dirstate.p1():
>          return repo.dirstate.copies(), {}, {}, {}
>
> +    if repo.ui.configbool('experimental', 'disablecopytrace'):
> +        # If we're just tracking against the parent, do a simple check.
> +        # This is necessary to ensure copies survive rebasing.
> +        if ca in c2.parents():
> +            return pathcopies(ca, c2), {}, {}, {}
> +        return {}, {}, {}, {}
> +
>      limit = _findlimit(repo, c1.rev(), c2.rev())
>      if limit is None:
>          # no common ancestor, no copies
> @@ -506,7 +516,8 @@ def duplicatecopies(repo, rev, fromrev,
>      copies between fromrev and rev.
>      '''
>      exclude = {}
> -    if skiprev is not None:
> +    if (skiprev is not None and
> +        not repo.ui.configbool('experimental', 'disablecopytrace')):
>

I don't follow this bit, so I tried removing it to see what failed, but all
tests passed. What does it do?


>          exclude = pathcopies(repo[fromrev], repo[skiprev])
>      for dst, src in pathcopies(repo[fromrev], repo[rev]).iteritems():
>          # copies.pathcopies returns backward renames, so dst might not
> diff --git a/tests/test-copy-move-merge.t b/tests/test-copy-move-merge.t
> --- a/tests/test-copy-move-merge.t
> +++ b/tests/test-copy-move-merge.t
> @@ -61,4 +61,73 @@ file c
>    1
>    2
>
> +Test disabling copy tracing
> +
> +- first verify copy metadata was kept
> +
> +  $ hg up -qC 2
> +  $ hg rebase --keep -d 1 -b 2 --config extensions.rebase=
> +  rebasing 2:add3f11052fa "other" (tip)
> +  merging b and a to b
> +  merging c and a to c
> +
> +  $ cat b
> +  0
> +  1
> +  2
> +
> +- next verify copy metadata is lost when disabled
> +
> +  $ hg strip -r . --config extensions.strip=
> +  2 files updated, 0 files merged, 0 files removed, 0 files unresolved
> +  saved backup bundle to
> $TESTTMP/t/.hg/strip-backup/550bd84c0cd3-fc575957-backup.hg (glob)
> +  $ hg up -qC 2
> +  $ hg rebase --keep -d 1 -b 2 --config extensions.rebase= --config
> experimental.disablecopytrace=True
> +  rebasing 2:add3f11052fa "other" (tip)
> +  remote changed a which local deleted
> +  use (c)hanged version or leave (d)eleted? c
> +
> +  $ cat b
> +  1
> +  2
> +
>    $ cd ..
> +
> +Verify disabling copy tracing still keeps copies from rebase source
> +
> +  $ hg init copydisable
> +  $ cd copydisable
> +  $ touch a
> +  $ hg ci -Aqm a
> +  $ touch b
> +  $ touch c
> +  $ hg ci -Aqm b
> +  $ hg cp b x
> +  $ hg cp c y
> +  $ echo x >> x
> +  $ hg ci -qm xy
> +  $ hg up -q 1
> +  $ hg cp b x
> +  $ touch z
> +  $ hg ci -Aqm xz
> +  $ hg log -G -T '{rev} {desc}\n'
> +  @  3 xz
> +  |
> +  | o  2 xy
> +  |/
> +  o  1 b
> +  |
> +  o  0 a
> +
> +  $ hg rebase -d . -b 2 --config extensions.rebase= --config
> experimental.disablecopytrace=True
> +  rebasing 2:002ca7a9f426 "xy"
> +  merging x
> +  saved backup bundle to
> $TESTTMP/copydisable/.hg/strip-backup/002ca7a9f426-19f9ad1e-backup.hg (glob)
> +  $ hg up -q 3
> +  $ hg log -f x -T '{rev} {desc}\n'
> +  3 xy
> +  2 xz
> +  1 b
> +  $ hg log -f y -T '{rev} {desc}\n'
> +  3 xy
> +  1 b
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel at selenic.com
> http://selenic.com/mailman/listinfo/mercurial-devel
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://selenic.com/pipermail/mercurial-devel/attachments/20150414/c072f625/attachment.html>


More information about the Mercurial-devel mailing list