mercurial/copies.py
author Simon Sapin <simon.sapin@octobus.net>
Fri, 29 Jan 2021 13:46:19 +0100
changeset 46494 0da465780bba
parent 46482 892eb7c5edaa
child 46606 c692384bb559
permissions -rw-r--r--
rhg: Build in release mode on CI This follows e73b40c790ec which made tests use the release executable. With e73b40c790ec but not this, tests are skipped on CI because the executable is missing. Differential Revision: https://phab.mercurial-scm.org/D9907
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
46148
70a9eb899637 copies: document the current algorithm step
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46114
diff changeset
     1
# coding: utf8
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     2
# copies.py - copy detection for Mercurial
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     3
#
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     4
# Copyright 2008 Matt Mackall <mpm@selenic.com>
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     5
#
8225
46293a0c7e9f updated license to be explicit about GPL version 2
Martin Geisler <mg@lazybytes.net>
parents: 8209
diff changeset
     6
# This software may be used and distributed according to the terms of the
10263
25e572394f5c Update license to GPLv2+
Matt Mackall <mpm@selenic.com>
parents: 10262
diff changeset
     7
# GNU General Public License version 2 or any later version.
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     8
25924
cfc24c22454e copies: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25289
diff changeset
     9
from __future__ import absolute_import
cfc24c22454e copies: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25289
diff changeset
    10
34191
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34095
diff changeset
    11
import collections
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34095
diff changeset
    12
import os
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    13
34846
f05a6e015ecc copies: add a config to limit the number of candidates to check in heuristics
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34787
diff changeset
    14
from .i18n import _
46114
59fa3890d40a node: import symbols explicitly
Joerg Sonnenberger <joerg@bec.de>
parents: 46110
diff changeset
    15
from .node import (
59fa3890d40a node: import symbols explicitly
Joerg Sonnenberger <joerg@bec.de>
parents: 46110
diff changeset
    16
    nullid,
59fa3890d40a node: import symbols explicitly
Joerg Sonnenberger <joerg@bec.de>
parents: 46110
diff changeset
    17
    nullrev,
59fa3890d40a node: import symbols explicitly
Joerg Sonnenberger <joerg@bec.de>
parents: 46110
diff changeset
    18
)
43148
843da18386d5 sidedatacopies: deal with upgrading and downgrading to that format
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43147
diff changeset
    19
25924
cfc24c22454e copies: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25289
diff changeset
    20
from . import (
33886
252fb66ee5bb copies: use intersectmatchers() in non-merge p1 optimization
Yuya Nishihara <yuya@tcha.org>
parents: 33843
diff changeset
    21
    match as matchmod,
25924
cfc24c22454e copies: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25289
diff changeset
    22
    pathutil,
45977
a66568f20ddc copies: use the rust code for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45957
diff changeset
    23
    policy,
43106
d783f945a701 py3: finish porting iteritems() to pycompat and remove source transformer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43077
diff changeset
    24
    pycompat,
25924
cfc24c22454e copies: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25289
diff changeset
    25
    util,
cfc24c22454e copies: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25289
diff changeset
    26
)
43148
843da18386d5 sidedatacopies: deal with upgrading and downgrading to that format
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43147
diff changeset
    27
843da18386d5 sidedatacopies: deal with upgrading and downgrading to that format
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43147
diff changeset
    28
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43022
diff changeset
    29
from .utils import stringutil
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43022
diff changeset
    30
46061
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46040
diff changeset
    31
from .revlogutils import (
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46040
diff changeset
    32
    flagutil,
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46040
diff changeset
    33
    sidedata as sidedatamod,
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46040
diff changeset
    34
)
45672
f877b3628015 copies: return None instead of ChangingFiles when relevant
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45670
diff changeset
    35
45977
a66568f20ddc copies: use the rust code for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45957
diff changeset
    36
rustmod = policy.importrust("copy_tracing")
a66568f20ddc copies: use the rust code for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45957
diff changeset
    37
25924
cfc24c22454e copies: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25289
diff changeset
    38
42593
11ceb1b8fd74 copies: inline _chainandfilter() to prepare for next patch
Martin von Zweigbergk <martinvonz@google.com>
parents: 42592
diff changeset
    39
def _filter(src, dst, t):
11ceb1b8fd74 copies: inline _chainandfilter() to prepare for next patch
Martin von Zweigbergk <martinvonz@google.com>
parents: 42592
diff changeset
    40
    """filters out invalid copies after chaining"""
42257
d1c2688eda80 copies: document cases in _chain()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42256
diff changeset
    41
42593
11ceb1b8fd74 copies: inline _chainandfilter() to prepare for next patch
Martin von Zweigbergk <martinvonz@google.com>
parents: 42592
diff changeset
    42
    # When _chain()'ing copies in 'a' (from 'src' via some other commit 'mid')
11ceb1b8fd74 copies: inline _chainandfilter() to prepare for next patch
Martin von Zweigbergk <martinvonz@google.com>
parents: 42592
diff changeset
    43
    # with copies in 'b' (from 'mid' to 'dst'), we can get the different cases
46302
599d247af600 copies: fix some comment in _filter
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46184
diff changeset
    44
    # in the following table (not including trivial cases). For example, case 6
42593
11ceb1b8fd74 copies: inline _chainandfilter() to prepare for next patch
Martin von Zweigbergk <martinvonz@google.com>
parents: 42592
diff changeset
    45
    # is where a file existed in 'src' and remained under that name in 'mid' and
42257
d1c2688eda80 copies: document cases in _chain()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42256
diff changeset
    46
    # then was renamed between 'mid' and 'dst'.
d1c2688eda80 copies: document cases in _chain()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42256
diff changeset
    47
    #
d1c2688eda80 copies: document cases in _chain()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42256
diff changeset
    48
    # case src mid dst result
d1c2688eda80 copies: document cases in _chain()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42256
diff changeset
    49
    #   1   x   y   -    -
d1c2688eda80 copies: document cases in _chain()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42256
diff changeset
    50
    #   2   x   y   y   x->y
d1c2688eda80 copies: document cases in _chain()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42256
diff changeset
    51
    #   3   x   y   x    -
d1c2688eda80 copies: document cases in _chain()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42256
diff changeset
    52
    #   4   x   y   z   x->z
d1c2688eda80 copies: document cases in _chain()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42256
diff changeset
    53
    #   5   -   x   y    -
d1c2688eda80 copies: document cases in _chain()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42256
diff changeset
    54
    #   6   x   x   y   x->y
42395
f3d06d37e194 copies: split up _chain() in naive chaining and filtering steps
Martin von Zweigbergk <martinvonz@google.com>
parents: 42366
diff changeset
    55
    #
f3d06d37e194 copies: split up _chain() in naive chaining and filtering steps
Martin von Zweigbergk <martinvonz@google.com>
parents: 42366
diff changeset
    56
    # _chain() takes care of chaining the copies in 'a' and 'b', but it
f3d06d37e194 copies: split up _chain() in naive chaining and filtering steps
Martin von Zweigbergk <martinvonz@google.com>
parents: 42366
diff changeset
    57
    # cannot tell the difference between cases 1 and 2, between 3 and 4, or
f3d06d37e194 copies: split up _chain() in naive chaining and filtering steps
Martin von Zweigbergk <martinvonz@google.com>
parents: 42366
diff changeset
    58
    # between 5 and 6, so it includes all cases in its result.
f3d06d37e194 copies: split up _chain() in naive chaining and filtering steps
Martin von Zweigbergk <martinvonz@google.com>
parents: 42366
diff changeset
    59
    # Cases 1, 3, and 5 are then removed by _filter().
42257
d1c2688eda80 copies: document cases in _chain()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42256
diff changeset
    60
42395
f3d06d37e194 copies: split up _chain() in naive chaining and filtering steps
Martin von Zweigbergk <martinvonz@google.com>
parents: 42366
diff changeset
    61
    for k, v in list(t.items()):
46471
1d6d1a15a963 copies: simplify the conditional for _filter's case 3
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46470
diff changeset
    62
        if k == v:  # case 3
42395
f3d06d37e194 copies: split up _chain() in naive chaining and filtering steps
Martin von Zweigbergk <martinvonz@google.com>
parents: 42366
diff changeset
    63
            del t[k]
46471
1d6d1a15a963 copies: simplify the conditional for _filter's case 3
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46470
diff changeset
    64
        elif v not in src:  # case 5
1d6d1a15a963 copies: simplify the conditional for _filter's case 3
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46470
diff changeset
    65
            # remove copies from files that didn't exist
42395
f3d06d37e194 copies: split up _chain() in naive chaining and filtering steps
Martin von Zweigbergk <martinvonz@google.com>
parents: 42366
diff changeset
    66
            del t[k]
46470
154ded9104f1 copies: clarify which case some conditional are handling
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46469
diff changeset
    67
        elif k not in dst:  # case 1
46471
1d6d1a15a963 copies: simplify the conditional for _filter's case 3
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46470
diff changeset
    68
            # remove copies to files that were then removed
42395
f3d06d37e194 copies: split up _chain() in naive chaining and filtering steps
Martin von Zweigbergk <martinvonz@google.com>
parents: 42366
diff changeset
    69
            del t[k]
f3d06d37e194 copies: split up _chain() in naive chaining and filtering steps
Martin von Zweigbergk <martinvonz@google.com>
parents: 42366
diff changeset
    70
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43022
diff changeset
    71
43804
995066c41bb2 copies: expand `_chain` variable name to make the function easier to read
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43803
diff changeset
    72
def _chain(prefix, suffix):
995066c41bb2 copies: expand `_chain` variable name to make the function easier to read
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43803
diff changeset
    73
    """chain two sets of copies 'prefix' and 'suffix'"""
995066c41bb2 copies: expand `_chain` variable name to make the function easier to read
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43803
diff changeset
    74
    result = prefix.copy()
995066c41bb2 copies: expand `_chain` variable name to make the function easier to read
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43803
diff changeset
    75
    for key, value in pycompat.iteritems(suffix):
995066c41bb2 copies: expand `_chain` variable name to make the function easier to read
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43803
diff changeset
    76
        result[key] = prefix.get(value, value)
995066c41bb2 copies: expand `_chain` variable name to make the function easier to read
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43803
diff changeset
    77
    return result
15775
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
    78
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43022
diff changeset
    79
43199
069cbbb53cdf copies: drop the findlimit logic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43198
diff changeset
    80
def _tracefile(fctx, am, basemf):
35428
9cf37d111acb copies: consistently use """ for docstrings
Martin von Zweigbergk <martinvonz@google.com>
parents: 35427
diff changeset
    81
    """return file context that is the ancestor of fctx present in ancestor
43198
c16fe77e340a pathcopies: give up any optimization based on `introrev`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43148
diff changeset
    82
    manifest am
c16fe77e340a pathcopies: give up any optimization based on `introrev`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43148
diff changeset
    83
c16fe77e340a pathcopies: give up any optimization based on `introrev`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43148
diff changeset
    84
    Note: we used to try and stop after a given limit, however checking if that
c16fe77e340a pathcopies: give up any optimization based on `introrev`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43148
diff changeset
    85
    limit is reached turned out to be very expensive. we are better off
c16fe77e340a pathcopies: give up any optimization based on `introrev`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43148
diff changeset
    86
    disabling that feature."""
15775
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
    87
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
    88
    for f in fctx.ancestors():
42554
4ebbd7c4a3c5 copies: return only path from _tracefile() since that's all caller needs
Martin von Zweigbergk <martinvonz@google.com>
parents: 42527
diff changeset
    89
        path = f.path()
4ebbd7c4a3c5 copies: return only path from _tracefile() since that's all caller needs
Martin von Zweigbergk <martinvonz@google.com>
parents: 42527
diff changeset
    90
        if am.get(path, None) == f.filenode():
4ebbd7c4a3c5 copies: return only path from _tracefile() since that's all caller needs
Martin von Zweigbergk <martinvonz@google.com>
parents: 42527
diff changeset
    91
            return path
42595
819712deac69 copies: follow copies across merge base without source file (issue6163)
Martin von Zweigbergk <martinvonz@google.com>
parents: 42594
diff changeset
    92
        if basemf and basemf.get(path, None) == f.filenode():
819712deac69 copies: follow copies across merge base without source file (issue6163)
Martin von Zweigbergk <martinvonz@google.com>
parents: 42594
diff changeset
    93
            return path
15775
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
    94
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43022
diff changeset
    95
41761
012f695546aa copies: respect narrowmatcher in "parent -> working dir" case
Martin von Zweigbergk <martinvonz@google.com>
parents: 41735
diff changeset
    96
def _dirstatecopies(repo, match=None):
012f695546aa copies: respect narrowmatcher in "parent -> working dir" case
Martin von Zweigbergk <martinvonz@google.com>
parents: 41735
diff changeset
    97
    ds = repo.dirstate
15775
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
    98
    c = ds.copies().copy()
34355
1a5abc45e2fa py3: explicitly convert dict.keys() and dict.items() into a list
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34318
diff changeset
    99
    for k in list(c):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   100
        if ds[k] not in b'anm' or (match and not match(k)):
15775
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
   101
            del c[k]
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
   102
    return c
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
   103
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43022
diff changeset
   104
24782
4906dc0e038c copies: add matcher parameter to copy logic
Durham Goode <durham@fb.com>
parents: 24625
diff changeset
   105
def _computeforwardmissing(a, b, match=None):
24011
d7d08337b3f6 copy: move _forwardcopies file logic to a function
Durham Goode <durham@fb.com>
parents: 24010
diff changeset
   106
    """Computes which files are in b but not a.
d7d08337b3f6 copy: move _forwardcopies file logic to a function
Durham Goode <durham@fb.com>
parents: 24010
diff changeset
   107
    This is its own function so extensions can easily wrap this call to see what
d7d08337b3f6 copy: move _forwardcopies file logic to a function
Durham Goode <durham@fb.com>
parents: 24010
diff changeset
   108
    files _forwardcopies is about to process.
d7d08337b3f6 copy: move _forwardcopies file logic to a function
Durham Goode <durham@fb.com>
parents: 24010
diff changeset
   109
    """
24782
4906dc0e038c copies: add matcher parameter to copy logic
Durham Goode <durham@fb.com>
parents: 24625
diff changeset
   110
    ma = a.manifest()
4906dc0e038c copies: add matcher parameter to copy logic
Durham Goode <durham@fb.com>
parents: 24625
diff changeset
   111
    mb = b.manifest()
31266
5a909a8098a1 copies: remove use of manifest.matches
Durham Goode <durham@fb.com>
parents: 30586
diff changeset
   112
    return mb.filesnotin(ma, match=match)
24011
d7d08337b3f6 copy: move _forwardcopies file logic to a function
Durham Goode <durham@fb.com>
parents: 24010
diff changeset
   113
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43022
diff changeset
   114
42115
27475ae67676 copies: extract function for deciding whether to use changeset-centric algos
Martin von Zweigbergk <martinvonz@google.com>
parents: 41941
diff changeset
   115
def usechangesetcentricalgo(repo):
27475ae67676 copies: extract function for deciding whether to use changeset-centric algos
Martin von Zweigbergk <martinvonz@google.com>
parents: 41941
diff changeset
   116
    """Checks if we should use changeset-centric copy algorithms"""
43146
0171483b082f sidedatacopies: read rename information from sidedata
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43117
diff changeset
   117
    if repo.filecopiesmode == b'changeset-sidedata':
0171483b082f sidedatacopies: read rename information from sidedata
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43117
diff changeset
   118
        return True
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   119
    readfrom = repo.ui.config(b'experimental', b'copies.read-from')
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   120
    changesetsource = (b'changeset-only', b'compatibility')
43022
f3bcae1e9e23 copies: expand the logic of usechangesetcentricalgo
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 42729
diff changeset
   121
    return readfrom in changesetsource
42115
27475ae67676 copies: extract function for deciding whether to use changeset-centric algos
Martin von Zweigbergk <martinvonz@google.com>
parents: 41941
diff changeset
   122
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43022
diff changeset
   123
42595
819712deac69 copies: follow copies across merge base without source file (issue6163)
Martin von Zweigbergk <martinvonz@google.com>
parents: 42594
diff changeset
   124
def _committedforwardcopies(a, b, base, match):
35429
8801cdcea01f copies: extract method for getting non-wdir forward copies
Martin von Zweigbergk <martinvonz@google.com>
parents: 35428
diff changeset
   125
    """Like _forwardcopies(), but b.rev() cannot be None (working copy)"""
20294
243ea5ffdf31 diff: search beyond ancestor when detecting renames
Mads Kiilerich <madski@unity3d.com>
parents: 19178
diff changeset
   126
    # files might have to be traced back to the fctx parent of the last
243ea5ffdf31 diff: search beyond ancestor when detecting renames
Mads Kiilerich <madski@unity3d.com>
parents: 19178
diff changeset
   127
    # one-side-only changeset, but not further back than that
40058
25b2868206e2 copies: add a devel debug mode to trace what copy tracing does
Boris Feld <boris.feld@octobus.net>
parents: 39967
diff changeset
   128
    repo = a._repo
41765
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41763
diff changeset
   129
42115
27475ae67676 copies: extract function for deciding whether to use changeset-centric algos
Martin von Zweigbergk <martinvonz@google.com>
parents: 41941
diff changeset
   130
    if usechangesetcentricalgo(repo):
41765
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41763
diff changeset
   131
        return _changesetforwardcopies(a, b, match)
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41763
diff changeset
   132
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   133
    debug = repo.ui.debugflag and repo.ui.configbool(b'devel', b'debug.copies')
40058
25b2868206e2 copies: add a devel debug mode to trace what copy tracing does
Boris Feld <boris.feld@octobus.net>
parents: 39967
diff changeset
   134
    dbg = repo.ui.debug
25b2868206e2 copies: add a devel debug mode to trace what copy tracing does
Boris Feld <boris.feld@octobus.net>
parents: 39967
diff changeset
   135
    if debug:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   136
        dbg(b'debug.copies:    looking into rename from %s to %s\n' % (a, b))
20294
243ea5ffdf31 diff: search beyond ancestor when detecting renames
Mads Kiilerich <madski@unity3d.com>
parents: 19178
diff changeset
   137
    am = a.manifest()
42595
819712deac69 copies: follow copies across merge base without source file (issue6163)
Martin von Zweigbergk <martinvonz@google.com>
parents: 42594
diff changeset
   138
    basemf = None if base is None else base.manifest()
20294
243ea5ffdf31 diff: search beyond ancestor when detecting renames
Mads Kiilerich <madski@unity3d.com>
parents: 19178
diff changeset
   139
15775
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
   140
    # find where new files came from
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
   141
    # we currently don't try to find where old files went, too expensive
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
   142
    # this means we can miss a case like 'hg rm b; hg cp a b'
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
   143
    cm = {}
28000
d4247c306d82 copies: optimize forward copy detection logic for rebases
Durham Goode <durham@fb.com>
parents: 27876
diff changeset
   144
d4247c306d82 copies: optimize forward copy detection logic for rebases
Durham Goode <durham@fb.com>
parents: 27876
diff changeset
   145
    # Computing the forward missing is quite expensive on large manifests, since
d4247c306d82 copies: optimize forward copy detection logic for rebases
Durham Goode <durham@fb.com>
parents: 27876
diff changeset
   146
    # it compares the entire manifests. We can optimize it in the common use
d4247c306d82 copies: optimize forward copy detection logic for rebases
Durham Goode <durham@fb.com>
parents: 27876
diff changeset
   147
    # case of computing what copies are in a commit versus its parent (like
d4247c306d82 copies: optimize forward copy detection logic for rebases
Durham Goode <durham@fb.com>
parents: 27876
diff changeset
   148
    # during a rebase or histedit). Note, we exclude merge commits from this
d4247c306d82 copies: optimize forward copy detection logic for rebases
Durham Goode <durham@fb.com>
parents: 27876
diff changeset
   149
    # optimization, since the ctx.files() for a merge commit is not correct for
d4247c306d82 copies: optimize forward copy detection logic for rebases
Durham Goode <durham@fb.com>
parents: 27876
diff changeset
   150
    # this comparison.
d4247c306d82 copies: optimize forward copy detection logic for rebases
Durham Goode <durham@fb.com>
parents: 27876
diff changeset
   151
    forwardmissingmatch = match
46114
59fa3890d40a node: import symbols explicitly
Joerg Sonnenberger <joerg@bec.de>
parents: 46110
diff changeset
   152
    if b.p1() == a and b.p2().node() == nullid:
41941
a791623458ef copies: remove dependency on scmutil by directly using match.exact()
Martin von Zweigbergk <martinvonz@google.com>
parents: 41937
diff changeset
   153
        filesmatcher = matchmod.exact(b.files())
33886
252fb66ee5bb copies: use intersectmatchers() in non-merge p1 optimization
Yuya Nishihara <yuya@tcha.org>
parents: 33843
diff changeset
   154
        forwardmissingmatch = matchmod.intersectmatchers(match, filesmatcher)
46480
e948ad0dcbe2 copies: add an devel option to trace all files
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46471
diff changeset
   155
    if repo.ui.configbool(b'devel', b'copy-tracing.trace-all-files'):
e948ad0dcbe2 copies: add an devel option to trace all files
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46471
diff changeset
   156
        missing = list(b.walk(match))
e948ad0dcbe2 copies: add an devel option to trace all files
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46471
diff changeset
   157
        # _computeforwardmissing(a, b, match=forwardmissingmatch)
e948ad0dcbe2 copies: add an devel option to trace all files
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46471
diff changeset
   158
        if debug:
e948ad0dcbe2 copies: add an devel option to trace all files
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46471
diff changeset
   159
            dbg(b'debug.copies:      searching all files: %d\n' % len(missing))
e948ad0dcbe2 copies: add an devel option to trace all files
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46471
diff changeset
   160
    else:
e948ad0dcbe2 copies: add an devel option to trace all files
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46471
diff changeset
   161
        missing = _computeforwardmissing(a, b, match=forwardmissingmatch)
e948ad0dcbe2 copies: add an devel option to trace all files
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46471
diff changeset
   162
        if debug:
e948ad0dcbe2 copies: add an devel option to trace all files
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46471
diff changeset
   163
            dbg(
e948ad0dcbe2 copies: add an devel option to trace all files
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46471
diff changeset
   164
                b'debug.copies:      missing files to search: %d\n'
e948ad0dcbe2 copies: add an devel option to trace all files
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46471
diff changeset
   165
                % len(missing)
e948ad0dcbe2 copies: add an devel option to trace all files
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46471
diff changeset
   166
            )
28000
d4247c306d82 copies: optimize forward copy detection logic for rebases
Durham Goode <durham@fb.com>
parents: 27876
diff changeset
   167
23980
c1ce5442453f _adjustlinkrev: reuse ancestors set during rename detection (issue4514)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23139
diff changeset
   168
    ancestrycontext = a._repo.changelog.ancestors([b.rev()], inclusive=True)
40058
25b2868206e2 copies: add a devel debug mode to trace what copy tracing does
Boris Feld <boris.feld@octobus.net>
parents: 39967
diff changeset
   169
42243
390ec72b8ea4 copies: process files in deterministic order for stable tests
Martin von Zweigbergk <martinvonz@google.com>
parents: 42211
diff changeset
   170
    for f in sorted(missing):
40058
25b2868206e2 copies: add a devel debug mode to trace what copy tracing does
Boris Feld <boris.feld@octobus.net>
parents: 39967
diff changeset
   171
        if debug:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   172
            dbg(b'debug.copies:        tracing file: %s\n' % f)
23980
c1ce5442453f _adjustlinkrev: reuse ancestors set during rename detection (issue4514)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23139
diff changeset
   173
        fctx = b[f]
c1ce5442453f _adjustlinkrev: reuse ancestors set during rename detection (issue4514)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23139
diff changeset
   174
        fctx._ancestrycontext = ancestrycontext
40058
25b2868206e2 copies: add a devel debug mode to trace what copy tracing does
Boris Feld <boris.feld@octobus.net>
parents: 39967
diff changeset
   175
40059
cf01616f8d96 copies: add time information to the debug information
Boris Feld <boris.feld@octobus.net>
parents: 40058
diff changeset
   176
        if debug:
cf01616f8d96 copies: add time information to the debug information
Boris Feld <boris.feld@octobus.net>
parents: 40058
diff changeset
   177
            start = util.timer()
43199
069cbbb53cdf copies: drop the findlimit logic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43198
diff changeset
   178
        opath = _tracefile(fctx, am, basemf)
42554
4ebbd7c4a3c5 copies: return only path from _tracefile() since that's all caller needs
Martin von Zweigbergk <martinvonz@google.com>
parents: 42527
diff changeset
   179
        if opath:
40058
25b2868206e2 copies: add a devel debug mode to trace what copy tracing does
Boris Feld <boris.feld@octobus.net>
parents: 39967
diff changeset
   180
            if debug:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   181
                dbg(b'debug.copies:          rename of: %s\n' % opath)
42554
4ebbd7c4a3c5 copies: return only path from _tracefile() since that's all caller needs
Martin von Zweigbergk <martinvonz@google.com>
parents: 42527
diff changeset
   182
            cm[f] = opath
40059
cf01616f8d96 copies: add time information to the debug information
Boris Feld <boris.feld@octobus.net>
parents: 40058
diff changeset
   183
        if debug:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43022
diff changeset
   184
            dbg(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   185
                b'debug.copies:          time: %f seconds\n'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43022
diff changeset
   186
                % (util.timer() - start)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43022
diff changeset
   187
            )
35429
8801cdcea01f copies: extract method for getting non-wdir forward copies
Martin von Zweigbergk <martinvonz@google.com>
parents: 35428
diff changeset
   188
    return cm
8801cdcea01f copies: extract method for getting non-wdir forward copies
Martin von Zweigbergk <martinvonz@google.com>
parents: 35428
diff changeset
   189
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43022
diff changeset
   190
46061
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46040
diff changeset
   191
def _revinfo_getter(repo, match):
45642
2693659c2b34 copies: directly pass a changes object to the copy tracing code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45641
diff changeset
   192
    """returns a function that returns the following data given a <rev>"
43255
b8d60845fa5d copies: extract data extraction into a `revinfo` function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43254
diff changeset
   193
b8d60845fa5d copies: extract data extraction into a `revinfo` function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43254
diff changeset
   194
    * p1: revision number of first parent
b8d60845fa5d copies: extract data extraction into a `revinfo` function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43254
diff changeset
   195
    * p2: revision number of first parent
45642
2693659c2b34 copies: directly pass a changes object to the copy tracing code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45641
diff changeset
   196
    * changes: a ChangingFiles object
43255
b8d60845fa5d copies: extract data extraction into a `revinfo` function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43254
diff changeset
   197
    """
b8d60845fa5d copies: extract data extraction into a `revinfo` function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43254
diff changeset
   198
    cl = repo.changelog
b8d60845fa5d copies: extract data extraction into a `revinfo` function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43254
diff changeset
   199
    parents = cl.parentrevs
45672
f877b3628015 copies: return None instead of ChangingFiles when relevant
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45670
diff changeset
   200
    flags = cl.flags
f877b3628015 copies: return None instead of ChangingFiles when relevant
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45670
diff changeset
   201
f877b3628015 copies: return None instead of ChangingFiles when relevant
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45670
diff changeset
   202
    HASCOPIESINFO = flagutil.REVIDX_HASCOPIESINFO
43255
b8d60845fa5d copies: extract data extraction into a `revinfo` function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43254
diff changeset
   203
45640
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45639
diff changeset
   204
    changelogrevision = cl.changelogrevision
43257
675c776fbcd1 sidedatacopies: directly fetch copies information from sidedata
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43256
diff changeset
   205
46159
929054848d6c copies: properly match result during changeset centric copy tracing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46158
diff changeset
   206
    if rustmod is not None:
46061
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46040
diff changeset
   207
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46040
diff changeset
   208
        def revinfo(rev):
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46040
diff changeset
   209
            p1, p2 = parents(rev)
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46040
diff changeset
   210
            if flags(rev) & HASCOPIESINFO:
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46040
diff changeset
   211
                raw = changelogrevision(rev)._sidedata.get(sidedatamod.SD_FILES)
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46040
diff changeset
   212
            else:
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46040
diff changeset
   213
                raw = None
46150
a132aa5979ec copies: no longer cache the ChangedFiles during copy tracing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   214
            return (p1, p2, raw)
46061
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46040
diff changeset
   215
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46040
diff changeset
   216
    else:
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46040
diff changeset
   217
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46040
diff changeset
   218
        def revinfo(rev):
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46040
diff changeset
   219
            p1, p2 = parents(rev)
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46040
diff changeset
   220
            if flags(rev) & HASCOPIESINFO:
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46040
diff changeset
   221
                changes = changelogrevision(rev).changes
46150
a132aa5979ec copies: no longer cache the ChangedFiles during copy tracing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   222
            else:
a132aa5979ec copies: no longer cache the ChangedFiles during copy tracing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   223
                changes = None
a132aa5979ec copies: no longer cache the ChangedFiles during copy tracing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   224
            return (p1, p2, changes)
43255
b8d60845fa5d copies: extract data extraction into a `revinfo` function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43254
diff changeset
   225
b8d60845fa5d copies: extract data extraction into a `revinfo` function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43254
diff changeset
   226
    return revinfo
b8d60845fa5d copies: extract data extraction into a `revinfo` function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43254
diff changeset
   227
b8d60845fa5d copies: extract data extraction into a `revinfo` function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43254
diff changeset
   228
45907
06b64fabf91c copies: cache the ancestor checking call when tracing copy
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45821
diff changeset
   229
def cached_is_ancestor(is_ancestor):
06b64fabf91c copies: cache the ancestor checking call when tracing copy
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45821
diff changeset
   230
    """return a cached version of is_ancestor"""
06b64fabf91c copies: cache the ancestor checking call when tracing copy
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45821
diff changeset
   231
    cache = {}
06b64fabf91c copies: cache the ancestor checking call when tracing copy
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45821
diff changeset
   232
06b64fabf91c copies: cache the ancestor checking call when tracing copy
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45821
diff changeset
   233
    def _is_ancestor(anc, desc):
06b64fabf91c copies: cache the ancestor checking call when tracing copy
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45821
diff changeset
   234
        if anc > desc:
06b64fabf91c copies: cache the ancestor checking call when tracing copy
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45821
diff changeset
   235
            return False
06b64fabf91c copies: cache the ancestor checking call when tracing copy
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45821
diff changeset
   236
        elif anc == desc:
06b64fabf91c copies: cache the ancestor checking call when tracing copy
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45821
diff changeset
   237
            return True
06b64fabf91c copies: cache the ancestor checking call when tracing copy
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45821
diff changeset
   238
        key = (anc, desc)
06b64fabf91c copies: cache the ancestor checking call when tracing copy
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45821
diff changeset
   239
        ret = cache.get(key)
06b64fabf91c copies: cache the ancestor checking call when tracing copy
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45821
diff changeset
   240
        if ret is None:
06b64fabf91c copies: cache the ancestor checking call when tracing copy
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45821
diff changeset
   241
            ret = cache[key] = is_ancestor(anc, desc)
06b64fabf91c copies: cache the ancestor checking call when tracing copy
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45821
diff changeset
   242
        return ret
06b64fabf91c copies: cache the ancestor checking call when tracing copy
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45821
diff changeset
   243
06b64fabf91c copies: cache the ancestor checking call when tracing copy
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45821
diff changeset
   244
    return _is_ancestor
06b64fabf91c copies: cache the ancestor checking call when tracing copy
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45821
diff changeset
   245
06b64fabf91c copies: cache the ancestor checking call when tracing copy
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45821
diff changeset
   246
41765
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41763
diff changeset
   247
def _changesetforwardcopies(a, b, match):
46114
59fa3890d40a node: import symbols explicitly
Joerg Sonnenberger <joerg@bec.de>
parents: 46110
diff changeset
   248
    if a.rev() in (nullrev, b.rev()):
41765
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41763
diff changeset
   249
        return {}
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41763
diff changeset
   250
43256
00de32aa834e copies: use an unfiltered repository for the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43255
diff changeset
   251
    repo = a.repo().unfiltered()
41765
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41763
diff changeset
   252
    children = {}
43255
b8d60845fa5d copies: extract data extraction into a `revinfo` function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43254
diff changeset
   253
41765
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41763
diff changeset
   254
    cl = repo.changelog
45987
8b99c473aae2 copies-rust: move is_ancestor caching within the rust code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45977
diff changeset
   255
    isancestor = cl.isancestorrev
46149
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   256
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   257
    # To track rename from "A" to B, we need to gather all parent → children
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   258
    # edges that are contains in `::B` but not in `::A`.
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   259
    #
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   260
    #
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   261
    # To do so, we need to gather all revisions exclusive¹ to "B" (ie¹: `::b -
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   262
    # ::a`) and also all the "roots point", ie the parents of the exclusive set
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   263
    # that belong to ::a. These are exactly all the revisions needed to express
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   264
    # the parent → children we need to combine.
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   265
    #
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   266
    # [1] actually, we need to gather all the edges within `(::a)::b`, ie:
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   267
    # excluding paths that leads to roots that are not ancestors of `a`. We
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   268
    # keep this out of the explanation because it is hard enough without this special case..
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   269
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   270
    parents = cl._uncheckedparentrevs
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   271
    graph_roots = (nullrev, nullrev)
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   272
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   273
    ancestors = cl.ancestors([a.rev()], inclusive=True)
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   274
    revs = cl.findmissingrevs(common=[a.rev()], heads=[b.rev()])
43299
83bb1e89ab9b copies: compute the exact set of revision to walk
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43297
diff changeset
   275
    roots = set()
46149
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   276
    has_graph_roots = False
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   277
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   278
    # iterate over `only(B, A)`
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   279
    for r in revs:
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   280
        ps = parents(r)
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   281
        if ps == graph_roots:
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   282
            has_graph_roots = True
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   283
        else:
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   284
            p1, p2 = ps
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   285
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   286
            # find all the "root points" (see larger comment above)
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   287
            if p1 != nullrev and p1 in ancestors:
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   288
                roots.add(p1)
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   289
            if p2 != nullrev and p2 in ancestors:
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   290
                roots.add(p2)
43299
83bb1e89ab9b copies: compute the exact set of revision to walk
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43297
diff changeset
   291
    if not roots:
83bb1e89ab9b copies: compute the exact set of revision to walk
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43297
diff changeset
   292
        # no common revision to track copies from
83bb1e89ab9b copies: compute the exact set of revision to walk
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43297
diff changeset
   293
        return {}
46149
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   294
    if has_graph_roots:
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   295
        # this deal with the special case mentionned in the [1] footnotes. We
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   296
        # must filter out revisions that leads to non-common graphroots.
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   297
        roots = list(roots)
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   298
        m = min(roots)
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   299
        h = [b.rev()]
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   300
        roots_to_head = cl.reachableroots(m, h, roots, includepath=True)
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   301
        roots_to_head = set(roots_to_head)
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   302
        revs = [r for r in revs if r in roots_to_head]
45639
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   303
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   304
    if repo.filecopiesmode == b'changeset-sidedata':
46149
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   305
        # When using side-data, we will process the edges "from" the children.
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   306
        # We iterate over the childre, gathering previous collected data for
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   307
        # the parents. Do know when the parents data is no longer necessary, we
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   308
        # keep a counter of how many children each revision has.
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   309
        #
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   310
        # An interresting property of `children_count` is that it only contains
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   311
        # revision that will be relevant for a edge of the graph. So if a
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   312
        # children has parent not in `children_count`, that edges should not be
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   313
        # processed.
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   314
        children_count = dict((r, 0) for r in roots)
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   315
        for r in revs:
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   316
            for p in cl.parentrevs(r):
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   317
                if p == nullrev:
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   318
                    continue
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   319
                children_count[r] = 0
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   320
                if p in children_count:
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   321
                    children_count[p] += 1
46061
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46040
diff changeset
   322
        revinfo = _revinfo_getter(repo, match)
45639
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   323
        return _combine_changeset_copies(
46149
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   324
            revs, children_count, b.rev(), revinfo, match, isancestor
45639
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   325
        )
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   326
    else:
46149
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   327
        # When not using side-data, we will process the edges "from" the parent.
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   328
        # so we need a full mapping of the parent -> children relation.
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   329
        children = dict((r, []) for r in roots)
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   330
        for r in revs:
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   331
            for p in cl.parentrevs(r):
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   332
                if p == nullrev:
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   333
                    continue
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   334
                children[r] = []
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   335
                if p in children:
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   336
                    children[p].append(r)
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   337
        x = revs.pop()
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   338
        assert x == b.rev()
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   339
        revs.extend(roots)
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   340
        revs.sort()
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   341
45640
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45639
diff changeset
   342
        revinfo = _revinfo_getter_extra(repo)
45639
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   343
        return _combine_changeset_copies_extra(
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   344
            revs, children, b.rev(), revinfo, match, isancestor
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   345
        )
43806
421ea5772039 copies: split the combination of the copies mapping in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43805
diff changeset
   346
421ea5772039 copies: split the combination of the copies mapping in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43805
diff changeset
   347
45627
fb000408bca5 copies: rename some function to the new naming scheme
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45014
diff changeset
   348
def _combine_changeset_copies(
46149
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   349
    revs, children_count, targetrev, revinfo, match, isancestor
44858
45f3f35cefe7 copies: fix the changeset based algorithm regarding merge
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44323
diff changeset
   350
):
43806
421ea5772039 copies: split the combination of the copies mapping in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43805
diff changeset
   351
    """combine the copies information for each item of iterrevs
421ea5772039 copies: split the combination of the copies mapping in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43805
diff changeset
   352
421ea5772039 copies: split the combination of the copies mapping in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43805
diff changeset
   353
    revs: sorted iterable of revision to visit
46149
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   354
    children_count: a {parent: <number-of-relevant-children>} mapping.
43806
421ea5772039 copies: split the combination of the copies mapping in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43805
diff changeset
   355
    targetrev: the final copies destination revision (not in iterrevs)
421ea5772039 copies: split the combination of the copies mapping in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43805
diff changeset
   356
    revinfo(rev): a function that return (p1, p2, p1copies, p2copies, removed)
421ea5772039 copies: split the combination of the copies mapping in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43805
diff changeset
   357
    match: a matcher
421ea5772039 copies: split the combination of the copies mapping in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43805
diff changeset
   358
421ea5772039 copies: split the combination of the copies mapping in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43805
diff changeset
   359
    It returns the aggregated copies information for `targetrev`.
421ea5772039 copies: split the combination of the copies mapping in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43805
diff changeset
   360
    """
45977
a66568f20ddc copies: use the rust code for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45957
diff changeset
   361
a66568f20ddc copies: use the rust code for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45957
diff changeset
   362
    alwaysmatch = match.always()
a66568f20ddc copies: use the rust code for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45957
diff changeset
   363
46159
929054848d6c copies: properly match result during changeset centric copy tracing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46158
diff changeset
   364
    if rustmod is not None:
46158
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   365
        final_copies = rustmod.combine_changeset_copies(
46149
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   366
            list(revs), children_count, targetrev, revinfo, isancestor
45977
a66568f20ddc copies: use the rust code for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45957
diff changeset
   367
        )
46158
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   368
    else:
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   369
        isancestor = cached_is_ancestor(isancestor)
46148
70a9eb899637 copies: document the current algorithm step
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46114
diff changeset
   370
46158
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   371
        all_copies = {}
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   372
        # iterate over all the "children" side of copy tracing "edge"
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   373
        for current_rev in revs:
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   374
            p1, p2, changes = revinfo(current_rev)
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   375
            current_copies = None
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   376
            # iterate over all parents to chain the existing data with the
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   377
            # data from the parent → child edge.
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   378
            for parent, parent_rev in ((1, p1), (2, p2)):
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   379
                if parent_rev == nullrev:
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   380
                    continue
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   381
                remaining_children = children_count.get(parent_rev)
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   382
                if remaining_children is None:
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   383
                    continue
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   384
                remaining_children -= 1
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   385
                children_count[parent_rev] = remaining_children
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   386
                if remaining_children:
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   387
                    copies = all_copies.get(parent_rev, None)
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   388
                else:
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   389
                    copies = all_copies.pop(parent_rev, None)
46148
70a9eb899637 copies: document the current algorithm step
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46114
diff changeset
   390
46158
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   391
                if copies is None:
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   392
                    # this is a root
46184
cb8b2ee89a5d copies: stop attempt to avoid extra dict copies around branching
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46183
diff changeset
   393
                    newcopies = copies = {}
cb8b2ee89a5d copies: stop attempt to avoid extra dict copies around branching
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46183
diff changeset
   394
                elif remaining_children:
cb8b2ee89a5d copies: stop attempt to avoid extra dict copies around branching
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46183
diff changeset
   395
                    newcopies = copies.copy()
cb8b2ee89a5d copies: stop attempt to avoid extra dict copies around branching
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46183
diff changeset
   396
                else:
cb8b2ee89a5d copies: stop attempt to avoid extra dict copies around branching
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46183
diff changeset
   397
                    newcopies = copies
46158
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   398
                # chain the data in the edge with the existing data
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   399
                if changes is not None:
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   400
                    childcopies = {}
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   401
                    if parent == 1:
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   402
                        childcopies = changes.copied_from_p1
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   403
                    elif parent == 2:
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   404
                        childcopies = changes.copied_from_p2
46148
70a9eb899637 copies: document the current algorithm step
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46114
diff changeset
   405
46158
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   406
                    if childcopies:
46149
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   407
                        newcopies = copies.copy()
46158
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   408
                        for dest, source in pycompat.iteritems(childcopies):
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   409
                            prev = copies.get(source)
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   410
                            if prev is not None and prev[1] is not None:
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   411
                                source = prev[1]
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   412
                            newcopies[dest] = (current_rev, source)
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   413
                        assert newcopies is not copies
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   414
                    if changes.removed:
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   415
                        for f in changes.removed:
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   416
                            if f in newcopies:
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   417
                                if newcopies is copies:
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   418
                                    # copy on write to avoid affecting potential other
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   419
                                    # branches.  when there are no other branches, this
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   420
                                    # could be avoided.
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   421
                                    newcopies = copies.copy()
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   422
                                newcopies[f] = (current_rev, None)
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   423
                # check potential need to combine the data from another parent (for
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   424
                # that child). See comment below for details.
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   425
                if current_copies is None:
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   426
                    current_copies = newcopies
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   427
                else:
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   428
                    # we are the second parent to work on c, we need to merge our
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   429
                    # work with the other.
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   430
                    #
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   431
                    # In case of conflict, parent 1 take precedence over parent 2.
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   432
                    # This is an arbitrary choice made anew when implementing
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   433
                    # changeset based copies. It was made without regards with
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   434
                    # potential filelog related behavior.
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   435
                    assert parent == 2
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   436
                    current_copies = _merge_copies_dict(
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   437
                        newcopies, current_copies, isancestor, changes
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   438
                    )
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   439
            all_copies[current_rev] = current_copies
46148
70a9eb899637 copies: document the current algorithm step
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46114
diff changeset
   440
46158
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   441
        # filter out internal details and return a {dest: source mapping}
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   442
        final_copies = {}
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   443
        for dest, (tt, source) in all_copies[targetrev].items():
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   444
            if source is not None:
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   445
                final_copies[dest] = source
46159
929054848d6c copies: properly match result during changeset centric copy tracing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46158
diff changeset
   446
    if not alwaysmatch:
929054848d6c copies: properly match result during changeset centric copy tracing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46158
diff changeset
   447
        for filename in list(final_copies.keys()):
929054848d6c copies: properly match result during changeset centric copy tracing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46158
diff changeset
   448
            if not match(filename):
929054848d6c copies: properly match result during changeset centric copy tracing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46158
diff changeset
   449
                del final_copies[filename]
44858
45f3f35cefe7 copies: fix the changeset based algorithm regarding merge
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44323
diff changeset
   450
    return final_copies
45f3f35cefe7 copies: fix the changeset based algorithm regarding merge
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44323
diff changeset
   451
45f3f35cefe7 copies: fix the changeset based algorithm regarding merge
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44323
diff changeset
   452
46161
3a0c41336961 copies: extract value comparison in the python copy tracing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46159
diff changeset
   453
# constant to decide which side to pick with _merge_copies_dict
3a0c41336961 copies: extract value comparison in the python copy tracing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46159
diff changeset
   454
PICK_MINOR = 0
3a0c41336961 copies: extract value comparison in the python copy tracing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46159
diff changeset
   455
PICK_MAJOR = 1
3a0c41336961 copies: extract value comparison in the python copy tracing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46159
diff changeset
   456
PICK_EITHER = 2
3a0c41336961 copies: extract value comparison in the python copy tracing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46159
diff changeset
   457
3a0c41336961 copies: extract value comparison in the python copy tracing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46159
diff changeset
   458
45642
2693659c2b34 copies: directly pass a changes object to the copy tracing code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45641
diff changeset
   459
def _merge_copies_dict(minor, major, isancestor, changes):
44858
45f3f35cefe7 copies: fix the changeset based algorithm regarding merge
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44323
diff changeset
   460
    """merge two copies-mapping together, minor and major
45f3f35cefe7 copies: fix the changeset based algorithm regarding merge
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44323
diff changeset
   461
45f3f35cefe7 copies: fix the changeset based algorithm regarding merge
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44323
diff changeset
   462
    In case of conflict, value from "major" will be picked.
45f3f35cefe7 copies: fix the changeset based algorithm regarding merge
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44323
diff changeset
   463
45f3f35cefe7 copies: fix the changeset based algorithm regarding merge
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44323
diff changeset
   464
    - `isancestors(low_rev, high_rev)`: callable return True if `low_rev` is an
45f3f35cefe7 copies: fix the changeset based algorithm regarding merge
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44323
diff changeset
   465
                                        ancestors of `high_rev`,
45f3f35cefe7 copies: fix the changeset based algorithm regarding merge
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44323
diff changeset
   466
45f3f35cefe7 copies: fix the changeset based algorithm regarding merge
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44323
diff changeset
   467
    - `ismerged(path)`: callable return True if `path` have been merged in the
45f3f35cefe7 copies: fix the changeset based algorithm regarding merge
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44323
diff changeset
   468
                        current revision,
46001
f9f8d8aa9a92 copies: clarify the return of _merge_copies_dict
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46000
diff changeset
   469
f9f8d8aa9a92 copies: clarify the return of _merge_copies_dict
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46000
diff changeset
   470
    return the resulting dict (in practice, the "minor" object, updated)
44858
45f3f35cefe7 copies: fix the changeset based algorithm regarding merge
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44323
diff changeset
   471
    """
45f3f35cefe7 copies: fix the changeset based algorithm regarding merge
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44323
diff changeset
   472
    for dest, value in major.items():
45f3f35cefe7 copies: fix the changeset based algorithm regarding merge
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44323
diff changeset
   473
        other = minor.get(dest)
45f3f35cefe7 copies: fix the changeset based algorithm regarding merge
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44323
diff changeset
   474
        if other is None:
45f3f35cefe7 copies: fix the changeset based algorithm regarding merge
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44323
diff changeset
   475
            minor[dest] = value
45f3f35cefe7 copies: fix the changeset based algorithm regarding merge
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44323
diff changeset
   476
        else:
46161
3a0c41336961 copies: extract value comparison in the python copy tracing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46159
diff changeset
   477
            pick = _compare_values(changes, isancestor, dest, other, value)
3a0c41336961 copies: extract value comparison in the python copy tracing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46159
diff changeset
   478
            if pick == PICK_MAJOR:
45670
a8fb29b05f92 salvaged: properly deal with salvaged file during copy tracing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45642
diff changeset
   479
                minor[dest] = value
46001
f9f8d8aa9a92 copies: clarify the return of _merge_copies_dict
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46000
diff changeset
   480
    return minor
41765
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41763
diff changeset
   481
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43022
diff changeset
   482
46162
6b9d65298484 copies: rename value/other variable to minor/major for clarity
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46161
diff changeset
   483
def _compare_values(changes, isancestor, dest, minor, major):
46161
3a0c41336961 copies: extract value comparison in the python copy tracing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46159
diff changeset
   484
    """compare two value within a _merge_copies_dict loop iteration"""
46183
ee63c1173c1b copies: deal with the "same revision" special case earlier
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46162
diff changeset
   485
    major_tt, major_value = major
ee63c1173c1b copies: deal with the "same revision" special case earlier
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46162
diff changeset
   486
    minor_tt, minor_value = minor
46161
3a0c41336961 copies: extract value comparison in the python copy tracing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46159
diff changeset
   487
46183
ee63c1173c1b copies: deal with the "same revision" special case earlier
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46162
diff changeset
   488
    # evacuate some simple case first:
ee63c1173c1b copies: deal with the "same revision" special case earlier
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46162
diff changeset
   489
    if major_tt == minor_tt:
ee63c1173c1b copies: deal with the "same revision" special case earlier
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46162
diff changeset
   490
        # if it comes from the same revision it must be the same value
ee63c1173c1b copies: deal with the "same revision" special case earlier
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46162
diff changeset
   491
        assert major_value == minor_value
46161
3a0c41336961 copies: extract value comparison in the python copy tracing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46159
diff changeset
   492
        return PICK_EITHER
46183
ee63c1173c1b copies: deal with the "same revision" special case earlier
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46162
diff changeset
   493
    elif major[1] == minor[1]:
ee63c1173c1b copies: deal with the "same revision" special case earlier
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46162
diff changeset
   494
        return PICK_EITHER
ee63c1173c1b copies: deal with the "same revision" special case earlier
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46162
diff changeset
   495
ee63c1173c1b copies: deal with the "same revision" special case earlier
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46162
diff changeset
   496
    # actual merging needed: content from "major" wins, unless it is older than
ee63c1173c1b copies: deal with the "same revision" special case earlier
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46162
diff changeset
   497
    # the branch point or there is a merge
46162
6b9d65298484 copies: rename value/other variable to minor/major for clarity
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46161
diff changeset
   498
    elif changes is not None and major[1] is None and dest in changes.salvaged:
46161
3a0c41336961 copies: extract value comparison in the python copy tracing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46159
diff changeset
   499
        return PICK_MINOR
46162
6b9d65298484 copies: rename value/other variable to minor/major for clarity
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46161
diff changeset
   500
    elif changes is not None and minor[1] is None and dest in changes.salvaged:
46161
3a0c41336961 copies: extract value comparison in the python copy tracing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46159
diff changeset
   501
        return PICK_MAJOR
3a0c41336961 copies: extract value comparison in the python copy tracing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46159
diff changeset
   502
    elif changes is not None and dest in changes.merged:
3a0c41336961 copies: extract value comparison in the python copy tracing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46159
diff changeset
   503
        return PICK_MAJOR
46162
6b9d65298484 copies: rename value/other variable to minor/major for clarity
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46161
diff changeset
   504
    elif not isancestor(major_tt, minor_tt):
6b9d65298484 copies: rename value/other variable to minor/major for clarity
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46161
diff changeset
   505
        if major[1] is not None:
46161
3a0c41336961 copies: extract value comparison in the python copy tracing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46159
diff changeset
   506
            return PICK_MAJOR
46162
6b9d65298484 copies: rename value/other variable to minor/major for clarity
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46161
diff changeset
   507
        elif isancestor(minor_tt, major_tt):
46161
3a0c41336961 copies: extract value comparison in the python copy tracing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46159
diff changeset
   508
            return PICK_MAJOR
3a0c41336961 copies: extract value comparison in the python copy tracing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46159
diff changeset
   509
    return PICK_MINOR
3a0c41336961 copies: extract value comparison in the python copy tracing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46159
diff changeset
   510
3a0c41336961 copies: extract value comparison in the python copy tracing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46159
diff changeset
   511
45640
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45639
diff changeset
   512
def _revinfo_getter_extra(repo):
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45639
diff changeset
   513
    """return a function that return multiple data given a <rev>"i
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45639
diff changeset
   514
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45639
diff changeset
   515
    * p1: revision number of first parent
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45639
diff changeset
   516
    * p2: revision number of first parent
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45639
diff changeset
   517
    * p1copies: mapping of copies from p1
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45639
diff changeset
   518
    * p2copies: mapping of copies from p2
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45639
diff changeset
   519
    * removed: a list of removed files
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45639
diff changeset
   520
    * ismerged: a callback to know if file was merged in that revision
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45639
diff changeset
   521
    """
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45639
diff changeset
   522
    cl = repo.changelog
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45639
diff changeset
   523
    parents = cl.parentrevs
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45639
diff changeset
   524
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45639
diff changeset
   525
    def get_ismerged(rev):
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45639
diff changeset
   526
        ctx = repo[rev]
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45639
diff changeset
   527
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45639
diff changeset
   528
        def ismerged(path):
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45639
diff changeset
   529
            if path not in ctx.files():
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45639
diff changeset
   530
                return False
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45639
diff changeset
   531
            fctx = ctx[path]
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45639
diff changeset
   532
            parents = fctx._filelog.parents(fctx._filenode)
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45639
diff changeset
   533
            nb_parents = 0
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45639
diff changeset
   534
            for n in parents:
46114
59fa3890d40a node: import symbols explicitly
Joerg Sonnenberger <joerg@bec.de>
parents: 46110
diff changeset
   535
                if n != nullid:
45640
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45639
diff changeset
   536
                    nb_parents += 1
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45639
diff changeset
   537
            return nb_parents >= 2
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45639
diff changeset
   538
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45639
diff changeset
   539
        return ismerged
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45639
diff changeset
   540
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45639
diff changeset
   541
    def revinfo(rev):
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45639
diff changeset
   542
        p1, p2 = parents(rev)
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45639
diff changeset
   543
        ctx = repo[rev]
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45639
diff changeset
   544
        p1copies, p2copies = ctx._copies
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45639
diff changeset
   545
        removed = ctx.filesremoved()
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45639
diff changeset
   546
        return p1, p2, p1copies, p2copies, removed, get_ismerged(rev)
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45639
diff changeset
   547
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45639
diff changeset
   548
    return revinfo
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45639
diff changeset
   549
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45639
diff changeset
   550
45639
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   551
def _combine_changeset_copies_extra(
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   552
    revs, children, targetrev, revinfo, match, isancestor
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   553
):
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   554
    """version of `_combine_changeset_copies` that works with the Google
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   555
    specific "extra" based storage for copy information"""
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   556
    all_copies = {}
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   557
    alwaysmatch = match.always()
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   558
    for r in revs:
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   559
        copies = all_copies.pop(r, None)
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   560
        if copies is None:
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   561
            # this is a root
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   562
            copies = {}
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   563
        for i, c in enumerate(children[r]):
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   564
            p1, p2, p1copies, p2copies, removed, ismerged = revinfo(c)
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   565
            if r == p1:
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   566
                parent = 1
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   567
                childcopies = p1copies
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   568
            else:
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   569
                assert r == p2
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   570
                parent = 2
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   571
                childcopies = p2copies
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   572
            if not alwaysmatch:
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   573
                childcopies = {
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   574
                    dst: src for dst, src in childcopies.items() if match(dst)
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   575
                }
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   576
            newcopies = copies
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   577
            if childcopies:
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   578
                newcopies = copies.copy()
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   579
                for dest, source in pycompat.iteritems(childcopies):
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   580
                    prev = copies.get(source)
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   581
                    if prev is not None and prev[1] is not None:
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   582
                        source = prev[1]
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   583
                    newcopies[dest] = (c, source)
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   584
                assert newcopies is not copies
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   585
            for f in removed:
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   586
                if f in newcopies:
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   587
                    if newcopies is copies:
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   588
                        # copy on write to avoid affecting potential other
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   589
                        # branches.  when there are no other branches, this
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   590
                        # could be avoided.
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   591
                        newcopies = copies.copy()
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   592
                    newcopies[f] = (c, None)
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   593
            othercopies = all_copies.get(c)
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   594
            if othercopies is None:
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   595
                all_copies[c] = newcopies
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   596
            else:
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   597
                # we are the second parent to work on c, we need to merge our
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   598
                # work with the other.
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   599
                #
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   600
                # In case of conflict, parent 1 take precedence over parent 2.
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   601
                # This is an arbitrary choice made anew when implementing
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   602
                # changeset based copies. It was made without regards with
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   603
                # potential filelog related behavior.
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   604
                if parent == 1:
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   605
                    _merge_copies_dict_extra(
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   606
                        othercopies, newcopies, isancestor, ismerged
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   607
                    )
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   608
                else:
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   609
                    _merge_copies_dict_extra(
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   610
                        newcopies, othercopies, isancestor, ismerged
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   611
                    )
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   612
                    all_copies[c] = newcopies
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   613
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   614
    final_copies = {}
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   615
    for dest, (tt, source) in all_copies[targetrev].items():
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   616
        if source is not None:
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   617
            final_copies[dest] = source
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   618
    return final_copies
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   619
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   620
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   621
def _merge_copies_dict_extra(minor, major, isancestor, ismerged):
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   622
    """version of `_merge_copies_dict` that works with the Google
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   623
    specific "extra" based storage for copy information"""
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   624
    for dest, value in major.items():
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   625
        other = minor.get(dest)
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   626
        if other is None:
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   627
            minor[dest] = value
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   628
        else:
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   629
            new_tt = value[0]
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   630
            other_tt = other[0]
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   631
            if value[1] == other[1]:
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   632
                continue
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   633
            # content from "major" wins, unless it is older
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   634
            # than the branch point or there is a merge
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   635
            if (
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   636
                new_tt == other_tt
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   637
                or not isancestor(new_tt, other_tt)
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   638
                or ismerged(dest)
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   639
            ):
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   640
                minor[dest] = value
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   641
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45627
diff changeset
   642
42595
819712deac69 copies: follow copies across merge base without source file (issue6163)
Martin von Zweigbergk <martinvonz@google.com>
parents: 42594
diff changeset
   643
def _forwardcopies(a, b, base=None, match=None):
35429
8801cdcea01f copies: extract method for getting non-wdir forward copies
Martin von Zweigbergk <martinvonz@google.com>
parents: 35428
diff changeset
   644
    """find {dst@b: src@a} copy mapping where a is an ancestor of b"""
8801cdcea01f copies: extract method for getting non-wdir forward copies
Martin von Zweigbergk <martinvonz@google.com>
parents: 35428
diff changeset
   645
42595
819712deac69 copies: follow copies across merge base without source file (issue6163)
Martin von Zweigbergk <martinvonz@google.com>
parents: 42594
diff changeset
   646
    if base is None:
819712deac69 copies: follow copies across merge base without source file (issue6163)
Martin von Zweigbergk <martinvonz@google.com>
parents: 42594
diff changeset
   647
        base = a
40422
873f3682c8af narrow: make copies.pathcopies() filter with narrowspec again
Martin von Zweigbergk <martinvonz@google.com>
parents: 40077
diff changeset
   648
    match = a.repo().narrowmatch(match)
35429
8801cdcea01f copies: extract method for getting non-wdir forward copies
Martin von Zweigbergk <martinvonz@google.com>
parents: 35428
diff changeset
   649
    # check for working copy
8801cdcea01f copies: extract method for getting non-wdir forward copies
Martin von Zweigbergk <martinvonz@google.com>
parents: 35428
diff changeset
   650
    if b.rev() is None:
42595
819712deac69 copies: follow copies across merge base without source file (issue6163)
Martin von Zweigbergk <martinvonz@google.com>
parents: 42594
diff changeset
   651
        cm = _committedforwardcopies(a, b.p1(), base, match)
35430
e54f02ec6a05 copies: group wdir-handling in one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 35429
diff changeset
   652
        # combine copies from dirstate if necessary
42593
11ceb1b8fd74 copies: inline _chainandfilter() to prepare for next patch
Martin von Zweigbergk <martinvonz@google.com>
parents: 42592
diff changeset
   653
        copies = _chain(cm, _dirstatecopies(b._repo, match))
42592
a48f6f18dc6d copies: remove most early returns from pathcopies() and _forwardcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42591
diff changeset
   654
    else:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43022
diff changeset
   655
        copies = _committedforwardcopies(a, b, base, match)
42592
a48f6f18dc6d copies: remove most early returns from pathcopies() and _forwardcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42591
diff changeset
   656
    return copies
15775
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
   657
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43022
diff changeset
   658
41762
3158cb74fbca copies: make _backwardrenames() filter out copies by destination
Martin von Zweigbergk <martinvonz@google.com>
parents: 41761
diff changeset
   659
def _backwardrenames(a, b, match):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   660
    if a._repo.ui.config(b'experimental', b'copytrace') == b'off':
26013
38f92d12357c copy: add flag for disabling copy tracing
Durham Goode <durham@fb.com>
parents: 25924
diff changeset
   661
        return {}
38f92d12357c copy: add flag for disabling copy tracing
Durham Goode <durham@fb.com>
parents: 25924
diff changeset
   662
18136
f23dea2b296e copies: do not track backward copies, only renames (issue3739)
Siddharth Agarwal <sid0@fb.com>
parents: 18135
diff changeset
   663
    # Even though we're not taking copies into account, 1:n rename situations
f23dea2b296e copies: do not track backward copies, only renames (issue3739)
Siddharth Agarwal <sid0@fb.com>
parents: 18135
diff changeset
   664
    # can still exist (e.g. hg cp a b; hg mv a c). In those cases we
f23dea2b296e copies: do not track backward copies, only renames (issue3739)
Siddharth Agarwal <sid0@fb.com>
parents: 18135
diff changeset
   665
    # arbitrarily pick one of the renames.
41762
3158cb74fbca copies: make _backwardrenames() filter out copies by destination
Martin von Zweigbergk <martinvonz@google.com>
parents: 41761
diff changeset
   666
    # We don't want to pass in "match" here, since that would filter
3158cb74fbca copies: make _backwardrenames() filter out copies by destination
Martin von Zweigbergk <martinvonz@google.com>
parents: 41761
diff changeset
   667
    # the destination by it. Since we're reversing the copies, we want
3158cb74fbca copies: make _backwardrenames() filter out copies by destination
Martin von Zweigbergk <martinvonz@google.com>
parents: 41761
diff changeset
   668
    # to filter the source instead.
15775
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
   669
    f = _forwardcopies(b, a)
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
   670
    r = {}
43106
d783f945a701 py3: finish porting iteritems() to pycompat and remove source transformer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43077
diff changeset
   671
    for k, v in sorted(pycompat.iteritems(f)):
41762
3158cb74fbca copies: make _backwardrenames() filter out copies by destination
Martin von Zweigbergk <martinvonz@google.com>
parents: 41761
diff changeset
   672
        if match and not match(v):
3158cb74fbca copies: make _backwardrenames() filter out copies by destination
Martin von Zweigbergk <martinvonz@google.com>
parents: 41761
diff changeset
   673
            continue
18136
f23dea2b296e copies: do not track backward copies, only renames (issue3739)
Siddharth Agarwal <sid0@fb.com>
parents: 18135
diff changeset
   674
        # remove copies
f23dea2b296e copies: do not track backward copies, only renames (issue3739)
Siddharth Agarwal <sid0@fb.com>
parents: 18135
diff changeset
   675
        if v in a:
f23dea2b296e copies: do not track backward copies, only renames (issue3739)
Siddharth Agarwal <sid0@fb.com>
parents: 18135
diff changeset
   676
            continue
15775
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
   677
        r[v] = k
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
   678
    return r
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
   679
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43022
diff changeset
   680
24782
4906dc0e038c copies: add matcher parameter to copy logic
Durham Goode <durham@fb.com>
parents: 24625
diff changeset
   681
def pathcopies(x, y, match=None):
35428
9cf37d111acb copies: consistently use """ for docstrings
Martin von Zweigbergk <martinvonz@google.com>
parents: 35427
diff changeset
   682
    """find {dst@y: src@x} copy mapping for directed compare"""
40058
25b2868206e2 copies: add a devel debug mode to trace what copy tracing does
Boris Feld <boris.feld@octobus.net>
parents: 39967
diff changeset
   683
    repo = x._repo
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   684
    debug = repo.ui.debugflag and repo.ui.configbool(b'devel', b'debug.copies')
40058
25b2868206e2 copies: add a devel debug mode to trace what copy tracing does
Boris Feld <boris.feld@octobus.net>
parents: 39967
diff changeset
   685
    if debug:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   686
        repo.ui.debug(
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   687
            b'debug.copies: searching copies from %s to %s\n' % (x, y)
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   688
        )
15775
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
   689
    if x == y or not x or not y:
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
   690
        return {}
44323
30862e226339 copies: avoid filtering by short-circuit dirstate-only copies earlier
Martin von Zweigbergk <martinvonz@google.com>
parents: 44299
diff changeset
   691
    if y.rev() is None and x == y.p1():
30862e226339 copies: avoid filtering by short-circuit dirstate-only copies earlier
Martin von Zweigbergk <martinvonz@google.com>
parents: 44299
diff changeset
   692
        if debug:
30862e226339 copies: avoid filtering by short-circuit dirstate-only copies earlier
Martin von Zweigbergk <martinvonz@google.com>
parents: 44299
diff changeset
   693
            repo.ui.debug(b'debug.copies: search mode: dirstate\n')
30862e226339 copies: avoid filtering by short-circuit dirstate-only copies earlier
Martin von Zweigbergk <martinvonz@google.com>
parents: 44299
diff changeset
   694
        # short-circuit to avoid issues with merge states
30862e226339 copies: avoid filtering by short-circuit dirstate-only copies earlier
Martin von Zweigbergk <martinvonz@google.com>
parents: 44299
diff changeset
   695
        return _dirstatecopies(repo, match)
15775
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
   696
    a = y.ancestor(x)
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
   697
    if a == x:
40058
25b2868206e2 copies: add a devel debug mode to trace what copy tracing does
Boris Feld <boris.feld@octobus.net>
parents: 39967
diff changeset
   698
        if debug:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   699
            repo.ui.debug(b'debug.copies: search mode: forward\n')
42592
a48f6f18dc6d copies: remove most early returns from pathcopies() and _forwardcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42591
diff changeset
   700
        copies = _forwardcopies(x, y, match=match)
a48f6f18dc6d copies: remove most early returns from pathcopies() and _forwardcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42591
diff changeset
   701
    elif a == y:
40058
25b2868206e2 copies: add a devel debug mode to trace what copy tracing does
Boris Feld <boris.feld@octobus.net>
parents: 39967
diff changeset
   702
        if debug:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   703
            repo.ui.debug(b'debug.copies: search mode: backward\n')
42592
a48f6f18dc6d copies: remove most early returns from pathcopies() and _forwardcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42591
diff changeset
   704
        copies = _backwardrenames(x, y, match=match)
a48f6f18dc6d copies: remove most early returns from pathcopies() and _forwardcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42591
diff changeset
   705
    else:
a48f6f18dc6d copies: remove most early returns from pathcopies() and _forwardcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42591
diff changeset
   706
        if debug:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   707
            repo.ui.debug(b'debug.copies: search mode: combined\n')
42595
819712deac69 copies: follow copies across merge base without source file (issue6163)
Martin von Zweigbergk <martinvonz@google.com>
parents: 42594
diff changeset
   708
        base = None
46114
59fa3890d40a node: import symbols explicitly
Joerg Sonnenberger <joerg@bec.de>
parents: 46110
diff changeset
   709
        if a.rev() != nullrev:
42595
819712deac69 copies: follow copies across merge base without source file (issue6163)
Martin von Zweigbergk <martinvonz@google.com>
parents: 42594
diff changeset
   710
            base = x
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43022
diff changeset
   711
        copies = _chain(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43022
diff changeset
   712
            _backwardrenames(x, a, match=match),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43022
diff changeset
   713
            _forwardcopies(a, y, base, match=match),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43022
diff changeset
   714
        )
42594
d013099c551b copies: filter invalid copies only at end of pathcopies() (issue6163)
Martin von Zweigbergk <martinvonz@google.com>
parents: 42593
diff changeset
   715
    _filter(x, y, copies)
42592
a48f6f18dc6d copies: remove most early returns from pathcopies() and _forwardcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42591
diff changeset
   716
    return copies
15774
0bd17a4bed88 copies: split the copies api for "normal" and merge cases (API)
Matt Mackall <mpm@selenic.com>
parents: 14494
diff changeset
   717
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43022
diff changeset
   718
30186
f7ed5af31242 mergecopies: rename 'ca' to 'base'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30185
diff changeset
   719
def mergecopies(repo, c1, c2, base):
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   720
    """
42118
967c098eed33 copies: move comment about implementation of mergecopies() to end
Martin von Zweigbergk <martinvonz@google.com>
parents: 42115
diff changeset
   721
    Finds moves and copies between context c1 and c2 that are relevant for
34095
b4b196092cc3 copytrace: move the default copytracing algorithm in a new function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34094
diff changeset
   722
    merging. 'base' will be used as the merge base.
b4b196092cc3 copytrace: move the default copytracing algorithm in a new function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34094
diff changeset
   723
b4b196092cc3 copytrace: move the default copytracing algorithm in a new function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34094
diff changeset
   724
    Copytracing is used in commands like rebase, merge, unshelve, etc to merge
b4b196092cc3 copytrace: move the default copytracing algorithm in a new function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34094
diff changeset
   725
    files that were moved/ copied in one merge parent and modified in another.
b4b196092cc3 copytrace: move the default copytracing algorithm in a new function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34094
diff changeset
   726
    For example:
33843
42ad7cc645a4 copies: add more details to the documentation of mergecopies()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32663
diff changeset
   727
42ad7cc645a4 copies: add more details to the documentation of mergecopies()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32663
diff changeset
   728
    o          ---> 4 another commit
42ad7cc645a4 copies: add more details to the documentation of mergecopies()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32663
diff changeset
   729
    |
42ad7cc645a4 copies: add more details to the documentation of mergecopies()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32663
diff changeset
   730
    |   o      ---> 3 commit that modifies a.txt
42ad7cc645a4 copies: add more details to the documentation of mergecopies()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32663
diff changeset
   731
    |  /
42ad7cc645a4 copies: add more details to the documentation of mergecopies()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32663
diff changeset
   732
    o /        ---> 2 commit that moves a.txt to b.txt
42ad7cc645a4 copies: add more details to the documentation of mergecopies()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32663
diff changeset
   733
    |/
42ad7cc645a4 copies: add more details to the documentation of mergecopies()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32663
diff changeset
   734
    o          ---> 1 merge base
42ad7cc645a4 copies: add more details to the documentation of mergecopies()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32663
diff changeset
   735
42ad7cc645a4 copies: add more details to the documentation of mergecopies()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32663
diff changeset
   736
    If we try to rebase revision 3 on revision 4, since there is no a.txt in
42ad7cc645a4 copies: add more details to the documentation of mergecopies()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32663
diff changeset
   737
    revision 4, and if user have copytrace disabled, we prints the following
42ad7cc645a4 copies: add more details to the documentation of mergecopies()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32663
diff changeset
   738
    message:
42ad7cc645a4 copies: add more details to the documentation of mergecopies()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32663
diff changeset
   739
42ad7cc645a4 copies: add more details to the documentation of mergecopies()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32663
diff changeset
   740
    ```other changed <file> which local deleted```
42ad7cc645a4 copies: add more details to the documentation of mergecopies()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32663
diff changeset
   741
44274
7f8bdee0034e copies: define a type to return from mergecopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 44272
diff changeset
   742
    Returns a tuple where:
16168
7bbabfe25321 copies: add docstring for mergecopies
Matt Mackall <mpm@selenic.com>
parents: 15994
diff changeset
   743
44274
7f8bdee0034e copies: define a type to return from mergecopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 44272
diff changeset
   744
    "branch_copies" an instance of branch_copies.
18134
6c35b53cd28b copies: separate moves via directory renames from explicit copies
Siddharth Agarwal <sid0@fb.com>
parents: 17055
diff changeset
   745
16168
7bbabfe25321 copies: add docstring for mergecopies
Matt Mackall <mpm@selenic.com>
parents: 15994
diff changeset
   746
    "diverge" is a mapping of source name -> list of destination names
7bbabfe25321 copies: add docstring for mergecopies
Matt Mackall <mpm@selenic.com>
parents: 15994
diff changeset
   747
    for divergent renames.
16794
98687cdddcb1 merge: warn about file deleted in one branch and renamed in other (issue3074)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 16792
diff changeset
   748
42118
967c098eed33 copies: move comment about implementation of mergecopies() to end
Martin von Zweigbergk <martinvonz@google.com>
parents: 42115
diff changeset
   749
    This function calls different copytracing algorithms based on config.
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   750
    """
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   751
    # avoid silly behavior for update from empty dir
6430
a6a66e812c34 copies: teach symmetric difference about working revisions
Matt Mackall <mpm@selenic.com>
parents: 6429
diff changeset
   752
    if not c1 or not c2 or c1 == c2:
44275
fa9ad1da2e77 merge: start using the per-side copy dicts
Martin von Zweigbergk <martinvonz@google.com>
parents: 44274
diff changeset
   753
        return branch_copies(), branch_copies(), {}
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   754
41761
012f695546aa copies: respect narrowmatcher in "parent -> working dir" case
Martin von Zweigbergk <martinvonz@google.com>
parents: 41735
diff changeset
   755
    narrowmatch = c1.repo().narrowmatch()
012f695546aa copies: respect narrowmatcher in "parent -> working dir" case
Martin von Zweigbergk <martinvonz@google.com>
parents: 41735
diff changeset
   756
6646
9eb274d773d9 copies: teach copies about dirstate.copies
Matt Mackall <mpm@selenic.com>
parents: 6431
diff changeset
   757
    # avoid silly behavior for parent -> working dir
13878
a8d13ee0ce68 misc: replace .parents()[0] with p1()
Matt Mackall <mpm@selenic.com>
parents: 12683
diff changeset
   758
    if c2.node() is None and c1.node() == repo.dirstate.p1():
44275
fa9ad1da2e77 merge: start using the per-side copy dicts
Martin von Zweigbergk <martinvonz@google.com>
parents: 44274
diff changeset
   759
        return (
fa9ad1da2e77 merge: start using the per-side copy dicts
Martin von Zweigbergk <martinvonz@google.com>
parents: 44274
diff changeset
   760
            branch_copies(_dirstatecopies(repo, narrowmatch)),
fa9ad1da2e77 merge: start using the per-side copy dicts
Martin von Zweigbergk <martinvonz@google.com>
parents: 44274
diff changeset
   761
            branch_copies(),
fa9ad1da2e77 merge: start using the per-side copy dicts
Martin von Zweigbergk <martinvonz@google.com>
parents: 44274
diff changeset
   762
            {},
fa9ad1da2e77 merge: start using the per-side copy dicts
Martin von Zweigbergk <martinvonz@google.com>
parents: 44274
diff changeset
   763
        )
6646
9eb274d773d9 copies: teach copies about dirstate.copies
Matt Mackall <mpm@selenic.com>
parents: 6431
diff changeset
   764
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   765
    copytracing = repo.ui.config(b'experimental', b'copytrace')
42255
d8ca7b99fc51 copies: move check for experimental.copytrace==<falsy> earlier
Martin von Zweigbergk <martinvonz@google.com>
parents: 42254
diff changeset
   766
    if stringutil.parsebool(copytracing) is False:
d8ca7b99fc51 copies: move check for experimental.copytrace==<falsy> earlier
Martin von Zweigbergk <martinvonz@google.com>
parents: 42254
diff changeset
   767
        # stringutil.parsebool() returns None when it is unable to parse the
d8ca7b99fc51 copies: move check for experimental.copytrace==<falsy> earlier
Martin von Zweigbergk <martinvonz@google.com>
parents: 42254
diff changeset
   768
        # value, so we should rely on making sure copytracing is on such cases
44275
fa9ad1da2e77 merge: start using the per-side copy dicts
Martin von Zweigbergk <martinvonz@google.com>
parents: 44274
diff changeset
   769
        return branch_copies(), branch_copies(), {}
34095
b4b196092cc3 copytrace: move the default copytracing algorithm in a new function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34094
diff changeset
   770
42256
a6be3af3a397 copies: ignore heuristics copytracing when using changeset-centric algos
Martin von Zweigbergk <martinvonz@google.com>
parents: 42255
diff changeset
   771
    if usechangesetcentricalgo(repo):
a6be3af3a397 copies: ignore heuristics copytracing when using changeset-centric algos
Martin von Zweigbergk <martinvonz@google.com>
parents: 42255
diff changeset
   772
        # The heuristics don't make sense when we need changeset-centric algos
a6be3af3a397 copies: ignore heuristics copytracing when using changeset-centric algos
Martin von Zweigbergk <martinvonz@google.com>
parents: 42255
diff changeset
   773
        return _fullcopytracing(repo, c1, c2, base)
a6be3af3a397 copies: ignore heuristics copytracing when using changeset-centric algos
Martin von Zweigbergk <martinvonz@google.com>
parents: 42255
diff changeset
   774
26013
38f92d12357c copy: add flag for disabling copy tracing
Durham Goode <durham@fb.com>
parents: 25924
diff changeset
   775
    # Copy trace disabling is explicitly below the node == p1 logic above
38f92d12357c copy: add flag for disabling copy tracing
Durham Goode <durham@fb.com>
parents: 25924
diff changeset
   776
    # because the logic above is required for a simple copy to be kept across a
38f92d12357c copy: add flag for disabling copy tracing
Durham Goode <durham@fb.com>
parents: 25924
diff changeset
   777
    # rebase.
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   778
    if copytracing == b'heuristics':
34367
d00910b286cd copytrace: use ctx.mutable() instead of adhoc constant of non-public phases
Yuya Nishihara <yuya@tcha.org>
parents: 34355
diff changeset
   779
        # Do full copytracing if only non-public revisions are involved as
d00910b286cd copytrace: use ctx.mutable() instead of adhoc constant of non-public phases
Yuya Nishihara <yuya@tcha.org>
parents: 34355
diff changeset
   780
        # that will be fast enough and will also cover the copies which could
d00910b286cd copytrace: use ctx.mutable() instead of adhoc constant of non-public phases
Yuya Nishihara <yuya@tcha.org>
parents: 34355
diff changeset
   781
        # be missed by heuristics
34318
1826d695ad58 copytrace: add a a new config to limit the number of drafts in heuristics
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34295
diff changeset
   782
        if _isfullcopytraceable(repo, c1, base):
34295
fc3b8483c6cb copytrace: use the full copytracing method if only drafts are involved
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34191
diff changeset
   783
            return _fullcopytracing(repo, c1, c2, base)
34191
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34095
diff changeset
   784
        return _heuristicscopytracing(repo, c1, c2, base)
34095
b4b196092cc3 copytrace: move the default copytracing algorithm in a new function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34094
diff changeset
   785
    else:
b4b196092cc3 copytrace: move the default copytracing algorithm in a new function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34094
diff changeset
   786
        return _fullcopytracing(repo, c1, c2, base)
26013
38f92d12357c copy: add flag for disabling copy tracing
Durham Goode <durham@fb.com>
parents: 25924
diff changeset
   787
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43022
diff changeset
   788
34318
1826d695ad58 copytrace: add a a new config to limit the number of drafts in heuristics
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34295
diff changeset
   789
def _isfullcopytraceable(repo, c1, base):
45957
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45907
diff changeset
   790
    """Checks that if base, source and destination are all no-public branches,
34367
d00910b286cd copytrace: use ctx.mutable() instead of adhoc constant of non-public phases
Yuya Nishihara <yuya@tcha.org>
parents: 34355
diff changeset
   791
    if yes let's use the full copytrace algorithm for increased capabilities
d00910b286cd copytrace: use ctx.mutable() instead of adhoc constant of non-public phases
Yuya Nishihara <yuya@tcha.org>
parents: 34355
diff changeset
   792
    since it will be fast enough.
34516
e79b3611223b copies: add docs for config `experimental.copytrace.sourcecommitlimit`
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34367
diff changeset
   793
e79b3611223b copies: add docs for config `experimental.copytrace.sourcecommitlimit`
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34367
diff changeset
   794
    `experimental.copytrace.sourcecommitlimit` can be used to set a limit for
e79b3611223b copies: add docs for config `experimental.copytrace.sourcecommitlimit`
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34367
diff changeset
   795
    number of changesets from c1 to base such that if number of changesets are
e79b3611223b copies: add docs for config `experimental.copytrace.sourcecommitlimit`
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34367
diff changeset
   796
    more than the limit, full copytracing algorithm won't be used.
34295
fc3b8483c6cb copytrace: use the full copytracing method if only drafts are involved
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34191
diff changeset
   797
    """
34318
1826d695ad58 copytrace: add a a new config to limit the number of drafts in heuristics
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34295
diff changeset
   798
    if c1.rev() is None:
1826d695ad58 copytrace: add a a new config to limit the number of drafts in heuristics
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34295
diff changeset
   799
        c1 = c1.p1()
34367
d00910b286cd copytrace: use ctx.mutable() instead of adhoc constant of non-public phases
Yuya Nishihara <yuya@tcha.org>
parents: 34355
diff changeset
   800
    if c1.mutable() and base.mutable():
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43022
diff changeset
   801
        sourcecommitlimit = repo.ui.configint(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   802
            b'experimental', b'copytrace.sourcecommitlimit'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43022
diff changeset
   803
        )
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   804
        commits = len(repo.revs(b'%d::%d', base.rev(), c1.rev()))
34318
1826d695ad58 copytrace: add a a new config to limit the number of drafts in heuristics
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34295
diff changeset
   805
        return commits < sourcecommitlimit
34295
fc3b8483c6cb copytrace: use the full copytracing method if only drafts are involved
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34191
diff changeset
   806
    return False
fc3b8483c6cb copytrace: use the full copytracing method if only drafts are involved
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34191
diff changeset
   807
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43022
diff changeset
   808
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43022
diff changeset
   809
def _checksinglesidecopies(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43022
diff changeset
   810
    src, dsts1, m1, m2, mb, c2, base, copy, renamedelete
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43022
diff changeset
   811
):
42252
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42243
diff changeset
   812
    if src not in m2:
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42243
diff changeset
   813
        # deleted on side 2
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42243
diff changeset
   814
        if src not in m1:
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42243
diff changeset
   815
            # renamed on side 1, deleted on side 2
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42243
diff changeset
   816
            renamedelete[src] = dsts1
44284
d0c3eead515a copies: fix crash when copy source is not in graft base
Martin von Zweigbergk <martinvonz@google.com>
parents: 44275
diff changeset
   817
    elif src not in mb:
d0c3eead515a copies: fix crash when copy source is not in graft base
Martin von Zweigbergk <martinvonz@google.com>
parents: 44275
diff changeset
   818
        # Work around the "short-circuit to avoid issues with merge states"
d0c3eead515a copies: fix crash when copy source is not in graft base
Martin von Zweigbergk <martinvonz@google.com>
parents: 44275
diff changeset
   819
        # thing in pathcopies(): pathcopies(x, y) can return a copy where the
d0c3eead515a copies: fix crash when copy source is not in graft base
Martin von Zweigbergk <martinvonz@google.com>
parents: 44275
diff changeset
   820
        # destination doesn't exist in y.
d0c3eead515a copies: fix crash when copy source is not in graft base
Martin von Zweigbergk <martinvonz@google.com>
parents: 44275
diff changeset
   821
        pass
44788
d452acc8cce8 flags: account for flag change when tracking rename relevant to merge
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44323
diff changeset
   822
    elif mb[src] != m2[src] and not _related(c2[src], base[src]):
d452acc8cce8 flags: account for flag change when tracking rename relevant to merge
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44323
diff changeset
   823
        return
d452acc8cce8 flags: account for flag change when tracking rename relevant to merge
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44323
diff changeset
   824
    elif mb[src] != m2[src] or mb.flags(src) != m2.flags(src):
42252
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42243
diff changeset
   825
        # modified on side 2
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42243
diff changeset
   826
        for dst in dsts1:
44299
b4057d001760 merge: when rename was made on both sides, use ancestor as merge base
Martin von Zweigbergk <martinvonz@google.com>
parents: 44284
diff changeset
   827
            copy[dst] = src
42252
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42243
diff changeset
   828
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43022
diff changeset
   829
44274
7f8bdee0034e copies: define a type to return from mergecopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 44272
diff changeset
   830
class branch_copies(object):
7f8bdee0034e copies: define a type to return from mergecopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 44272
diff changeset
   831
    """Information about copies made on one side of a merge/graft.
7f8bdee0034e copies: define a type to return from mergecopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 44272
diff changeset
   832
7f8bdee0034e copies: define a type to return from mergecopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 44272
diff changeset
   833
    "copy" is a mapping from destination name -> source name,
7f8bdee0034e copies: define a type to return from mergecopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 44272
diff changeset
   834
    where source is in c1 and destination is in c2 or vice-versa.
7f8bdee0034e copies: define a type to return from mergecopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 44272
diff changeset
   835
7f8bdee0034e copies: define a type to return from mergecopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 44272
diff changeset
   836
    "movewithdir" is a mapping from source name -> destination name,
7f8bdee0034e copies: define a type to return from mergecopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 44272
diff changeset
   837
    where the file at source present in one context but not the other
7f8bdee0034e copies: define a type to return from mergecopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 44272
diff changeset
   838
    needs to be moved to destination by the merge process, because the
7f8bdee0034e copies: define a type to return from mergecopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 44272
diff changeset
   839
    other context moved the directory it is in.
7f8bdee0034e copies: define a type to return from mergecopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 44272
diff changeset
   840
7f8bdee0034e copies: define a type to return from mergecopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 44272
diff changeset
   841
    "renamedelete" is a mapping of source name -> list of destination
7f8bdee0034e copies: define a type to return from mergecopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 44272
diff changeset
   842
    names for files deleted in c1 that were renamed in c2 or vice-versa.
7f8bdee0034e copies: define a type to return from mergecopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 44272
diff changeset
   843
7f8bdee0034e copies: define a type to return from mergecopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 44272
diff changeset
   844
    "dirmove" is a mapping of detected source dir -> destination dir renames.
7f8bdee0034e copies: define a type to return from mergecopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 44272
diff changeset
   845
    This is needed for handling changes to new files previously grafted into
7f8bdee0034e copies: define a type to return from mergecopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 44272
diff changeset
   846
    renamed directories.
7f8bdee0034e copies: define a type to return from mergecopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 44272
diff changeset
   847
    """
7f8bdee0034e copies: define a type to return from mergecopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 44272
diff changeset
   848
7f8bdee0034e copies: define a type to return from mergecopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 44272
diff changeset
   849
    def __init__(
7f8bdee0034e copies: define a type to return from mergecopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 44272
diff changeset
   850
        self, copy=None, renamedelete=None, dirmove=None, movewithdir=None
7f8bdee0034e copies: define a type to return from mergecopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 44272
diff changeset
   851
    ):
7f8bdee0034e copies: define a type to return from mergecopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 44272
diff changeset
   852
        self.copy = {} if copy is None else copy
7f8bdee0034e copies: define a type to return from mergecopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 44272
diff changeset
   853
        self.renamedelete = {} if renamedelete is None else renamedelete
7f8bdee0034e copies: define a type to return from mergecopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 44272
diff changeset
   854
        self.dirmove = {} if dirmove is None else dirmove
7f8bdee0034e copies: define a type to return from mergecopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 44272
diff changeset
   855
        self.movewithdir = {} if movewithdir is None else movewithdir
7f8bdee0034e copies: define a type to return from mergecopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 44272
diff changeset
   856
45014
cfd06649a1b8 copies: implement __repr__ on branch_copies for debugging
Martin von Zweigbergk <martinvonz@google.com>
parents: 44981
diff changeset
   857
    def __repr__(self):
45957
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45907
diff changeset
   858
        return '<branch_copies\n  copy=%r\n  renamedelete=%r\n  dirmove=%r\n  movewithdir=%r\n>' % (
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45907
diff changeset
   859
            self.copy,
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45907
diff changeset
   860
            self.renamedelete,
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45907
diff changeset
   861
            self.dirmove,
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45907
diff changeset
   862
            self.movewithdir,
45014
cfd06649a1b8 copies: implement __repr__ on branch_copies for debugging
Martin von Zweigbergk <martinvonz@google.com>
parents: 44981
diff changeset
   863
        )
cfd06649a1b8 copies: implement __repr__ on branch_copies for debugging
Martin von Zweigbergk <martinvonz@google.com>
parents: 44981
diff changeset
   864
44274
7f8bdee0034e copies: define a type to return from mergecopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 44272
diff changeset
   865
34095
b4b196092cc3 copytrace: move the default copytracing algorithm in a new function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34094
diff changeset
   866
def _fullcopytracing(repo, c1, c2, base):
45957
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45907
diff changeset
   867
    """The full copytracing algorithm which finds all the new files that were
34095
b4b196092cc3 copytrace: move the default copytracing algorithm in a new function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34094
diff changeset
   868
    added from merge base up to the top commit and for each file it checks if
b4b196092cc3 copytrace: move the default copytracing algorithm in a new function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34094
diff changeset
   869
    this file was copied from another file.
b4b196092cc3 copytrace: move the default copytracing algorithm in a new function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34094
diff changeset
   870
b4b196092cc3 copytrace: move the default copytracing algorithm in a new function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34094
diff changeset
   871
    This is pretty slow when a lot of changesets are involved but will track all
b4b196092cc3 copytrace: move the default copytracing algorithm in a new function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34094
diff changeset
   872
    the copies.
b4b196092cc3 copytrace: move the default copytracing algorithm in a new function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34094
diff changeset
   873
    """
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   874
    m1 = c1.manifest()
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   875
    m2 = c2.manifest()
30186
f7ed5af31242 mergecopies: rename 'ca' to 'base'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30185
diff changeset
   876
    mb = base.manifest()
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   877
42252
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42243
diff changeset
   878
    copies1 = pathcopies(base, c1)
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42243
diff changeset
   879
    copies2 = pathcopies(base, c2)
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42243
diff changeset
   880
44242
baf3fe2977cc copies: move early return in mergecopies() earlier
Martin von Zweigbergk <martinvonz@google.com>
parents: 44093
diff changeset
   881
    if not (copies1 or copies2):
44275
fa9ad1da2e77 merge: start using the per-side copy dicts
Martin von Zweigbergk <martinvonz@google.com>
parents: 44274
diff changeset
   882
        return branch_copies(), branch_copies(), {}
44242
baf3fe2977cc copies: move early return in mergecopies() earlier
Martin von Zweigbergk <martinvonz@google.com>
parents: 44093
diff changeset
   883
42252
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42243
diff changeset
   884
    inversecopies1 = {}
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42243
diff changeset
   885
    inversecopies2 = {}
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42243
diff changeset
   886
    for dst, src in copies1.items():
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42243
diff changeset
   887
        inversecopies1.setdefault(src, []).append(dst)
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42243
diff changeset
   888
    for dst, src in copies2.items():
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42243
diff changeset
   889
        inversecopies2.setdefault(src, []).append(dst)
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42243
diff changeset
   890
44271
6ca9f45b32b0 copies: make mergecopies() distinguish between copies on each side
Martin von Zweigbergk <martinvonz@google.com>
parents: 44244
diff changeset
   891
    copy1 = {}
6ca9f45b32b0 copies: make mergecopies() distinguish between copies on each side
Martin von Zweigbergk <martinvonz@google.com>
parents: 44244
diff changeset
   892
    copy2 = {}
42252
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42243
diff changeset
   893
    diverge = {}
44271
6ca9f45b32b0 copies: make mergecopies() distinguish between copies on each side
Martin von Zweigbergk <martinvonz@google.com>
parents: 44244
diff changeset
   894
    renamedelete1 = {}
6ca9f45b32b0 copies: make mergecopies() distinguish between copies on each side
Martin von Zweigbergk <martinvonz@google.com>
parents: 44244
diff changeset
   895
    renamedelete2 = {}
42252
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42243
diff changeset
   896
    allsources = set(inversecopies1) | set(inversecopies2)
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42243
diff changeset
   897
    for src in allsources:
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42243
diff changeset
   898
        dsts1 = inversecopies1.get(src)
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42243
diff changeset
   899
        dsts2 = inversecopies2.get(src)
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42243
diff changeset
   900
        if dsts1 and dsts2:
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42243
diff changeset
   901
            # copied/renamed on both sides
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42243
diff changeset
   902
            if src not in m1 and src not in m2:
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42243
diff changeset
   903
                # renamed on both sides
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42243
diff changeset
   904
                dsts1 = set(dsts1)
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42243
diff changeset
   905
                dsts2 = set(dsts2)
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42243
diff changeset
   906
                # If there's some overlap in the rename destinations, we
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42243
diff changeset
   907
                # consider it not divergent. For example, if side 1 copies 'a'
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42243
diff changeset
   908
                # to 'b' and 'c' and deletes 'a', and side 2 copies 'a' to 'c'
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42243
diff changeset
   909
                # and 'd' and deletes 'a'.
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42243
diff changeset
   910
                if dsts1 & dsts2:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43022
diff changeset
   911
                    for dst in dsts1 & dsts2:
44271
6ca9f45b32b0 copies: make mergecopies() distinguish between copies on each side
Martin von Zweigbergk <martinvonz@google.com>
parents: 44244
diff changeset
   912
                        copy1[dst] = src
6ca9f45b32b0 copies: make mergecopies() distinguish between copies on each side
Martin von Zweigbergk <martinvonz@google.com>
parents: 44244
diff changeset
   913
                        copy2[dst] = src
42252
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42243
diff changeset
   914
                else:
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42243
diff changeset
   915
                    diverge[src] = sorted(dsts1 | dsts2)
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42243
diff changeset
   916
            elif src in m1 and src in m2:
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42243
diff changeset
   917
                # copied on both sides
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42243
diff changeset
   918
                dsts1 = set(dsts1)
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42243
diff changeset
   919
                dsts2 = set(dsts2)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43022
diff changeset
   920
                for dst in dsts1 & dsts2:
44271
6ca9f45b32b0 copies: make mergecopies() distinguish between copies on each side
Martin von Zweigbergk <martinvonz@google.com>
parents: 44244
diff changeset
   921
                    copy1[dst] = src
6ca9f45b32b0 copies: make mergecopies() distinguish between copies on each side
Martin von Zweigbergk <martinvonz@google.com>
parents: 44244
diff changeset
   922
                    copy2[dst] = src
42252
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42243
diff changeset
   923
            # TODO: Handle cases where it was renamed on one side and copied
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42243
diff changeset
   924
            # on the other side
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42243
diff changeset
   925
        elif dsts1:
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42243
diff changeset
   926
            # copied/renamed only on side 1
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43022
diff changeset
   927
            _checksinglesidecopies(
44271
6ca9f45b32b0 copies: make mergecopies() distinguish between copies on each side
Martin von Zweigbergk <martinvonz@google.com>
parents: 44244
diff changeset
   928
                src, dsts1, m1, m2, mb, c2, base, copy1, renamedelete1
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43022
diff changeset
   929
            )
42252
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42243
diff changeset
   930
        elif dsts2:
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42243
diff changeset
   931
            # copied/renamed only on side 2
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43022
diff changeset
   932
            _checksinglesidecopies(
44271
6ca9f45b32b0 copies: make mergecopies() distinguish between copies on each side
Martin von Zweigbergk <martinvonz@google.com>
parents: 44244
diff changeset
   933
                src, dsts2, m2, m1, mb, c1, base, copy2, renamedelete2
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43022
diff changeset
   934
            )
42252
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42243
diff changeset
   935
26659
df66736a128e copies: group bothnew with other sets
Matt Mackall <mpm@selenic.com>
parents: 26658
diff changeset
   936
    # find interesting file sets from manifests
46110
2f357d053df2 copies: make calculating lazy for dir move detection's "addedfiles"
Kyle Lippincott <spectral@google.com>
parents: 46061
diff changeset
   937
    cache = []
2f357d053df2 copies: make calculating lazy for dir move detection's "addedfiles"
Kyle Lippincott <spectral@google.com>
parents: 46061
diff changeset
   938
2f357d053df2 copies: make calculating lazy for dir move detection's "addedfiles"
Kyle Lippincott <spectral@google.com>
parents: 46061
diff changeset
   939
    def _get_addedfiles(idx):
2f357d053df2 copies: make calculating lazy for dir move detection's "addedfiles"
Kyle Lippincott <spectral@google.com>
parents: 46061
diff changeset
   940
        if not cache:
2f357d053df2 copies: make calculating lazy for dir move detection's "addedfiles"
Kyle Lippincott <spectral@google.com>
parents: 46061
diff changeset
   941
            addedinm1 = m1.filesnotin(mb, repo.narrowmatch())
2f357d053df2 copies: make calculating lazy for dir move detection's "addedfiles"
Kyle Lippincott <spectral@google.com>
parents: 46061
diff changeset
   942
            addedinm2 = m2.filesnotin(mb, repo.narrowmatch())
2f357d053df2 copies: make calculating lazy for dir move detection's "addedfiles"
Kyle Lippincott <spectral@google.com>
parents: 46061
diff changeset
   943
            u1 = sorted(addedinm1 - addedinm2)
2f357d053df2 copies: make calculating lazy for dir move detection's "addedfiles"
Kyle Lippincott <spectral@google.com>
parents: 46061
diff changeset
   944
            u2 = sorted(addedinm2 - addedinm1)
2f357d053df2 copies: make calculating lazy for dir move detection's "addedfiles"
Kyle Lippincott <spectral@google.com>
parents: 46061
diff changeset
   945
            cache.extend((u1, u2))
2f357d053df2 copies: make calculating lazy for dir move detection's "addedfiles"
Kyle Lippincott <spectral@google.com>
parents: 46061
diff changeset
   946
        return cache[idx]
42253
d69bc8ffbe6f copies: inline _computenonoverlap() in mergecopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42252
diff changeset
   947
46110
2f357d053df2 copies: make calculating lazy for dir move detection's "addedfiles"
Kyle Lippincott <spectral@google.com>
parents: 46061
diff changeset
   948
    u1fn = lambda: _get_addedfiles(0)
2f357d053df2 copies: make calculating lazy for dir move detection's "addedfiles"
Kyle Lippincott <spectral@google.com>
parents: 46061
diff changeset
   949
    u2fn = lambda: _get_addedfiles(1)
2f357d053df2 copies: make calculating lazy for dir move detection's "addedfiles"
Kyle Lippincott <spectral@google.com>
parents: 46061
diff changeset
   950
    if repo.ui.debugflag:
2f357d053df2 copies: make calculating lazy for dir move detection's "addedfiles"
Kyle Lippincott <spectral@google.com>
parents: 46061
diff changeset
   951
        u1 = u1fn()
2f357d053df2 copies: make calculating lazy for dir move detection's "addedfiles"
Kyle Lippincott <spectral@google.com>
parents: 46061
diff changeset
   952
        u2 = u2fn()
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   953
46110
2f357d053df2 copies: make calculating lazy for dir move detection's "addedfiles"
Kyle Lippincott <spectral@google.com>
parents: 46061
diff changeset
   954
        header = b"  unmatched files in %s"
2f357d053df2 copies: make calculating lazy for dir move detection's "addedfiles"
Kyle Lippincott <spectral@google.com>
parents: 46061
diff changeset
   955
        if u1:
2f357d053df2 copies: make calculating lazy for dir move detection's "addedfiles"
Kyle Lippincott <spectral@google.com>
parents: 46061
diff changeset
   956
            repo.ui.debug(
2f357d053df2 copies: make calculating lazy for dir move detection's "addedfiles"
Kyle Lippincott <spectral@google.com>
parents: 46061
diff changeset
   957
                b"%s:\n   %s\n" % (header % b'local', b"\n   ".join(u1))
2f357d053df2 copies: make calculating lazy for dir move detection's "addedfiles"
Kyle Lippincott <spectral@google.com>
parents: 46061
diff changeset
   958
            )
2f357d053df2 copies: make calculating lazy for dir move detection's "addedfiles"
Kyle Lippincott <spectral@google.com>
parents: 46061
diff changeset
   959
        if u2:
2f357d053df2 copies: make calculating lazy for dir move detection's "addedfiles"
Kyle Lippincott <spectral@google.com>
parents: 46061
diff changeset
   960
            repo.ui.debug(
2f357d053df2 copies: make calculating lazy for dir move detection's "addedfiles"
Kyle Lippincott <spectral@google.com>
parents: 46061
diff changeset
   961
                b"%s:\n   %s\n" % (header % b'other', b"\n   ".join(u2))
2f357d053df2 copies: make calculating lazy for dir move detection's "addedfiles"
Kyle Lippincott <spectral@google.com>
parents: 46061
diff changeset
   962
            )
2f357d053df2 copies: make calculating lazy for dir move detection's "addedfiles"
Kyle Lippincott <spectral@google.com>
parents: 46061
diff changeset
   963
44243
782e0d9c3b74 copies: avoid calculating debug-only stuff without --debug
Martin von Zweigbergk <martinvonz@google.com>
parents: 44242
diff changeset
   964
        renamedeleteset = set()
782e0d9c3b74 copies: avoid calculating debug-only stuff without --debug
Martin von Zweigbergk <martinvonz@google.com>
parents: 44242
diff changeset
   965
        divergeset = set()
782e0d9c3b74 copies: avoid calculating debug-only stuff without --debug
Martin von Zweigbergk <martinvonz@google.com>
parents: 44242
diff changeset
   966
        for dsts in diverge.values():
782e0d9c3b74 copies: avoid calculating debug-only stuff without --debug
Martin von Zweigbergk <martinvonz@google.com>
parents: 44242
diff changeset
   967
            divergeset.update(dsts)
44271
6ca9f45b32b0 copies: make mergecopies() distinguish between copies on each side
Martin von Zweigbergk <martinvonz@google.com>
parents: 44244
diff changeset
   968
        for dsts in renamedelete1.values():
6ca9f45b32b0 copies: make mergecopies() distinguish between copies on each side
Martin von Zweigbergk <martinvonz@google.com>
parents: 44244
diff changeset
   969
            renamedeleteset.update(dsts)
6ca9f45b32b0 copies: make mergecopies() distinguish between copies on each side
Martin von Zweigbergk <martinvonz@google.com>
parents: 44244
diff changeset
   970
        for dsts in renamedelete2.values():
44243
782e0d9c3b74 copies: avoid calculating debug-only stuff without --debug
Martin von Zweigbergk <martinvonz@google.com>
parents: 44242
diff changeset
   971
            renamedeleteset.update(dsts)
782e0d9c3b74 copies: avoid calculating debug-only stuff without --debug
Martin von Zweigbergk <martinvonz@google.com>
parents: 44242
diff changeset
   972
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43022
diff changeset
   973
        repo.ui.debug(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   974
            b"  all copies found (* = to merge, ! = divergent, "
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   975
            b"% = renamed and deleted):\n"
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43022
diff changeset
   976
        )
44272
17e12938f8e7 copies: print debug information about copies per side/branch
Martin von Zweigbergk <martinvonz@google.com>
parents: 44271
diff changeset
   977
        for side, copies in ((b"local", copies1), (b"remote", copies2)):
17e12938f8e7 copies: print debug information about copies per side/branch
Martin von Zweigbergk <martinvonz@google.com>
parents: 44271
diff changeset
   978
            if not copies:
17e12938f8e7 copies: print debug information about copies per side/branch
Martin von Zweigbergk <martinvonz@google.com>
parents: 44271
diff changeset
   979
                continue
17e12938f8e7 copies: print debug information about copies per side/branch
Martin von Zweigbergk <martinvonz@google.com>
parents: 44271
diff changeset
   980
            repo.ui.debug(b"   on %s side:\n" % side)
17e12938f8e7 copies: print debug information about copies per side/branch
Martin von Zweigbergk <martinvonz@google.com>
parents: 44271
diff changeset
   981
            for f in sorted(copies):
17e12938f8e7 copies: print debug information about copies per side/branch
Martin von Zweigbergk <martinvonz@google.com>
parents: 44271
diff changeset
   982
                note = b""
17e12938f8e7 copies: print debug information about copies per side/branch
Martin von Zweigbergk <martinvonz@google.com>
parents: 44271
diff changeset
   983
                if f in copy1 or f in copy2:
17e12938f8e7 copies: print debug information about copies per side/branch
Martin von Zweigbergk <martinvonz@google.com>
parents: 44271
diff changeset
   984
                    note += b"*"
17e12938f8e7 copies: print debug information about copies per side/branch
Martin von Zweigbergk <martinvonz@google.com>
parents: 44271
diff changeset
   985
                if f in divergeset:
17e12938f8e7 copies: print debug information about copies per side/branch
Martin von Zweigbergk <martinvonz@google.com>
parents: 44271
diff changeset
   986
                    note += b"!"
17e12938f8e7 copies: print debug information about copies per side/branch
Martin von Zweigbergk <martinvonz@google.com>
parents: 44271
diff changeset
   987
                if f in renamedeleteset:
17e12938f8e7 copies: print debug information about copies per side/branch
Martin von Zweigbergk <martinvonz@google.com>
parents: 44271
diff changeset
   988
                    note += b"%"
17e12938f8e7 copies: print debug information about copies per side/branch
Martin von Zweigbergk <martinvonz@google.com>
parents: 44271
diff changeset
   989
                repo.ui.debug(
17e12938f8e7 copies: print debug information about copies per side/branch
Martin von Zweigbergk <martinvonz@google.com>
parents: 44271
diff changeset
   990
                    b"    src: '%s' -> dst: '%s' %s\n" % (copies[f], f, note)
17e12938f8e7 copies: print debug information about copies per side/branch
Martin von Zweigbergk <martinvonz@google.com>
parents: 44271
diff changeset
   991
                )
44243
782e0d9c3b74 copies: avoid calculating debug-only stuff without --debug
Martin von Zweigbergk <martinvonz@google.com>
parents: 44242
diff changeset
   992
        del renamedeleteset
782e0d9c3b74 copies: avoid calculating debug-only stuff without --debug
Martin von Zweigbergk <martinvonz@google.com>
parents: 44242
diff changeset
   993
        del divergeset
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   994
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   995
    repo.ui.debug(b"  checking for directory renames\n")
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   996
46110
2f357d053df2 copies: make calculating lazy for dir move detection's "addedfiles"
Kyle Lippincott <spectral@google.com>
parents: 46061
diff changeset
   997
    dirmove1, movewithdir2 = _dir_renames(repo, c1, copy1, copies1, u2fn)
2f357d053df2 copies: make calculating lazy for dir move detection's "addedfiles"
Kyle Lippincott <spectral@google.com>
parents: 46061
diff changeset
   998
    dirmove2, movewithdir1 = _dir_renames(repo, c2, copy2, copies2, u1fn)
44244
45192589555c copies: extract function for finding directory renames
Martin von Zweigbergk <martinvonz@google.com>
parents: 44243
diff changeset
   999
44275
fa9ad1da2e77 merge: start using the per-side copy dicts
Martin von Zweigbergk <martinvonz@google.com>
parents: 44274
diff changeset
  1000
    branch_copies1 = branch_copies(copy1, renamedelete1, dirmove1, movewithdir1)
fa9ad1da2e77 merge: start using the per-side copy dicts
Martin von Zweigbergk <martinvonz@google.com>
parents: 44274
diff changeset
  1001
    branch_copies2 = branch_copies(copy2, renamedelete2, dirmove2, movewithdir2)
44271
6ca9f45b32b0 copies: make mergecopies() distinguish between copies on each side
Martin von Zweigbergk <martinvonz@google.com>
parents: 44244
diff changeset
  1002
44275
fa9ad1da2e77 merge: start using the per-side copy dicts
Martin von Zweigbergk <martinvonz@google.com>
parents: 44274
diff changeset
  1003
    return branch_copies1, branch_copies2, diverge
44244
45192589555c copies: extract function for finding directory renames
Martin von Zweigbergk <martinvonz@google.com>
parents: 44243
diff changeset
  1004
45192589555c copies: extract function for finding directory renames
Martin von Zweigbergk <martinvonz@google.com>
parents: 44243
diff changeset
  1005
46110
2f357d053df2 copies: make calculating lazy for dir move detection's "addedfiles"
Kyle Lippincott <spectral@google.com>
parents: 46061
diff changeset
  1006
def _dir_renames(repo, ctx, copy, fullcopy, addedfilesfn):
44271
6ca9f45b32b0 copies: make mergecopies() distinguish between copies on each side
Martin von Zweigbergk <martinvonz@google.com>
parents: 44244
diff changeset
  1007
    """Finds moved directories and files that should move with them.
6ca9f45b32b0 copies: make mergecopies() distinguish between copies on each side
Martin von Zweigbergk <martinvonz@google.com>
parents: 44244
diff changeset
  1008
6ca9f45b32b0 copies: make mergecopies() distinguish between copies on each side
Martin von Zweigbergk <martinvonz@google.com>
parents: 44244
diff changeset
  1009
    ctx: the context for one of the sides
6ca9f45b32b0 copies: make mergecopies() distinguish between copies on each side
Martin von Zweigbergk <martinvonz@google.com>
parents: 44244
diff changeset
  1010
    copy: files copied on the same side (as ctx)
6ca9f45b32b0 copies: make mergecopies() distinguish between copies on each side
Martin von Zweigbergk <martinvonz@google.com>
parents: 44244
diff changeset
  1011
    fullcopy: files copied on the same side (as ctx), including those that
6ca9f45b32b0 copies: make mergecopies() distinguish between copies on each side
Martin von Zweigbergk <martinvonz@google.com>
parents: 44244
diff changeset
  1012
              merge.manifestmerge() won't care about
46110
2f357d053df2 copies: make calculating lazy for dir move detection's "addedfiles"
Kyle Lippincott <spectral@google.com>
parents: 46061
diff changeset
  1013
    addedfilesfn: function returning added files on the other side (compared to
2f357d053df2 copies: make calculating lazy for dir move detection's "addedfiles"
Kyle Lippincott <spectral@google.com>
parents: 46061
diff changeset
  1014
                  ctx)
44271
6ca9f45b32b0 copies: make mergecopies() distinguish between copies on each side
Martin von Zweigbergk <martinvonz@google.com>
parents: 44244
diff changeset
  1015
    """
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1016
    # generate a directory move map
17055
8b7cd9a998f0 copies: re-include root directory in directory rename detection (issue3511)
Matt Mackall <mpm@selenic.com>
parents: 16795
diff changeset
  1017
    invalid = set()
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1018
    dirmove = {}
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1019
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1020
    # examine each file copy for a potential directory move, which is
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1021
    # when all the files in a directory are moved to a new directory
43106
d783f945a701 py3: finish porting iteritems() to pycompat and remove source transformer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43077
diff changeset
  1022
    for dst, src in pycompat.iteritems(fullcopy):
25282
0f28815ef066 copies: switch to using pathutil.dirname
Durham Goode <durham@fb.com>
parents: 24782
diff changeset
  1023
        dsrc, ddst = pathutil.dirname(src), pathutil.dirname(dst)
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1024
        if dsrc in invalid:
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1025
            # already seen to be uninteresting
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1026
            continue
46026
b9588ff9b66a copies: avoid materializing a full directory map during copy tracing
Kyle Lippincott <spectral@google.com>
parents: 46001
diff changeset
  1027
        elif ctx.hasdir(dsrc) and ctx.hasdir(ddst):
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1028
            # directory wasn't entirely moved locally
39291
eebd591803ab copies: correctly skip directories that have already been considered
Kyle Lippincott <spectral@google.com>
parents: 38670
diff changeset
  1029
            invalid.add(dsrc)
eebd591803ab copies: correctly skip directories that have already been considered
Kyle Lippincott <spectral@google.com>
parents: 38670
diff changeset
  1030
        elif dsrc in dirmove and dirmove[dsrc] != ddst:
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1031
            # files from the same directory moved to two different places
39291
eebd591803ab copies: correctly skip directories that have already been considered
Kyle Lippincott <spectral@google.com>
parents: 38670
diff changeset
  1032
            invalid.add(dsrc)
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1033
        else:
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1034
            # looks good so far
39291
eebd591803ab copies: correctly skip directories that have already been considered
Kyle Lippincott <spectral@google.com>
parents: 38670
diff changeset
  1035
            dirmove[dsrc] = ddst
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1036
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1037
    for i in invalid:
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1038
        if i in dirmove:
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1039
            del dirmove[i]
46026
b9588ff9b66a copies: avoid materializing a full directory map during copy tracing
Kyle Lippincott <spectral@google.com>
parents: 46001
diff changeset
  1040
    del invalid
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1041
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1042
    if not dirmove:
44244
45192589555c copies: extract function for finding directory renames
Martin von Zweigbergk <martinvonz@google.com>
parents: 44243
diff changeset
  1043
        return {}, {}
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1044
43106
d783f945a701 py3: finish porting iteritems() to pycompat and remove source transformer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43077
diff changeset
  1045
    dirmove = {k + b"/": v + b"/" for k, v in pycompat.iteritems(dirmove)}
39291
eebd591803ab copies: correctly skip directories that have already been considered
Kyle Lippincott <spectral@google.com>
parents: 38670
diff changeset
  1046
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1047
    for d in dirmove:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43022
diff changeset
  1048
        repo.ui.debug(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1049
            b"   discovered dir src: '%s' -> dst: '%s'\n" % (d, dirmove[d])
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43022
diff changeset
  1050
        )
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1051
30183
0106f93ca1d5 checkcopies: move 'movewithdir' initialisation right before its usage
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30138
diff changeset
  1052
    movewithdir = {}
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1053
    # check unaccounted nonoverlapping files against directory moves
46110
2f357d053df2 copies: make calculating lazy for dir move detection's "addedfiles"
Kyle Lippincott <spectral@google.com>
parents: 46061
diff changeset
  1054
    for f in addedfilesfn():
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1055
        if f not in fullcopy:
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1056
            for d in dirmove:
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1057
                if f.startswith(d):
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1058
                    # new file added in a directory that was moved, move it
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43022
diff changeset
  1059
                    df = dirmove[d] + f[len(d) :]
6426
e2c49ef2dd6e copies: don't double-detect items in the directory copy check
Matt Mackall <mpm@selenic.com>
parents: 6425
diff changeset
  1060
                    if df not in copy:
18134
6c35b53cd28b copies: separate moves via directory renames from explicit copies
Siddharth Agarwal <sid0@fb.com>
parents: 17055
diff changeset
  1061
                        movewithdir[f] = df
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43022
diff changeset
  1062
                        repo.ui.debug(
43117
8ff1ecfadcd1 cleanup: join string literals that are already on one line
Martin von Zweigbergk <martinvonz@google.com>
parents: 43106
diff changeset
  1063
                            b"   pending file src: '%s' -> dst: '%s'\n"
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43022
diff changeset
  1064
                            % (f, df)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43022
diff changeset
  1065
                        )
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1066
                    break
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1067
44244
45192589555c copies: extract function for finding directory renames
Martin von Zweigbergk <martinvonz@google.com>
parents: 44243
diff changeset
  1068
    return dirmove, movewithdir
19178
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
  1069
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43022
diff changeset
  1070
34191
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34095
diff changeset
  1071
def _heuristicscopytracing(repo, c1, c2, base):
45957
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45907
diff changeset
  1072
    """Fast copytracing using filename heuristics
34191
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34095
diff changeset
  1073
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34095
diff changeset
  1074
    Assumes that moves or renames are of following two types:
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34095
diff changeset
  1075
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34095
diff changeset
  1076
    1) Inside a directory only (same directory name but different filenames)
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34095
diff changeset
  1077
    2) Move from one directory to another
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34095
diff changeset
  1078
                    (same filenames but different directory names)
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34095
diff changeset
  1079
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34095
diff changeset
  1080
    Works only when there are no merge commits in the "source branch".
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34095
diff changeset
  1081
    Source branch is commits from base up to c2 not including base.
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34095
diff changeset
  1082
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34095
diff changeset
  1083
    If merge is involved it fallbacks to _fullcopytracing().
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34095
diff changeset
  1084
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34095
diff changeset
  1085
    Can be used by setting the following config:
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34095
diff changeset
  1086
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34095
diff changeset
  1087
        [experimental]
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34095
diff changeset
  1088
        copytrace = heuristics
34846
f05a6e015ecc copies: add a config to limit the number of candidates to check in heuristics
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34787
diff changeset
  1089
f05a6e015ecc copies: add a config to limit the number of candidates to check in heuristics
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34787
diff changeset
  1090
    In some cases the copy/move candidates found by heuristics can be very large
f05a6e015ecc copies: add a config to limit the number of candidates to check in heuristics
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34787
diff changeset
  1091
    in number and that will make the algorithm slow. The number of possible
f05a6e015ecc copies: add a config to limit the number of candidates to check in heuristics
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34787
diff changeset
  1092
    candidates to check can be limited by using the config
f05a6e015ecc copies: add a config to limit the number of candidates to check in heuristics
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34787
diff changeset
  1093
    `experimental.copytrace.movecandidateslimit` which defaults to 100.
34191
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34095
diff changeset
  1094
    """
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34095
diff changeset
  1095
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34095
diff changeset
  1096
    if c1.rev() is None:
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34095
diff changeset
  1097
        c1 = c1.p1()
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34095
diff changeset
  1098
    if c2.rev() is None:
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34095
diff changeset
  1099
        c2 = c2.p1()
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34095
diff changeset
  1100
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34095
diff changeset
  1101
    changedfiles = set()
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34095
diff changeset
  1102
    m1 = c1.manifest()
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1103
    if not repo.revs(b'%d::%d', base.rev(), c2.rev()):
34191
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34095
diff changeset
  1104
        # If base is not in c2 branch, we switch to fullcopytracing
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43022
diff changeset
  1105
        repo.ui.debug(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1106
            b"switching to full copytracing as base is not "
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1107
            b"an ancestor of c2\n"
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43022
diff changeset
  1108
        )
34191
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34095
diff changeset
  1109
        return _fullcopytracing(repo, c1, c2, base)
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34095
diff changeset
  1110
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34095
diff changeset
  1111
    ctx = c2
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34095
diff changeset
  1112
    while ctx != base:
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34095
diff changeset
  1113
        if len(ctx.parents()) == 2:
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34095
diff changeset
  1114
            # To keep things simple let's not handle merges
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1115
            repo.ui.debug(b"switching to full copytracing because of merges\n")
34191
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34095
diff changeset
  1116
            return _fullcopytracing(repo, c1, c2, base)
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34095
diff changeset
  1117
        changedfiles.update(ctx.files())
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34095
diff changeset
  1118
        ctx = ctx.p1()
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34095
diff changeset
  1119
44275
fa9ad1da2e77 merge: start using the per-side copy dicts
Martin von Zweigbergk <martinvonz@google.com>
parents: 44274
diff changeset
  1120
    copies2 = {}
34191
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34095
diff changeset
  1121
    cp = _forwardcopies(base, c2)
43106
d783f945a701 py3: finish porting iteritems() to pycompat and remove source transformer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43077
diff changeset
  1122
    for dst, src in pycompat.iteritems(cp):
34191
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34095
diff changeset
  1123
        if src in m1:
44275
fa9ad1da2e77 merge: start using the per-side copy dicts
Martin von Zweigbergk <martinvonz@google.com>
parents: 44274
diff changeset
  1124
            copies2[dst] = src
34191
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34095
diff changeset
  1125
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34095
diff changeset
  1126
    # file is missing if it isn't present in the destination, but is present in
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34095
diff changeset
  1127
    # the base and present in the source.
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34095
diff changeset
  1128
    # Presence in the base is important to exclude added files, presence in the
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34095
diff changeset
  1129
    # source is important to exclude removed files.
36379
f62369667a7c py3: use list comprehensions instead of filter where we need to eagerly filter
Augie Fackler <augie@google.com>
parents: 36155
diff changeset
  1130
    filt = lambda f: f not in m1 and f in base and f in c2
f62369667a7c py3: use list comprehensions instead of filter where we need to eagerly filter
Augie Fackler <augie@google.com>
parents: 36155
diff changeset
  1131
    missingfiles = [f for f in changedfiles if filt(f)]
34191
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34095
diff changeset
  1132
44275
fa9ad1da2e77 merge: start using the per-side copy dicts
Martin von Zweigbergk <martinvonz@google.com>
parents: 44274
diff changeset
  1133
    copies1 = {}
34191
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34095
diff changeset
  1134
    if missingfiles:
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34095
diff changeset
  1135
        basenametofilename = collections.defaultdict(list)
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34095
diff changeset
  1136
        dirnametofilename = collections.defaultdict(list)
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34095
diff changeset
  1137
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34095
diff changeset
  1138
        for f in m1.filesnotin(base.manifest()):
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34095
diff changeset
  1139
            basename = os.path.basename(f)
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34095
diff changeset
  1140
            dirname = os.path.dirname(f)
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34095
diff changeset
  1141
            basenametofilename[basename].append(f)
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34095
diff changeset
  1142
            dirnametofilename[dirname].append(f)
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34095
diff changeset
  1143
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34095
diff changeset
  1144
        for f in missingfiles:
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34095
diff changeset
  1145
            basename = os.path.basename(f)
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34095
diff changeset
  1146
            dirname = os.path.dirname(f)
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34095
diff changeset
  1147
            samebasename = basenametofilename[basename]
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34095
diff changeset
  1148
            samedirname = dirnametofilename[dirname]
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34095
diff changeset
  1149
            movecandidates = samebasename + samedirname
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34095
diff changeset
  1150
            # f is guaranteed to be present in c2, that's why
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34095
diff changeset
  1151
            # c2.filectx(f) won't fail
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34095
diff changeset
  1152
            f2 = c2.filectx(f)
34846
f05a6e015ecc copies: add a config to limit the number of candidates to check in heuristics
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34787
diff changeset
  1153
            # we can have a lot of candidates which can slow down the heuristics
f05a6e015ecc copies: add a config to limit the number of candidates to check in heuristics
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34787
diff changeset
  1154
            # config value to limit the number of candidates moves to check
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43022
diff changeset
  1155
            maxcandidates = repo.ui.configint(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1156
                b'experimental', b'copytrace.movecandidateslimit'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43022
diff changeset
  1157
            )
34846
f05a6e015ecc copies: add a config to limit the number of candidates to check in heuristics
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34787
diff changeset
  1158
f05a6e015ecc copies: add a config to limit the number of candidates to check in heuristics
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34787
diff changeset
  1159
            if len(movecandidates) > maxcandidates:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43022
diff changeset
  1160
                repo.ui.status(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43022
diff changeset
  1161
                    _(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1162
                        b"skipping copytracing for '%s', more "
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1163
                        b"candidates than the limit: %d\n"
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43022
diff changeset
  1164
                    )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43022
diff changeset
  1165
                    % (f, len(movecandidates))
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43022
diff changeset
  1166
                )
34846
f05a6e015ecc copies: add a config to limit the number of candidates to check in heuristics
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34787
diff changeset
  1167
                continue
f05a6e015ecc copies: add a config to limit the number of candidates to check in heuristics
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34787
diff changeset
  1168
34191
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34095
diff changeset
  1169
            for candidate in movecandidates:
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34095
diff changeset
  1170
                f1 = c1.filectx(candidate)
37392
a4f02a17420d copies: clean up _related logic
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 36379
diff changeset
  1171
                if _related(f1, f2):
34191
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34095
diff changeset
  1172
                    # if there are a few related copies then we'll merge
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34095
diff changeset
  1173
                    # changes into all of them. This matches the behaviour
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34095
diff changeset
  1174
                    # of upstream copytracing
44275
fa9ad1da2e77 merge: start using the per-side copy dicts
Martin von Zweigbergk <martinvonz@google.com>
parents: 44274
diff changeset
  1175
                    copies1[candidate] = f
34191
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34095
diff changeset
  1176
44275
fa9ad1da2e77 merge: start using the per-side copy dicts
Martin von Zweigbergk <martinvonz@google.com>
parents: 44274
diff changeset
  1177
    return branch_copies(copies1), branch_copies(copies2), {}
34191
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34095
diff changeset
  1178
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43022
diff changeset
  1179
37392
a4f02a17420d copies: clean up _related logic
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 36379
diff changeset
  1180
def _related(f1, f2):
30138
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
  1181
    """return True if f1 and f2 filectx have a common ancestor
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
  1182
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
  1183
    Walk back to common ancestor to see if the two files originate
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
  1184
    from the same file. Since workingfilectx's rev() is None it messes
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
  1185
    up the integer comparison logic, hence the pre-step check for
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
  1186
    None (f1 and f2 can only be workingfilectx's initially).
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
  1187
    """
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
  1188
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
  1189
    if f1 == f2:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43022
diff changeset
  1190
        return True  # a match
30138
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
  1191
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
  1192
    g1, g2 = f1.ancestors(), f2.ancestors()
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
  1193
    try:
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
  1194
        f1r, f2r = f1.linkrev(), f2.linkrev()
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
  1195
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
  1196
        if f1r is None:
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
  1197
            f1 = next(g1)
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
  1198
        if f2r is None:
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
  1199
            f2 = next(g2)
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
  1200
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
  1201
        while True:
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
  1202
            f1r, f2r = f1.linkrev(), f2.linkrev()
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
  1203
            if f1r > f2r:
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
  1204
                f1 = next(g1)
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
  1205
            elif f2r > f1r:
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
  1206
                f2 = next(g2)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43022
diff changeset
  1207
            else:  # f1 and f2 point to files in the same linkrev
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43022
diff changeset
  1208
                return f1 == f2  # true if they point to the same file
30138
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
  1209
    except StopIteration:
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
  1210
        return False
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
  1211
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43022
diff changeset
  1212
44092
833210fbd900 graftcopies: remove `skip` and `repo` arguments
Martin von Zweigbergk <martinvonz@google.com>
parents: 44091
diff changeset
  1213
def graftcopies(wctx, ctx, base):
44093
06e7e7652ac0 graftcopies: document why the function is useful at all
Martin von Zweigbergk <martinvonz@google.com>
parents: 44092
diff changeset
  1214
    """reproduce copies between base and ctx in the wctx
06e7e7652ac0 graftcopies: document why the function is useful at all
Martin von Zweigbergk <martinvonz@google.com>
parents: 44092
diff changeset
  1215
06e7e7652ac0 graftcopies: document why the function is useful at all
Martin von Zweigbergk <martinvonz@google.com>
parents: 44092
diff changeset
  1216
    Unlike mergecopies(), this function will only consider copies between base
06e7e7652ac0 graftcopies: document why the function is useful at all
Martin von Zweigbergk <martinvonz@google.com>
parents: 44092
diff changeset
  1217
    and ctx; it will ignore copies between base and wctx. Also unlike
06e7e7652ac0 graftcopies: document why the function is useful at all
Martin von Zweigbergk <martinvonz@google.com>
parents: 44092
diff changeset
  1218
    mergecopies(), this function will apply copies to the working copy (instead
06e7e7652ac0 graftcopies: document why the function is useful at all
Martin von Zweigbergk <martinvonz@google.com>
parents: 44092
diff changeset
  1219
    of just returning information about the copies). That makes it cheaper
06e7e7652ac0 graftcopies: document why the function is useful at all
Martin von Zweigbergk <martinvonz@google.com>
parents: 44092
diff changeset
  1220
    (especially in the common case of base==ctx.p1()) and useful also when
06e7e7652ac0 graftcopies: document why the function is useful at all
Martin von Zweigbergk <martinvonz@google.com>
parents: 44092
diff changeset
  1221
    experimental.copytrace=off.
06e7e7652ac0 graftcopies: document why the function is useful at all
Martin von Zweigbergk <martinvonz@google.com>
parents: 44092
diff changeset
  1222
06e7e7652ac0 graftcopies: document why the function is useful at all
Martin von Zweigbergk <martinvonz@google.com>
parents: 44092
diff changeset
  1223
    merge.update() will have already marked most copies, but it will only
06e7e7652ac0 graftcopies: document why the function is useful at all
Martin von Zweigbergk <martinvonz@google.com>
parents: 44092
diff changeset
  1224
    mark copies if it thinks the source files are related (see
06e7e7652ac0 graftcopies: document why the function is useful at all
Martin von Zweigbergk <martinvonz@google.com>
parents: 44092
diff changeset
  1225
    merge._related()). It will also not mark copies if the file wasn't modified
06e7e7652ac0 graftcopies: document why the function is useful at all
Martin von Zweigbergk <martinvonz@google.com>
parents: 44092
diff changeset
  1226
    on the local side. This function adds the copies that were "missed"
06e7e7652ac0 graftcopies: document why the function is useful at all
Martin von Zweigbergk <martinvonz@google.com>
parents: 44092
diff changeset
  1227
    by merge.update().
06e7e7652ac0 graftcopies: document why the function is useful at all
Martin von Zweigbergk <martinvonz@google.com>
parents: 44092
diff changeset
  1228
    """
44091
3df0bd706c40 graftcopies: use _filter() for filtering out invalid copies
Martin von Zweigbergk <martinvonz@google.com>
parents: 44090
diff changeset
  1229
    new_copies = pathcopies(base, ctx)
46469
f213b250fed0 copies: explicitly filter out existing file in graftcopies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46302
diff changeset
  1230
    parent = wctx.p1()
f213b250fed0 copies: explicitly filter out existing file in graftcopies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46302
diff changeset
  1231
    _filter(parent, wctx, new_copies)
46482
892eb7c5edaa copies: fix an incorrect comment in graftcopies() from recent D9802
Martin von Zweigbergk <martinvonz@google.com>
parents: 46480
diff changeset
  1232
    # Extra filtering to drop copy information for files that existed before
892eb7c5edaa copies: fix an incorrect comment in graftcopies() from recent D9802
Martin von Zweigbergk <martinvonz@google.com>
parents: 46480
diff changeset
  1233
    # the graft. This is to handle the case of grafting a rename onto a commit
892eb7c5edaa copies: fix an incorrect comment in graftcopies() from recent D9802
Martin von Zweigbergk <martinvonz@google.com>
parents: 46480
diff changeset
  1234
    # that already has the rename. Otherwise the presence of copy information
892eb7c5edaa copies: fix an incorrect comment in graftcopies() from recent D9802
Martin von Zweigbergk <martinvonz@google.com>
parents: 46480
diff changeset
  1235
    # would result in the creation of an empty commit where we would prefer to
892eb7c5edaa copies: fix an incorrect comment in graftcopies() from recent D9802
Martin von Zweigbergk <martinvonz@google.com>
parents: 46480
diff changeset
  1236
    # not create one.
46469
f213b250fed0 copies: explicitly filter out existing file in graftcopies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46302
diff changeset
  1237
    for dest, __ in list(new_copies.items()):
f213b250fed0 copies: explicitly filter out existing file in graftcopies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46302
diff changeset
  1238
        if dest in parent:
f213b250fed0 copies: explicitly filter out existing file in graftcopies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46302
diff changeset
  1239
            del new_copies[dest]
44091
3df0bd706c40 graftcopies: use _filter() for filtering out invalid copies
Martin von Zweigbergk <martinvonz@google.com>
parents: 44090
diff changeset
  1240
    for dst, src in pycompat.iteritems(new_copies):
3df0bd706c40 graftcopies: use _filter() for filtering out invalid copies
Martin von Zweigbergk <martinvonz@google.com>
parents: 44090
diff changeset
  1241
        wctx[dst].markcopied(src)