mercurial/copies.py
author Pierre-Yves David <pierre-yves.david@octobus.net>
Sun, 13 Dec 2020 20:16:34 +0100
changeset 46159 929054848d6c
parent 46158 1fcfff09cac5
child 46161 3a0c41336961
permissions -rw-r--r--
copies: properly match result during changeset centric copy tracing By filtering "during" the iteration we were excluding rename information that were not in the matched set but that file served as base information for the matched set. We now do all copy tracing matching at the end of the process to ensure we raise proper result. If we were aggregating information top down instead of bottom up we could do filtering during processing. However, we don't. Differential Revision: https://phab.mercurial-scm.org/D9585
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: 46113
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
34179
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
    11
import collections
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
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 _
46113
59fa3890d40a node: import symbols explicitly
Joerg Sonnenberger <joerg@bec.de>
parents: 46109
diff changeset
    15
from .node import (
59fa3890d40a node: import symbols explicitly
Joerg Sonnenberger <joerg@bec.de>
parents: 46109
diff changeset
    16
    nullid,
59fa3890d40a node: import symbols explicitly
Joerg Sonnenberger <joerg@bec.de>
parents: 46109
diff changeset
    17
    nullrev,
59fa3890d40a node: import symbols explicitly
Joerg Sonnenberger <joerg@bec.de>
parents: 46109
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 (
33867
252fb66ee5bb copies: use intersectmatchers() in non-merge p1 optimization
Yuya Nishihara <yuya@tcha.org>
parents: 33822
diff changeset
    21
    match as matchmod,
25924
cfc24c22454e copies: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25289
diff changeset
    22
    pathutil,
45962
a66568f20ddc copies: use the rust code for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45942
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: 43020
diff changeset
    29
from .utils import stringutil
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
    30
46057
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46036
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: 46036
diff changeset
    32
    flagutil,
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46036
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: 46036
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
45962
a66568f20ddc copies: use the rust code for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45942
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: 45942
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"""
42227
d1c2688eda80 copies: document cases in _chain()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42226
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
11ceb1b8fd74 copies: inline _chainandfilter() to prepare for next patch
Martin von Zweigbergk <martinvonz@google.com>
parents: 42592
diff changeset
    44
    # in the following table (not including trivial cases). For example, case 2
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
42227
d1c2688eda80 copies: document cases in _chain()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42226
diff changeset
    46
    # then was renamed between 'mid' and 'dst'.
d1c2688eda80 copies: document cases in _chain()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42226
diff changeset
    47
    #
d1c2688eda80 copies: document cases in _chain()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42226
diff changeset
    48
    # case src mid dst result
d1c2688eda80 copies: document cases in _chain()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42226
diff changeset
    49
    #   1   x   y   -    -
d1c2688eda80 copies: document cases in _chain()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42226
diff changeset
    50
    #   2   x   y   y   x->y
d1c2688eda80 copies: document cases in _chain()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42226
diff changeset
    51
    #   3   x   y   x    -
d1c2688eda80 copies: document cases in _chain()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42226
diff changeset
    52
    #   4   x   y   z   x->z
d1c2688eda80 copies: document cases in _chain()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42226
diff changeset
    53
    #   5   -   x   y    -
d1c2688eda80 copies: document cases in _chain()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42226
diff changeset
    54
    #   6   x   x   y   x->y
42373
f3d06d37e194 copies: split up _chain() in naive chaining and filtering steps
Martin von Zweigbergk <martinvonz@google.com>
parents: 42344
diff changeset
    55
    #
f3d06d37e194 copies: split up _chain() in naive chaining and filtering steps
Martin von Zweigbergk <martinvonz@google.com>
parents: 42344
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: 42344
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: 42344
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: 42344
diff changeset
    59
    # Cases 1, 3, and 5 are then removed by _filter().
42227
d1c2688eda80 copies: document cases in _chain()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42226
diff changeset
    60
42373
f3d06d37e194 copies: split up _chain() in naive chaining and filtering steps
Martin von Zweigbergk <martinvonz@google.com>
parents: 42344
diff changeset
    61
    for k, v in list(t.items()):
f3d06d37e194 copies: split up _chain() in naive chaining and filtering steps
Martin von Zweigbergk <martinvonz@google.com>
parents: 42344
diff changeset
    62
        # remove copies from files that didn't exist
f3d06d37e194 copies: split up _chain() in naive chaining and filtering steps
Martin von Zweigbergk <martinvonz@google.com>
parents: 42344
diff changeset
    63
        if v not in src:
f3d06d37e194 copies: split up _chain() in naive chaining and filtering steps
Martin von Zweigbergk <martinvonz@google.com>
parents: 42344
diff changeset
    64
            del t[k]
f3d06d37e194 copies: split up _chain() in naive chaining and filtering steps
Martin von Zweigbergk <martinvonz@google.com>
parents: 42344
diff changeset
    65
        # remove criss-crossed copies
f3d06d37e194 copies: split up _chain() in naive chaining and filtering steps
Martin von Zweigbergk <martinvonz@google.com>
parents: 42344
diff changeset
    66
        elif k in src and v in dst:
f3d06d37e194 copies: split up _chain() in naive chaining and filtering steps
Martin von Zweigbergk <martinvonz@google.com>
parents: 42344
diff changeset
    67
            del t[k]
f3d06d37e194 copies: split up _chain() in naive chaining and filtering steps
Martin von Zweigbergk <martinvonz@google.com>
parents: 42344
diff changeset
    68
        # remove copies to files that were then removed
f3d06d37e194 copies: split up _chain() in naive chaining and filtering steps
Martin von Zweigbergk <martinvonz@google.com>
parents: 42344
diff changeset
    69
        elif k not in dst:
f3d06d37e194 copies: split up _chain() in naive chaining and filtering steps
Martin von Zweigbergk <martinvonz@google.com>
parents: 42344
diff changeset
    70
            del t[k]
f3d06d37e194 copies: split up _chain() in naive chaining and filtering steps
Martin von Zweigbergk <martinvonz@google.com>
parents: 42344
diff changeset
    71
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
    72
43784
995066c41bb2 copies: expand `_chain` variable name to make the function easier to read
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43783
diff changeset
    73
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: 43783
diff changeset
    74
    """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: 43783
diff changeset
    75
    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: 43783
diff changeset
    76
    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: 43783
diff changeset
    77
        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: 43783
diff changeset
    78
    return result
15775
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
    79
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
    80
43199
069cbbb53cdf copies: drop the findlimit logic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43198
diff changeset
    81
def _tracefile(fctx, am, basemf):
35421
9cf37d111acb copies: consistently use """ for docstrings
Martin von Zweigbergk <martinvonz@google.com>
parents: 35420
diff changeset
    82
    """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
    83
    manifest am
c16fe77e340a pathcopies: give up any optimization based on `introrev`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43148
diff changeset
    84
c16fe77e340a pathcopies: give up any optimization based on `introrev`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43148
diff changeset
    85
    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
    86
    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
    87
    disabling that feature."""
15775
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
    88
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
    89
    for f in fctx.ancestors():
42548
4ebbd7c4a3c5 copies: return only path from _tracefile() since that's all caller needs
Martin von Zweigbergk <martinvonz@google.com>
parents: 42520
diff changeset
    90
        path = f.path()
4ebbd7c4a3c5 copies: return only path from _tracefile() since that's all caller needs
Martin von Zweigbergk <martinvonz@google.com>
parents: 42520
diff changeset
    91
        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: 42520
diff changeset
    92
            return path
42595
819712deac69 copies: follow copies across merge base without source file (issue6163)
Martin von Zweigbergk <martinvonz@google.com>
parents: 42594
diff changeset
    93
        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
    94
            return path
15775
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
    95
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
    96
41752
012f695546aa copies: respect narrowmatcher in "parent -> working dir" case
Martin von Zweigbergk <martinvonz@google.com>
parents: 41724
diff changeset
    97
def _dirstatecopies(repo, match=None):
012f695546aa copies: respect narrowmatcher in "parent -> working dir" case
Martin von Zweigbergk <martinvonz@google.com>
parents: 41724
diff changeset
    98
    ds = repo.dirstate
15775
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
    99
    c = ds.copies().copy()
34348
1a5abc45e2fa py3: explicitly convert dict.keys() and dict.items() into a list
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34311
diff changeset
   100
    for k in list(c):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   101
        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
   102
            del c[k]
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
   103
    return c
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
   104
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
   105
24782
4906dc0e038c copies: add matcher parameter to copy logic
Durham Goode <durham@fb.com>
parents: 24625
diff changeset
   106
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
   107
    """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
   108
    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
   109
    files _forwardcopies is about to process.
d7d08337b3f6 copy: move _forwardcopies file logic to a function
Durham Goode <durham@fb.com>
parents: 24010
diff changeset
   110
    """
24782
4906dc0e038c copies: add matcher parameter to copy logic
Durham Goode <durham@fb.com>
parents: 24625
diff changeset
   111
    ma = a.manifest()
4906dc0e038c copies: add matcher parameter to copy logic
Durham Goode <durham@fb.com>
parents: 24625
diff changeset
   112
    mb = b.manifest()
31256
5a909a8098a1 copies: remove use of manifest.matches
Durham Goode <durham@fb.com>
parents: 30581
diff changeset
   113
    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
   114
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
   115
42115
27475ae67676 copies: extract function for deciding whether to use changeset-centric algos
Martin von Zweigbergk <martinvonz@google.com>
parents: 41936
diff changeset
   116
def usechangesetcentricalgo(repo):
27475ae67676 copies: extract function for deciding whether to use changeset-centric algos
Martin von Zweigbergk <martinvonz@google.com>
parents: 41936
diff changeset
   117
    """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
   118
    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
   119
        return True
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   120
    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
   121
    changesetsource = (b'changeset-only', b'compatibility')
43020
f3bcae1e9e23 copies: expand the logic of usechangesetcentricalgo
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 42707
diff changeset
   122
    return readfrom in changesetsource
42115
27475ae67676 copies: extract function for deciding whether to use changeset-centric algos
Martin von Zweigbergk <martinvonz@google.com>
parents: 41936
diff changeset
   123
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
   124
42595
819712deac69 copies: follow copies across merge base without source file (issue6163)
Martin von Zweigbergk <martinvonz@google.com>
parents: 42594
diff changeset
   125
def _committedforwardcopies(a, b, base, match):
35422
8801cdcea01f copies: extract method for getting non-wdir forward copies
Martin von Zweigbergk <martinvonz@google.com>
parents: 35421
diff changeset
   126
    """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
   127
    # 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
   128
    # one-side-only changeset, but not further back than that
40057
25b2868206e2 copies: add a devel debug mode to trace what copy tracing does
Boris Feld <boris.feld@octobus.net>
parents: 39966
diff changeset
   129
    repo = a._repo
41756
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
   130
42115
27475ae67676 copies: extract function for deciding whether to use changeset-centric algos
Martin von Zweigbergk <martinvonz@google.com>
parents: 41936
diff changeset
   131
    if usechangesetcentricalgo(repo):
41756
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
   132
        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: 41754
diff changeset
   133
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   134
    debug = repo.ui.debugflag and repo.ui.configbool(b'devel', b'debug.copies')
40057
25b2868206e2 copies: add a devel debug mode to trace what copy tracing does
Boris Feld <boris.feld@octobus.net>
parents: 39966
diff changeset
   135
    dbg = repo.ui.debug
25b2868206e2 copies: add a devel debug mode to trace what copy tracing does
Boris Feld <boris.feld@octobus.net>
parents: 39966
diff changeset
   136
    if debug:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   137
        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
   138
    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
   139
    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
   140
15775
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
   141
    # find where new files came from
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
   142
    # 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
   143
    # 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
   144
    cm = {}
28000
d4247c306d82 copies: optimize forward copy detection logic for rebases
Durham Goode <durham@fb.com>
parents: 27876
diff changeset
   145
d4247c306d82 copies: optimize forward copy detection logic for rebases
Durham Goode <durham@fb.com>
parents: 27876
diff changeset
   146
    # 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
   147
    # 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
   148
    # 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
   149
    # 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
   150
    # 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
   151
    # this comparison.
d4247c306d82 copies: optimize forward copy detection logic for rebases
Durham Goode <durham@fb.com>
parents: 27876
diff changeset
   152
    forwardmissingmatch = match
46113
59fa3890d40a node: import symbols explicitly
Joerg Sonnenberger <joerg@bec.de>
parents: 46109
diff changeset
   153
    if b.p1() == a and b.p2().node() == nullid:
41936
a791623458ef copies: remove dependency on scmutil by directly using match.exact()
Martin von Zweigbergk <martinvonz@google.com>
parents: 41932
diff changeset
   154
        filesmatcher = matchmod.exact(b.files())
33867
252fb66ee5bb copies: use intersectmatchers() in non-merge p1 optimization
Yuya Nishihara <yuya@tcha.org>
parents: 33822
diff changeset
   155
        forwardmissingmatch = matchmod.intersectmatchers(match, filesmatcher)
28000
d4247c306d82 copies: optimize forward copy detection logic for rebases
Durham Goode <durham@fb.com>
parents: 27876
diff changeset
   156
    missing = _computeforwardmissing(a, b, match=forwardmissingmatch)
d4247c306d82 copies: optimize forward copy detection logic for rebases
Durham Goode <durham@fb.com>
parents: 27876
diff changeset
   157
23980
c1ce5442453f _adjustlinkrev: reuse ancestors set during rename detection (issue4514)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23139
diff changeset
   158
    ancestrycontext = a._repo.changelog.ancestors([b.rev()], inclusive=True)
40057
25b2868206e2 copies: add a devel debug mode to trace what copy tracing does
Boris Feld <boris.feld@octobus.net>
parents: 39966
diff changeset
   159
25b2868206e2 copies: add a devel debug mode to trace what copy tracing does
Boris Feld <boris.feld@octobus.net>
parents: 39966
diff changeset
   160
    if debug:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   161
        dbg(b'debug.copies:      missing files to search: %d\n' % len(missing))
40057
25b2868206e2 copies: add a devel debug mode to trace what copy tracing does
Boris Feld <boris.feld@octobus.net>
parents: 39966
diff changeset
   162
42210
390ec72b8ea4 copies: process files in deterministic order for stable tests
Martin von Zweigbergk <martinvonz@google.com>
parents: 42169
diff changeset
   163
    for f in sorted(missing):
40057
25b2868206e2 copies: add a devel debug mode to trace what copy tracing does
Boris Feld <boris.feld@octobus.net>
parents: 39966
diff changeset
   164
        if debug:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   165
            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
   166
        fctx = b[f]
c1ce5442453f _adjustlinkrev: reuse ancestors set during rename detection (issue4514)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23139
diff changeset
   167
        fctx._ancestrycontext = ancestrycontext
40057
25b2868206e2 copies: add a devel debug mode to trace what copy tracing does
Boris Feld <boris.feld@octobus.net>
parents: 39966
diff changeset
   168
40058
cf01616f8d96 copies: add time information to the debug information
Boris Feld <boris.feld@octobus.net>
parents: 40057
diff changeset
   169
        if debug:
cf01616f8d96 copies: add time information to the debug information
Boris Feld <boris.feld@octobus.net>
parents: 40057
diff changeset
   170
            start = util.timer()
43199
069cbbb53cdf copies: drop the findlimit logic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43198
diff changeset
   171
        opath = _tracefile(fctx, am, basemf)
42548
4ebbd7c4a3c5 copies: return only path from _tracefile() since that's all caller needs
Martin von Zweigbergk <martinvonz@google.com>
parents: 42520
diff changeset
   172
        if opath:
40057
25b2868206e2 copies: add a devel debug mode to trace what copy tracing does
Boris Feld <boris.feld@octobus.net>
parents: 39966
diff changeset
   173
            if debug:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   174
                dbg(b'debug.copies:          rename of: %s\n' % opath)
42548
4ebbd7c4a3c5 copies: return only path from _tracefile() since that's all caller needs
Martin von Zweigbergk <martinvonz@google.com>
parents: 42520
diff changeset
   175
            cm[f] = opath
40058
cf01616f8d96 copies: add time information to the debug information
Boris Feld <boris.feld@octobus.net>
parents: 40057
diff changeset
   176
        if debug:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
   177
            dbg(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   178
                b'debug.copies:          time: %f seconds\n'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
   179
                % (util.timer() - start)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
   180
            )
35422
8801cdcea01f copies: extract method for getting non-wdir forward copies
Martin von Zweigbergk <martinvonz@google.com>
parents: 35421
diff changeset
   181
    return cm
8801cdcea01f copies: extract method for getting non-wdir forward copies
Martin von Zweigbergk <martinvonz@google.com>
parents: 35421
diff changeset
   182
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
   183
46057
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46036
diff changeset
   184
def _revinfo_getter(repo, match):
45640
2693659c2b34 copies: directly pass a changes object to the copy tracing code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45639
diff changeset
   185
    """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
   186
b8d60845fa5d copies: extract data extraction into a `revinfo` function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43254
diff changeset
   187
    * 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
   188
    * p2: revision number of first parent
45640
2693659c2b34 copies: directly pass a changes object to the copy tracing code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45639
diff changeset
   189
    * 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
   190
    """
b8d60845fa5d copies: extract data extraction into a `revinfo` function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43254
diff changeset
   191
    cl = repo.changelog
b8d60845fa5d copies: extract data extraction into a `revinfo` function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43254
diff changeset
   192
    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
   193
    flags = cl.flags
f877b3628015 copies: return None instead of ChangingFiles when relevant
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45670
diff changeset
   194
f877b3628015 copies: return None instead of ChangingFiles when relevant
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45670
diff changeset
   195
    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
   196
45638
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45637
diff changeset
   197
    changelogrevision = cl.changelogrevision
43257
675c776fbcd1 sidedatacopies: directly fetch copies information from sidedata
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43256
diff changeset
   198
46159
929054848d6c copies: properly match result during changeset centric copy tracing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46158
diff changeset
   199
    if rustmod is not None:
46057
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46036
diff changeset
   200
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46036
diff changeset
   201
        def revinfo(rev):
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46036
diff changeset
   202
            p1, p2 = parents(rev)
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46036
diff changeset
   203
            if flags(rev) & HASCOPIESINFO:
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46036
diff changeset
   204
                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: 46036
diff changeset
   205
            else:
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46036
diff changeset
   206
                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
   207
            return (p1, p2, raw)
46057
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46036
diff changeset
   208
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46036
diff changeset
   209
    else:
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46036
diff changeset
   210
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46036
diff changeset
   211
        def revinfo(rev):
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46036
diff changeset
   212
            p1, p2 = parents(rev)
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46036
diff changeset
   213
            if flags(rev) & HASCOPIESINFO:
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46036
diff changeset
   214
                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
   215
            else:
a132aa5979ec copies: no longer cache the ChangedFiles during copy tracing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   216
                changes = None
a132aa5979ec copies: no longer cache the ChangedFiles during copy tracing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
   217
            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
   218
b8d60845fa5d copies: extract data extraction into a `revinfo` function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43254
diff changeset
   219
    return revinfo
b8d60845fa5d copies: extract data extraction into a `revinfo` function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43254
diff changeset
   220
b8d60845fa5d copies: extract data extraction into a `revinfo` function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43254
diff changeset
   221
45892
06b64fabf91c copies: cache the ancestor checking call when tracing copy
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45798
diff changeset
   222
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: 45798
diff changeset
   223
    """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: 45798
diff changeset
   224
    cache = {}
06b64fabf91c copies: cache the ancestor checking call when tracing copy
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45798
diff changeset
   225
06b64fabf91c copies: cache the ancestor checking call when tracing copy
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45798
diff changeset
   226
    def _is_ancestor(anc, desc):
06b64fabf91c copies: cache the ancestor checking call when tracing copy
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45798
diff changeset
   227
        if anc > desc:
06b64fabf91c copies: cache the ancestor checking call when tracing copy
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45798
diff changeset
   228
            return False
06b64fabf91c copies: cache the ancestor checking call when tracing copy
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45798
diff changeset
   229
        elif anc == desc:
06b64fabf91c copies: cache the ancestor checking call when tracing copy
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45798
diff changeset
   230
            return True
06b64fabf91c copies: cache the ancestor checking call when tracing copy
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45798
diff changeset
   231
        key = (anc, desc)
06b64fabf91c copies: cache the ancestor checking call when tracing copy
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45798
diff changeset
   232
        ret = cache.get(key)
06b64fabf91c copies: cache the ancestor checking call when tracing copy
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45798
diff changeset
   233
        if ret is None:
06b64fabf91c copies: cache the ancestor checking call when tracing copy
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45798
diff changeset
   234
            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: 45798
diff changeset
   235
        return ret
06b64fabf91c copies: cache the ancestor checking call when tracing copy
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45798
diff changeset
   236
06b64fabf91c copies: cache the ancestor checking call when tracing copy
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45798
diff changeset
   237
    return _is_ancestor
06b64fabf91c copies: cache the ancestor checking call when tracing copy
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45798
diff changeset
   238
06b64fabf91c copies: cache the ancestor checking call when tracing copy
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45798
diff changeset
   239
41756
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
   240
def _changesetforwardcopies(a, b, match):
46113
59fa3890d40a node: import symbols explicitly
Joerg Sonnenberger <joerg@bec.de>
parents: 46109
diff changeset
   241
    if a.rev() in (nullrev, b.rev()):
41756
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
   242
        return {}
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
   243
43256
00de32aa834e copies: use an unfiltered repository for the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43255
diff changeset
   244
    repo = a.repo().unfiltered()
41756
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
   245
    children = {}
43255
b8d60845fa5d copies: extract data extraction into a `revinfo` function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43254
diff changeset
   246
41756
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
   247
    cl = repo.changelog
45972
8b99c473aae2 copies-rust: move is_ancestor caching within the rust code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45962
diff changeset
   248
    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
   249
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   250
    # 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
   251
    # 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
   252
    #
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   253
    #
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   254
    # 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
   255
    # ::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
   256
    # 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
   257
    # 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
   258
    #
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   259
    # [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
   260
    # 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
   261
    # 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
   262
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   263
    parents = cl._uncheckedparentrevs
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   264
    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
   265
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   266
    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
   267
    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
   268
    roots = set()
46149
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   269
    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
   270
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   271
    # 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
   272
    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
   273
        ps = parents(r)
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   274
        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
   275
            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
   276
        else:
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   277
            p1, p2 = ps
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   278
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   279
            # 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
   280
            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
   281
                roots.add(p1)
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   282
            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
   283
                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
   284
    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
   285
        # 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
   286
        return {}
46149
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   287
    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
   288
        # 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
   289
        # 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
   290
        roots = list(roots)
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   291
        m = min(roots)
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   292
        h = [b.rev()]
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   293
        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
   294
        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
   295
        revs = [r for r in revs if r in roots_to_head]
45637
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
   296
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
   297
    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
   298
        # 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
   299
        # 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
   300
        # 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
   301
        # 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
   302
        #
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   303
        # 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
   304
        # 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
   305
        # 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
   306
        # processed.
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   307
        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
   308
        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
   309
            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
   310
                if p == nullrev:
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   311
                    continue
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   312
                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
   313
                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
   314
                    children_count[p] += 1
46057
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46036
diff changeset
   315
        revinfo = _revinfo_getter(repo, match)
45637
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
   316
        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
   317
            revs, children_count, b.rev(), revinfo, match, isancestor
45637
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
   318
        )
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
   319
    else:
46149
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   320
        # 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
   321
        # 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
   322
        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
   323
        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
   324
            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
   325
                if p == nullrev:
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   326
                    continue
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   327
                children[r] = []
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   328
                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
   329
                    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
   330
        x = revs.pop()
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   331
        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
   332
        revs.extend(roots)
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   333
        revs.sort()
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   334
45638
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45637
diff changeset
   335
        revinfo = _revinfo_getter_extra(repo)
45637
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
   336
        return _combine_changeset_copies_extra(
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
   337
            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: 45624
diff changeset
   338
        )
43786
421ea5772039 copies: split the combination of the copies mapping in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43785
diff changeset
   339
421ea5772039 copies: split the combination of the copies mapping in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43785
diff changeset
   340
45624
fb000408bca5 copies: rename some function to the new naming scheme
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44994
diff changeset
   341
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
   342
    revs, children_count, targetrev, revinfo, match, isancestor
44758
45f3f35cefe7 copies: fix the changeset based algorithm regarding merge
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44276
diff changeset
   343
):
43786
421ea5772039 copies: split the combination of the copies mapping in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43785
diff changeset
   344
    """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: 43785
diff changeset
   345
421ea5772039 copies: split the combination of the copies mapping in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43785
diff changeset
   346
    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
   347
    children_count: a {parent: <number-of-relevant-children>} mapping.
43786
421ea5772039 copies: split the combination of the copies mapping in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43785
diff changeset
   348
    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: 43785
diff changeset
   349
    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: 43785
diff changeset
   350
    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: 43785
diff changeset
   351
421ea5772039 copies: split the combination of the copies mapping in its own function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43785
diff changeset
   352
    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: 43785
diff changeset
   353
    """
45962
a66568f20ddc copies: use the rust code for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45942
diff changeset
   354
a66568f20ddc copies: use the rust code for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45942
diff changeset
   355
    alwaysmatch = match.always()
a66568f20ddc copies: use the rust code for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45942
diff changeset
   356
46159
929054848d6c copies: properly match result during changeset centric copy tracing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46158
diff changeset
   357
    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
   358
        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
   359
            list(revs), children_count, targetrev, revinfo, isancestor
45962
a66568f20ddc copies: use the rust code for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45942
diff changeset
   360
        )
46158
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   361
    else:
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   362
        isancestor = cached_is_ancestor(isancestor)
46148
70a9eb899637 copies: document the current algorithm step
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46113
diff changeset
   363
46158
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   364
        all_copies = {}
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   365
        # 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
   366
        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
   367
            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
   368
            current_copies = None
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   369
            # 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
   370
            # 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
   371
            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
   372
                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
   373
                    continue
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   374
                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
   375
                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
   376
                    continue
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   377
                remaining_children -= 1
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   378
                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
   379
                if remaining_children:
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   380
                    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
   381
                else:
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   382
                    copies = all_copies.pop(parent_rev, None)
46148
70a9eb899637 copies: document the current algorithm step
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46113
diff changeset
   383
46158
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   384
                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
   385
                    # this is a root
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   386
                    copies = {}
46149
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   387
46158
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   388
                newcopies = copies
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   389
                # 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
   390
                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
   391
                    childcopies = {}
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   392
                    if parent == 1:
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   393
                        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
   394
                    elif parent == 2:
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   395
                        childcopies = changes.copied_from_p2
46148
70a9eb899637 copies: document the current algorithm step
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46113
diff changeset
   396
46158
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   397
                    if childcopies:
46149
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
   398
                        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
   399
                        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
   400
                            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
   401
                            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
   402
                                source = prev[1]
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   403
                            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
   404
                        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
   405
                    if changes.removed:
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   406
                        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
   407
                            newcopies = copies.copy()
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   408
                        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
   409
                            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
   410
                                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
   411
                                    # 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
   412
                                    # 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
   413
                                    # could be avoided.
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   414
                                    newcopies = copies.copy()
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   415
                                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
   416
                # 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
   417
                # 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
   418
                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
   419
                    current_copies = newcopies
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   420
                elif current_copies is newcopies:
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   421
                    # nothing to merge:
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   422
                    pass
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   423
                else:
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   424
                    # 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
   425
                    # 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
   426
                    #
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   427
                    # 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
   428
                    # 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
   429
                    # 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
   430
                    # 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
   431
                    assert parent == 2
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   432
                    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
   433
                        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
   434
                    )
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   435
            all_copies[current_rev] = current_copies
46148
70a9eb899637 copies: document the current algorithm step
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46113
diff changeset
   436
46158
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   437
        # 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
   438
        final_copies = {}
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
   439
        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
   440
            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
   441
                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
   442
    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
   443
        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
   444
            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
   445
                del final_copies[filename]
44758
45f3f35cefe7 copies: fix the changeset based algorithm regarding merge
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44276
diff changeset
   446
    return final_copies
45f3f35cefe7 copies: fix the changeset based algorithm regarding merge
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44276
diff changeset
   447
45f3f35cefe7 copies: fix the changeset based algorithm regarding merge
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44276
diff changeset
   448
45640
2693659c2b34 copies: directly pass a changes object to the copy tracing code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45639
diff changeset
   449
def _merge_copies_dict(minor, major, isancestor, changes):
44758
45f3f35cefe7 copies: fix the changeset based algorithm regarding merge
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44276
diff changeset
   450
    """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: 44276
diff changeset
   451
45f3f35cefe7 copies: fix the changeset based algorithm regarding merge
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44276
diff changeset
   452
    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: 44276
diff changeset
   453
45f3f35cefe7 copies: fix the changeset based algorithm regarding merge
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44276
diff changeset
   454
    - `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: 44276
diff changeset
   455
                                        ancestors of `high_rev`,
45f3f35cefe7 copies: fix the changeset based algorithm regarding merge
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44276
diff changeset
   456
45f3f35cefe7 copies: fix the changeset based algorithm regarding merge
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44276
diff changeset
   457
    - `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: 44276
diff changeset
   458
                        current revision,
45986
f9f8d8aa9a92 copies: clarify the return of _merge_copies_dict
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45985
diff changeset
   459
f9f8d8aa9a92 copies: clarify the return of _merge_copies_dict
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45985
diff changeset
   460
    return the resulting dict (in practice, the "minor" object, updated)
44758
45f3f35cefe7 copies: fix the changeset based algorithm regarding merge
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44276
diff changeset
   461
    """
45f3f35cefe7 copies: fix the changeset based algorithm regarding merge
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44276
diff changeset
   462
    for dest, value in major.items():
45f3f35cefe7 copies: fix the changeset based algorithm regarding merge
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44276
diff changeset
   463
        other = minor.get(dest)
45f3f35cefe7 copies: fix the changeset based algorithm regarding merge
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44276
diff changeset
   464
        if other is None:
45f3f35cefe7 copies: fix the changeset based algorithm regarding merge
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44276
diff changeset
   465
            minor[dest] = value
45f3f35cefe7 copies: fix the changeset based algorithm regarding merge
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44276
diff changeset
   466
        else:
45f3f35cefe7 copies: fix the changeset based algorithm regarding merge
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44276
diff changeset
   467
            new_tt = value[0]
45f3f35cefe7 copies: fix the changeset based algorithm regarding merge
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44276
diff changeset
   468
            other_tt = other[0]
45f3f35cefe7 copies: fix the changeset based algorithm regarding merge
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44276
diff changeset
   469
            if value[1] == other[1]:
45f3f35cefe7 copies: fix the changeset based algorithm regarding merge
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44276
diff changeset
   470
                continue
45f3f35cefe7 copies: fix the changeset based algorithm regarding merge
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44276
diff changeset
   471
            # content from "major" wins, unless it is older
45f3f35cefe7 copies: fix the changeset based algorithm regarding merge
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44276
diff changeset
   472
            # than the branch point or there is a merge
45670
a8fb29b05f92 salvaged: properly deal with salvaged file during copy tracing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45640
diff changeset
   473
            if new_tt == other_tt:
a8fb29b05f92 salvaged: properly deal with salvaged file during copy tracing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45640
diff changeset
   474
                minor[dest] = value
45672
f877b3628015 copies: return None instead of ChangingFiles when relevant
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45670
diff changeset
   475
            elif (
f877b3628015 copies: return None instead of ChangingFiles when relevant
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45670
diff changeset
   476
                changes is not None
f877b3628015 copies: return None instead of ChangingFiles when relevant
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45670
diff changeset
   477
                and value[1] is None
f877b3628015 copies: return None instead of ChangingFiles when relevant
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45670
diff changeset
   478
                and dest in changes.salvaged
f877b3628015 copies: return None instead of ChangingFiles when relevant
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45670
diff changeset
   479
            ):
45670
a8fb29b05f92 salvaged: properly deal with salvaged file during copy tracing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45640
diff changeset
   480
                pass
45672
f877b3628015 copies: return None instead of ChangingFiles when relevant
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45670
diff changeset
   481
            elif (
f877b3628015 copies: return None instead of ChangingFiles when relevant
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45670
diff changeset
   482
                changes is not None
f877b3628015 copies: return None instead of ChangingFiles when relevant
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45670
diff changeset
   483
                and other[1] is None
f877b3628015 copies: return None instead of ChangingFiles when relevant
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45670
diff changeset
   484
                and dest in changes.salvaged
f877b3628015 copies: return None instead of ChangingFiles when relevant
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45670
diff changeset
   485
            ):
45670
a8fb29b05f92 salvaged: properly deal with salvaged file during copy tracing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45640
diff changeset
   486
                minor[dest] = value
45673
7990e7d957b0 copies: move `merged` testing sooner
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45672
diff changeset
   487
            elif changes is not None and dest in changes.merged:
45670
a8fb29b05f92 salvaged: properly deal with salvaged file during copy tracing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45640
diff changeset
   488
                minor[dest] = value
45673
7990e7d957b0 copies: move `merged` testing sooner
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45672
diff changeset
   489
            elif not isancestor(new_tt, other_tt):
45798
ff7e0ca666e8 copies: make sure deleted copy info do not overwriting unrelated ones
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45673
diff changeset
   490
                if value[1] is not None:
ff7e0ca666e8 copies: make sure deleted copy info do not overwriting unrelated ones
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45673
diff changeset
   491
                    minor[dest] = value
ff7e0ca666e8 copies: make sure deleted copy info do not overwriting unrelated ones
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45673
diff changeset
   492
                elif isancestor(other_tt, new_tt):
ff7e0ca666e8 copies: make sure deleted copy info do not overwriting unrelated ones
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45673
diff changeset
   493
                    minor[dest] = value
45986
f9f8d8aa9a92 copies: clarify the return of _merge_copies_dict
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45985
diff changeset
   494
    return minor
41756
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
   495
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
   496
45638
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45637
diff changeset
   497
def _revinfo_getter_extra(repo):
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45637
diff changeset
   498
    """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: 45637
diff changeset
   499
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45637
diff changeset
   500
    * p1: revision number of first parent
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45637
diff changeset
   501
    * p2: revision number of first parent
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45637
diff changeset
   502
    * p1copies: mapping of copies from p1
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45637
diff changeset
   503
    * p2copies: mapping of copies from p2
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45637
diff changeset
   504
    * removed: a list of removed files
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45637
diff changeset
   505
    * 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: 45637
diff changeset
   506
    """
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45637
diff changeset
   507
    cl = repo.changelog
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45637
diff changeset
   508
    parents = cl.parentrevs
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45637
diff changeset
   509
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45637
diff changeset
   510
    def get_ismerged(rev):
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45637
diff changeset
   511
        ctx = repo[rev]
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45637
diff changeset
   512
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45637
diff changeset
   513
        def ismerged(path):
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45637
diff changeset
   514
            if path not in ctx.files():
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45637
diff changeset
   515
                return False
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45637
diff changeset
   516
            fctx = ctx[path]
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45637
diff changeset
   517
            parents = fctx._filelog.parents(fctx._filenode)
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45637
diff changeset
   518
            nb_parents = 0
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45637
diff changeset
   519
            for n in parents:
46113
59fa3890d40a node: import symbols explicitly
Joerg Sonnenberger <joerg@bec.de>
parents: 46109
diff changeset
   520
                if n != nullid:
45638
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45637
diff changeset
   521
                    nb_parents += 1
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45637
diff changeset
   522
            return nb_parents >= 2
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45637
diff changeset
   523
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45637
diff changeset
   524
        return ismerged
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45637
diff changeset
   525
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45637
diff changeset
   526
    def revinfo(rev):
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45637
diff changeset
   527
        p1, p2 = parents(rev)
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45637
diff changeset
   528
        ctx = repo[rev]
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45637
diff changeset
   529
        p1copies, p2copies = ctx._copies
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45637
diff changeset
   530
        removed = ctx.filesremoved()
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45637
diff changeset
   531
        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: 45637
diff changeset
   532
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45637
diff changeset
   533
    return revinfo
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45637
diff changeset
   534
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45637
diff changeset
   535
45637
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
   536
def _combine_changeset_copies_extra(
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
   537
    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: 45624
diff changeset
   538
):
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
   539
    """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: 45624
diff changeset
   540
    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: 45624
diff changeset
   541
    all_copies = {}
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
   542
    alwaysmatch = match.always()
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
   543
    for r in revs:
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
   544
        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: 45624
diff changeset
   545
        if copies is None:
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
   546
            # this is a root
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
   547
            copies = {}
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
   548
        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: 45624
diff changeset
   549
            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: 45624
diff changeset
   550
            if r == p1:
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
   551
                parent = 1
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
   552
                childcopies = p1copies
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
   553
            else:
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
   554
                assert r == p2
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
   555
                parent = 2
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
   556
                childcopies = p2copies
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
   557
            if not alwaysmatch:
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
   558
                childcopies = {
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
   559
                    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: 45624
diff changeset
   560
                }
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
   561
            newcopies = copies
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
   562
            if childcopies:
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
   563
                newcopies = copies.copy()
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
   564
                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: 45624
diff changeset
   565
                    prev = copies.get(source)
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
   566
                    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: 45624
diff changeset
   567
                        source = prev[1]
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
   568
                    newcopies[dest] = (c, source)
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
   569
                assert newcopies is not copies
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
   570
            for f in removed:
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
   571
                if f in newcopies:
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
   572
                    if newcopies is copies:
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
   573
                        # 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: 45624
diff changeset
   574
                        # 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: 45624
diff changeset
   575
                        # could be avoided.
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
   576
                        newcopies = copies.copy()
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
   577
                    newcopies[f] = (c, None)
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
   578
            othercopies = all_copies.get(c)
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
   579
            if othercopies is None:
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
   580
                all_copies[c] = newcopies
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
   581
            else:
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
   582
                # 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: 45624
diff changeset
   583
                # work with the other.
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
   584
                #
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
   585
                # 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: 45624
diff changeset
   586
                # 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: 45624
diff changeset
   587
                # 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: 45624
diff changeset
   588
                # potential filelog related behavior.
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
   589
                if parent == 1:
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
   590
                    _merge_copies_dict_extra(
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
   591
                        othercopies, newcopies, isancestor, ismerged
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
   592
                    )
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
   593
                else:
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
   594
                    _merge_copies_dict_extra(
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
   595
                        newcopies, othercopies, isancestor, ismerged
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
   596
                    )
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
   597
                    all_copies[c] = newcopies
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
   598
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
   599
    final_copies = {}
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
   600
    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: 45624
diff changeset
   601
        if source is not None:
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
   602
            final_copies[dest] = source
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
   603
    return final_copies
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
   604
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
   605
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
   606
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: 45624
diff changeset
   607
    """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: 45624
diff changeset
   608
    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: 45624
diff changeset
   609
    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: 45624
diff changeset
   610
        other = minor.get(dest)
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
   611
        if other is None:
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
   612
            minor[dest] = value
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
   613
        else:
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
   614
            new_tt = value[0]
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
   615
            other_tt = other[0]
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
   616
            if value[1] == other[1]:
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
   617
                continue
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
   618
            # 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: 45624
diff changeset
   619
            # 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: 45624
diff changeset
   620
            if (
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
   621
                new_tt == other_tt
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
   622
                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: 45624
diff changeset
   623
                or ismerged(dest)
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
   624
            ):
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
   625
                minor[dest] = value
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
   626
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
   627
42595
819712deac69 copies: follow copies across merge base without source file (issue6163)
Martin von Zweigbergk <martinvonz@google.com>
parents: 42594
diff changeset
   628
def _forwardcopies(a, b, base=None, match=None):
35422
8801cdcea01f copies: extract method for getting non-wdir forward copies
Martin von Zweigbergk <martinvonz@google.com>
parents: 35421
diff changeset
   629
    """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: 35421
diff changeset
   630
42595
819712deac69 copies: follow copies across merge base without source file (issue6163)
Martin von Zweigbergk <martinvonz@google.com>
parents: 42594
diff changeset
   631
    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
   632
        base = a
40448
873f3682c8af narrow: make copies.pathcopies() filter with narrowspec again
Martin von Zweigbergk <martinvonz@google.com>
parents: 40076
diff changeset
   633
    match = a.repo().narrowmatch(match)
35422
8801cdcea01f copies: extract method for getting non-wdir forward copies
Martin von Zweigbergk <martinvonz@google.com>
parents: 35421
diff changeset
   634
    # check for working copy
8801cdcea01f copies: extract method for getting non-wdir forward copies
Martin von Zweigbergk <martinvonz@google.com>
parents: 35421
diff changeset
   635
    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
   636
        cm = _committedforwardcopies(a, b.p1(), base, match)
35423
e54f02ec6a05 copies: group wdir-handling in one place
Martin von Zweigbergk <martinvonz@google.com>
parents: 35422
diff changeset
   637
        # 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
   638
        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
   639
    else:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
   640
        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
   641
    return copies
15775
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
   642
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
   643
41753
3158cb74fbca copies: make _backwardrenames() filter out copies by destination
Martin von Zweigbergk <martinvonz@google.com>
parents: 41752
diff changeset
   644
def _backwardrenames(a, b, match):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   645
    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
   646
        return {}
38f92d12357c copy: add flag for disabling copy tracing
Durham Goode <durham@fb.com>
parents: 25924
diff changeset
   647
18136
f23dea2b296e copies: do not track backward copies, only renames (issue3739)
Siddharth Agarwal <sid0@fb.com>
parents: 18135
diff changeset
   648
    # 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
   649
    # 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
   650
    # arbitrarily pick one of the renames.
41753
3158cb74fbca copies: make _backwardrenames() filter out copies by destination
Martin von Zweigbergk <martinvonz@google.com>
parents: 41752
diff changeset
   651
    # 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: 41752
diff changeset
   652
    # 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: 41752
diff changeset
   653
    # to filter the source instead.
15775
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
   654
    f = _forwardcopies(b, a)
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
   655
    r = {}
43106
d783f945a701 py3: finish porting iteritems() to pycompat and remove source transformer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43077
diff changeset
   656
    for k, v in sorted(pycompat.iteritems(f)):
41753
3158cb74fbca copies: make _backwardrenames() filter out copies by destination
Martin von Zweigbergk <martinvonz@google.com>
parents: 41752
diff changeset
   657
        if match and not match(v):
3158cb74fbca copies: make _backwardrenames() filter out copies by destination
Martin von Zweigbergk <martinvonz@google.com>
parents: 41752
diff changeset
   658
            continue
18136
f23dea2b296e copies: do not track backward copies, only renames (issue3739)
Siddharth Agarwal <sid0@fb.com>
parents: 18135
diff changeset
   659
        # remove copies
f23dea2b296e copies: do not track backward copies, only renames (issue3739)
Siddharth Agarwal <sid0@fb.com>
parents: 18135
diff changeset
   660
        if v in a:
f23dea2b296e copies: do not track backward copies, only renames (issue3739)
Siddharth Agarwal <sid0@fb.com>
parents: 18135
diff changeset
   661
            continue
15775
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
   662
        r[v] = k
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
   663
    return r
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
   664
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
   665
24782
4906dc0e038c copies: add matcher parameter to copy logic
Durham Goode <durham@fb.com>
parents: 24625
diff changeset
   666
def pathcopies(x, y, match=None):
35421
9cf37d111acb copies: consistently use """ for docstrings
Martin von Zweigbergk <martinvonz@google.com>
parents: 35420
diff changeset
   667
    """find {dst@y: src@x} copy mapping for directed compare"""
40057
25b2868206e2 copies: add a devel debug mode to trace what copy tracing does
Boris Feld <boris.feld@octobus.net>
parents: 39966
diff changeset
   668
    repo = x._repo
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   669
    debug = repo.ui.debugflag and repo.ui.configbool(b'devel', b'debug.copies')
40057
25b2868206e2 copies: add a devel debug mode to trace what copy tracing does
Boris Feld <boris.feld@octobus.net>
parents: 39966
diff changeset
   670
    if debug:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   671
        repo.ui.debug(
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   672
            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
   673
        )
15775
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
   674
    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
   675
        return {}
44276
30862e226339 copies: avoid filtering by short-circuit dirstate-only copies earlier
Martin von Zweigbergk <martinvonz@google.com>
parents: 44237
diff changeset
   676
    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: 44237
diff changeset
   677
        if debug:
30862e226339 copies: avoid filtering by short-circuit dirstate-only copies earlier
Martin von Zweigbergk <martinvonz@google.com>
parents: 44237
diff changeset
   678
            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: 44237
diff changeset
   679
        # 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: 44237
diff changeset
   680
        return _dirstatecopies(repo, match)
15775
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
   681
    a = y.ancestor(x)
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
   682
    if a == x:
40057
25b2868206e2 copies: add a devel debug mode to trace what copy tracing does
Boris Feld <boris.feld@octobus.net>
parents: 39966
diff changeset
   683
        if debug:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   684
            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
   685
        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
   686
    elif a == y:
40057
25b2868206e2 copies: add a devel debug mode to trace what copy tracing does
Boris Feld <boris.feld@octobus.net>
parents: 39966
diff changeset
   687
        if debug:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   688
            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
   689
        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
   690
    else:
a48f6f18dc6d copies: remove most early returns from pathcopies() and _forwardcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42591
diff changeset
   691
        if debug:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   692
            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
   693
        base = None
46113
59fa3890d40a node: import symbols explicitly
Joerg Sonnenberger <joerg@bec.de>
parents: 46109
diff changeset
   694
        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
   695
            base = x
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
   696
        copies = _chain(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
   697
            _backwardrenames(x, a, match=match),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
   698
            _forwardcopies(a, y, base, match=match),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
   699
        )
42594
d013099c551b copies: filter invalid copies only at end of pathcopies() (issue6163)
Martin von Zweigbergk <martinvonz@google.com>
parents: 42593
diff changeset
   700
    _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
   701
    return copies
15774
0bd17a4bed88 copies: split the copies api for "normal" and merge cases (API)
Matt Mackall <mpm@selenic.com>
parents: 14494
diff changeset
   702
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
   703
30186
f7ed5af31242 mergecopies: rename 'ca' to 'base'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30185
diff changeset
   704
def mergecopies(repo, c1, c2, base):
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   705
    """
42118
967c098eed33 copies: move comment about implementation of mergecopies() to end
Martin von Zweigbergk <martinvonz@google.com>
parents: 42115
diff changeset
   706
    Finds moves and copies between context c1 and c2 that are relevant for
34078
b4b196092cc3 copytrace: move the default copytracing algorithm in a new function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34077
diff changeset
   707
    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: 34077
diff changeset
   708
b4b196092cc3 copytrace: move the default copytracing algorithm in a new function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34077
diff changeset
   709
    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: 34077
diff changeset
   710
    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: 34077
diff changeset
   711
    For example:
33822
42ad7cc645a4 copies: add more details to the documentation of mergecopies()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32640
diff changeset
   712
42ad7cc645a4 copies: add more details to the documentation of mergecopies()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32640
diff changeset
   713
    o          ---> 4 another commit
42ad7cc645a4 copies: add more details to the documentation of mergecopies()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32640
diff changeset
   714
    |
42ad7cc645a4 copies: add more details to the documentation of mergecopies()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32640
diff changeset
   715
    |   o      ---> 3 commit that modifies a.txt
42ad7cc645a4 copies: add more details to the documentation of mergecopies()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32640
diff changeset
   716
    |  /
42ad7cc645a4 copies: add more details to the documentation of mergecopies()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32640
diff changeset
   717
    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: 32640
diff changeset
   718
    |/
42ad7cc645a4 copies: add more details to the documentation of mergecopies()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32640
diff changeset
   719
    o          ---> 1 merge base
42ad7cc645a4 copies: add more details to the documentation of mergecopies()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32640
diff changeset
   720
42ad7cc645a4 copies: add more details to the documentation of mergecopies()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32640
diff changeset
   721
    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: 32640
diff changeset
   722
    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: 32640
diff changeset
   723
    message:
42ad7cc645a4 copies: add more details to the documentation of mergecopies()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32640
diff changeset
   724
42ad7cc645a4 copies: add more details to the documentation of mergecopies()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32640
diff changeset
   725
    ```other changed <file> which local deleted```
42ad7cc645a4 copies: add more details to the documentation of mergecopies()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32640
diff changeset
   726
44199
7f8bdee0034e copies: define a type to return from mergecopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 44197
diff changeset
   727
    Returns a tuple where:
16168
7bbabfe25321 copies: add docstring for mergecopies
Matt Mackall <mpm@selenic.com>
parents: 15994
diff changeset
   728
44199
7f8bdee0034e copies: define a type to return from mergecopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 44197
diff changeset
   729
    "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
   730
16168
7bbabfe25321 copies: add docstring for mergecopies
Matt Mackall <mpm@selenic.com>
parents: 15994
diff changeset
   731
    "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
   732
    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
   733
42118
967c098eed33 copies: move comment about implementation of mergecopies() to end
Martin von Zweigbergk <martinvonz@google.com>
parents: 42115
diff changeset
   734
    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
   735
    """
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   736
    # 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
   737
    if not c1 or not c2 or c1 == c2:
44200
fa9ad1da2e77 merge: start using the per-side copy dicts
Martin von Zweigbergk <martinvonz@google.com>
parents: 44199
diff changeset
   738
        return branch_copies(), branch_copies(), {}
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   739
41752
012f695546aa copies: respect narrowmatcher in "parent -> working dir" case
Martin von Zweigbergk <martinvonz@google.com>
parents: 41724
diff changeset
   740
    narrowmatch = c1.repo().narrowmatch()
012f695546aa copies: respect narrowmatcher in "parent -> working dir" case
Martin von Zweigbergk <martinvonz@google.com>
parents: 41724
diff changeset
   741
6646
9eb274d773d9 copies: teach copies about dirstate.copies
Matt Mackall <mpm@selenic.com>
parents: 6431
diff changeset
   742
    # avoid silly behavior for parent -> working dir
13878
a8d13ee0ce68 misc: replace .parents()[0] with p1()
Matt Mackall <mpm@selenic.com>
parents: 12683
diff changeset
   743
    if c2.node() is None and c1.node() == repo.dirstate.p1():
44200
fa9ad1da2e77 merge: start using the per-side copy dicts
Martin von Zweigbergk <martinvonz@google.com>
parents: 44199
diff changeset
   744
        return (
fa9ad1da2e77 merge: start using the per-side copy dicts
Martin von Zweigbergk <martinvonz@google.com>
parents: 44199
diff changeset
   745
            branch_copies(_dirstatecopies(repo, narrowmatch)),
fa9ad1da2e77 merge: start using the per-side copy dicts
Martin von Zweigbergk <martinvonz@google.com>
parents: 44199
diff changeset
   746
            branch_copies(),
fa9ad1da2e77 merge: start using the per-side copy dicts
Martin von Zweigbergk <martinvonz@google.com>
parents: 44199
diff changeset
   747
            {},
fa9ad1da2e77 merge: start using the per-side copy dicts
Martin von Zweigbergk <martinvonz@google.com>
parents: 44199
diff changeset
   748
        )
6646
9eb274d773d9 copies: teach copies about dirstate.copies
Matt Mackall <mpm@selenic.com>
parents: 6431
diff changeset
   749
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   750
    copytracing = repo.ui.config(b'experimental', b'copytrace')
42225
d8ca7b99fc51 copies: move check for experimental.copytrace==<falsy> earlier
Martin von Zweigbergk <martinvonz@google.com>
parents: 42224
diff changeset
   751
    if stringutil.parsebool(copytracing) is False:
d8ca7b99fc51 copies: move check for experimental.copytrace==<falsy> earlier
Martin von Zweigbergk <martinvonz@google.com>
parents: 42224
diff changeset
   752
        # 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: 42224
diff changeset
   753
        # value, so we should rely on making sure copytracing is on such cases
44200
fa9ad1da2e77 merge: start using the per-side copy dicts
Martin von Zweigbergk <martinvonz@google.com>
parents: 44199
diff changeset
   754
        return branch_copies(), branch_copies(), {}
34078
b4b196092cc3 copytrace: move the default copytracing algorithm in a new function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34077
diff changeset
   755
42226
a6be3af3a397 copies: ignore heuristics copytracing when using changeset-centric algos
Martin von Zweigbergk <martinvonz@google.com>
parents: 42225
diff changeset
   756
    if usechangesetcentricalgo(repo):
a6be3af3a397 copies: ignore heuristics copytracing when using changeset-centric algos
Martin von Zweigbergk <martinvonz@google.com>
parents: 42225
diff changeset
   757
        # 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: 42225
diff changeset
   758
        return _fullcopytracing(repo, c1, c2, base)
a6be3af3a397 copies: ignore heuristics copytracing when using changeset-centric algos
Martin von Zweigbergk <martinvonz@google.com>
parents: 42225
diff changeset
   759
26013
38f92d12357c copy: add flag for disabling copy tracing
Durham Goode <durham@fb.com>
parents: 25924
diff changeset
   760
    # 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
   761
    # 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
   762
    # rebase.
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   763
    if copytracing == b'heuristics':
34366
d00910b286cd copytrace: use ctx.mutable() instead of adhoc constant of non-public phases
Yuya Nishihara <yuya@tcha.org>
parents: 34348
diff changeset
   764
        # 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: 34348
diff changeset
   765
        # 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: 34348
diff changeset
   766
        # be missed by heuristics
34311
1826d695ad58 copytrace: add a a new config to limit the number of drafts in heuristics
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34288
diff changeset
   767
        if _isfullcopytraceable(repo, c1, base):
34288
fc3b8483c6cb copytrace: use the full copytracing method if only drafts are involved
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34179
diff changeset
   768
            return _fullcopytracing(repo, c1, c2, base)
34179
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
   769
        return _heuristicscopytracing(repo, c1, c2, base)
34078
b4b196092cc3 copytrace: move the default copytracing algorithm in a new function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34077
diff changeset
   770
    else:
b4b196092cc3 copytrace: move the default copytracing algorithm in a new function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34077
diff changeset
   771
        return _fullcopytracing(repo, c1, c2, base)
26013
38f92d12357c copy: add flag for disabling copy tracing
Durham Goode <durham@fb.com>
parents: 25924
diff changeset
   772
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
   773
34311
1826d695ad58 copytrace: add a a new config to limit the number of drafts in heuristics
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34288
diff changeset
   774
def _isfullcopytraceable(repo, c1, base):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45892
diff changeset
   775
    """Checks that if base, source and destination are all no-public branches,
34366
d00910b286cd copytrace: use ctx.mutable() instead of adhoc constant of non-public phases
Yuya Nishihara <yuya@tcha.org>
parents: 34348
diff changeset
   776
    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: 34348
diff changeset
   777
    since it will be fast enough.
34516
e79b3611223b copies: add docs for config `experimental.copytrace.sourcecommitlimit`
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34366
diff changeset
   778
e79b3611223b copies: add docs for config `experimental.copytrace.sourcecommitlimit`
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34366
diff changeset
   779
    `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: 34366
diff changeset
   780
    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: 34366
diff changeset
   781
    more than the limit, full copytracing algorithm won't be used.
34288
fc3b8483c6cb copytrace: use the full copytracing method if only drafts are involved
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34179
diff changeset
   782
    """
34311
1826d695ad58 copytrace: add a a new config to limit the number of drafts in heuristics
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34288
diff changeset
   783
    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: 34288
diff changeset
   784
        c1 = c1.p1()
34366
d00910b286cd copytrace: use ctx.mutable() instead of adhoc constant of non-public phases
Yuya Nishihara <yuya@tcha.org>
parents: 34348
diff changeset
   785
    if c1.mutable() and base.mutable():
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
   786
        sourcecommitlimit = repo.ui.configint(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   787
            b'experimental', b'copytrace.sourcecommitlimit'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
   788
        )
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   789
        commits = len(repo.revs(b'%d::%d', base.rev(), c1.rev()))
34311
1826d695ad58 copytrace: add a a new config to limit the number of drafts in heuristics
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34288
diff changeset
   790
        return commits < sourcecommitlimit
34288
fc3b8483c6cb copytrace: use the full copytracing method if only drafts are involved
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34179
diff changeset
   791
    return False
fc3b8483c6cb copytrace: use the full copytracing method if only drafts are involved
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34179
diff changeset
   792
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
   793
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
   794
def _checksinglesidecopies(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
   795
    src, dsts1, m1, m2, mb, c2, base, copy, renamedelete
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
   796
):
42222
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
   797
    if src not in m2:
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
   798
        # deleted on side 2
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
   799
        if src not in m1:
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
   800
            # renamed on side 1, deleted on side 2
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
   801
            renamedelete[src] = dsts1
44210
d0c3eead515a copies: fix crash when copy source is not in graft base
Martin von Zweigbergk <martinvonz@google.com>
parents: 44200
diff changeset
   802
    elif src not in mb:
d0c3eead515a copies: fix crash when copy source is not in graft base
Martin von Zweigbergk <martinvonz@google.com>
parents: 44200
diff changeset
   803
        # 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: 44200
diff changeset
   804
        # 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: 44200
diff changeset
   805
        # 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: 44200
diff changeset
   806
        pass
44909
d452acc8cce8 flags: account for flag change when tracking rename relevant to merge
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44276
diff changeset
   807
    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: 44276
diff changeset
   808
        return
d452acc8cce8 flags: account for flag change when tracking rename relevant to merge
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44276
diff changeset
   809
    elif mb[src] != m2[src] or mb.flags(src) != m2.flags(src):
42222
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
   810
        # modified on side 2
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
   811
        for dst in dsts1:
44237
b4057d001760 merge: when rename was made on both sides, use ancestor as merge base
Martin von Zweigbergk <martinvonz@google.com>
parents: 44210
diff changeset
   812
            copy[dst] = src
42222
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
   813
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
   814
44199
7f8bdee0034e copies: define a type to return from mergecopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 44197
diff changeset
   815
class branch_copies(object):
7f8bdee0034e copies: define a type to return from mergecopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 44197
diff changeset
   816
    """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: 44197
diff changeset
   817
7f8bdee0034e copies: define a type to return from mergecopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 44197
diff changeset
   818
    "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: 44197
diff changeset
   819
    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: 44197
diff changeset
   820
7f8bdee0034e copies: define a type to return from mergecopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 44197
diff changeset
   821
    "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: 44197
diff changeset
   822
    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: 44197
diff changeset
   823
    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: 44197
diff changeset
   824
    other context moved the directory it is in.
7f8bdee0034e copies: define a type to return from mergecopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 44197
diff changeset
   825
7f8bdee0034e copies: define a type to return from mergecopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 44197
diff changeset
   826
    "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: 44197
diff changeset
   827
    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: 44197
diff changeset
   828
7f8bdee0034e copies: define a type to return from mergecopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 44197
diff changeset
   829
    "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: 44197
diff changeset
   830
    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: 44197
diff changeset
   831
    renamed directories.
7f8bdee0034e copies: define a type to return from mergecopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 44197
diff changeset
   832
    """
7f8bdee0034e copies: define a type to return from mergecopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 44197
diff changeset
   833
7f8bdee0034e copies: define a type to return from mergecopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 44197
diff changeset
   834
    def __init__(
7f8bdee0034e copies: define a type to return from mergecopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 44197
diff changeset
   835
        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: 44197
diff changeset
   836
    ):
7f8bdee0034e copies: define a type to return from mergecopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 44197
diff changeset
   837
        self.copy = {} if copy is None else copy
7f8bdee0034e copies: define a type to return from mergecopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 44197
diff changeset
   838
        self.renamedelete = {} if renamedelete is None else renamedelete
7f8bdee0034e copies: define a type to return from mergecopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 44197
diff changeset
   839
        self.dirmove = {} if dirmove is None else dirmove
7f8bdee0034e copies: define a type to return from mergecopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 44197
diff changeset
   840
        self.movewithdir = {} if movewithdir is None else movewithdir
7f8bdee0034e copies: define a type to return from mergecopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 44197
diff changeset
   841
44994
cfd06649a1b8 copies: implement __repr__ on branch_copies for debugging
Martin von Zweigbergk <martinvonz@google.com>
parents: 44940
diff changeset
   842
    def __repr__(self):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45892
diff changeset
   843
        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: 45892
diff changeset
   844
            self.copy,
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45892
diff changeset
   845
            self.renamedelete,
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45892
diff changeset
   846
            self.dirmove,
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45892
diff changeset
   847
            self.movewithdir,
44994
cfd06649a1b8 copies: implement __repr__ on branch_copies for debugging
Martin von Zweigbergk <martinvonz@google.com>
parents: 44940
diff changeset
   848
        )
cfd06649a1b8 copies: implement __repr__ on branch_copies for debugging
Martin von Zweigbergk <martinvonz@google.com>
parents: 44940
diff changeset
   849
44199
7f8bdee0034e copies: define a type to return from mergecopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 44197
diff changeset
   850
34078
b4b196092cc3 copytrace: move the default copytracing algorithm in a new function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34077
diff changeset
   851
def _fullcopytracing(repo, c1, c2, base):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45892
diff changeset
   852
    """The full copytracing algorithm which finds all the new files that were
34078
b4b196092cc3 copytrace: move the default copytracing algorithm in a new function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34077
diff changeset
   853
    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: 34077
diff changeset
   854
    this file was copied from another file.
b4b196092cc3 copytrace: move the default copytracing algorithm in a new function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34077
diff changeset
   855
b4b196092cc3 copytrace: move the default copytracing algorithm in a new function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34077
diff changeset
   856
    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: 34077
diff changeset
   857
    the copies.
b4b196092cc3 copytrace: move the default copytracing algorithm in a new function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34077
diff changeset
   858
    """
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   859
    m1 = c1.manifest()
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   860
    m2 = c2.manifest()
30186
f7ed5af31242 mergecopies: rename 'ca' to 'base'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30185
diff changeset
   861
    mb = base.manifest()
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   862
42222
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
   863
    copies1 = pathcopies(base, c1)
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
   864
    copies2 = pathcopies(base, c2)
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
   865
44162
baf3fe2977cc copies: move early return in mergecopies() earlier
Martin von Zweigbergk <martinvonz@google.com>
parents: 44093
diff changeset
   866
    if not (copies1 or copies2):
44200
fa9ad1da2e77 merge: start using the per-side copy dicts
Martin von Zweigbergk <martinvonz@google.com>
parents: 44199
diff changeset
   867
        return branch_copies(), branch_copies(), {}
44162
baf3fe2977cc copies: move early return in mergecopies() earlier
Martin von Zweigbergk <martinvonz@google.com>
parents: 44093
diff changeset
   868
42222
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
   869
    inversecopies1 = {}
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
   870
    inversecopies2 = {}
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
   871
    for dst, src in copies1.items():
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
   872
        inversecopies1.setdefault(src, []).append(dst)
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
   873
    for dst, src in copies2.items():
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
   874
        inversecopies2.setdefault(src, []).append(dst)
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
   875
44196
6ca9f45b32b0 copies: make mergecopies() distinguish between copies on each side
Martin von Zweigbergk <martinvonz@google.com>
parents: 44164
diff changeset
   876
    copy1 = {}
6ca9f45b32b0 copies: make mergecopies() distinguish between copies on each side
Martin von Zweigbergk <martinvonz@google.com>
parents: 44164
diff changeset
   877
    copy2 = {}
42222
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
   878
    diverge = {}
44196
6ca9f45b32b0 copies: make mergecopies() distinguish between copies on each side
Martin von Zweigbergk <martinvonz@google.com>
parents: 44164
diff changeset
   879
    renamedelete1 = {}
6ca9f45b32b0 copies: make mergecopies() distinguish between copies on each side
Martin von Zweigbergk <martinvonz@google.com>
parents: 44164
diff changeset
   880
    renamedelete2 = {}
42222
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
   881
    allsources = set(inversecopies1) | set(inversecopies2)
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
   882
    for src in allsources:
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
   883
        dsts1 = inversecopies1.get(src)
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
   884
        dsts2 = inversecopies2.get(src)
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
   885
        if dsts1 and dsts2:
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
   886
            # copied/renamed on both sides
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
   887
            if src not in m1 and src not in m2:
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
   888
                # renamed on both sides
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
   889
                dsts1 = set(dsts1)
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
   890
                dsts2 = set(dsts2)
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
   891
                # If there's some overlap in the rename destinations, we
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
   892
                # 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: 42210
diff changeset
   893
                # 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: 42210
diff changeset
   894
                # and 'd' and deletes 'a'.
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
   895
                if dsts1 & dsts2:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
   896
                    for dst in dsts1 & dsts2:
44196
6ca9f45b32b0 copies: make mergecopies() distinguish between copies on each side
Martin von Zweigbergk <martinvonz@google.com>
parents: 44164
diff changeset
   897
                        copy1[dst] = src
6ca9f45b32b0 copies: make mergecopies() distinguish between copies on each side
Martin von Zweigbergk <martinvonz@google.com>
parents: 44164
diff changeset
   898
                        copy2[dst] = src
42222
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
   899
                else:
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
   900
                    diverge[src] = sorted(dsts1 | dsts2)
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
   901
            elif src in m1 and src in m2:
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
   902
                # copied on both sides
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
   903
                dsts1 = set(dsts1)
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
   904
                dsts2 = set(dsts2)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
   905
                for dst in dsts1 & dsts2:
44196
6ca9f45b32b0 copies: make mergecopies() distinguish between copies on each side
Martin von Zweigbergk <martinvonz@google.com>
parents: 44164
diff changeset
   906
                    copy1[dst] = src
6ca9f45b32b0 copies: make mergecopies() distinguish between copies on each side
Martin von Zweigbergk <martinvonz@google.com>
parents: 44164
diff changeset
   907
                    copy2[dst] = src
42222
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
   908
            # 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: 42210
diff changeset
   909
            # on the other side
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
   910
        elif dsts1:
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
   911
            # copied/renamed only on side 1
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
   912
            _checksinglesidecopies(
44196
6ca9f45b32b0 copies: make mergecopies() distinguish between copies on each side
Martin von Zweigbergk <martinvonz@google.com>
parents: 44164
diff changeset
   913
                src, dsts1, m1, m2, mb, c2, base, copy1, renamedelete1
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
   914
            )
42222
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
   915
        elif dsts2:
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
   916
            # copied/renamed only on side 2
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
   917
            _checksinglesidecopies(
44196
6ca9f45b32b0 copies: make mergecopies() distinguish between copies on each side
Martin von Zweigbergk <martinvonz@google.com>
parents: 44164
diff changeset
   918
                src, dsts2, m2, m1, mb, c1, base, copy2, renamedelete2
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
   919
            )
42222
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
   920
26659
df66736a128e copies: group bothnew with other sets
Matt Mackall <mpm@selenic.com>
parents: 26658
diff changeset
   921
    # find interesting file sets from manifests
46109
2f357d053df2 copies: make calculating lazy for dir move detection's "addedfiles"
Kyle Lippincott <spectral@google.com>
parents: 46057
diff changeset
   922
    cache = []
2f357d053df2 copies: make calculating lazy for dir move detection's "addedfiles"
Kyle Lippincott <spectral@google.com>
parents: 46057
diff changeset
   923
2f357d053df2 copies: make calculating lazy for dir move detection's "addedfiles"
Kyle Lippincott <spectral@google.com>
parents: 46057
diff changeset
   924
    def _get_addedfiles(idx):
2f357d053df2 copies: make calculating lazy for dir move detection's "addedfiles"
Kyle Lippincott <spectral@google.com>
parents: 46057
diff changeset
   925
        if not cache:
2f357d053df2 copies: make calculating lazy for dir move detection's "addedfiles"
Kyle Lippincott <spectral@google.com>
parents: 46057
diff changeset
   926
            addedinm1 = m1.filesnotin(mb, repo.narrowmatch())
2f357d053df2 copies: make calculating lazy for dir move detection's "addedfiles"
Kyle Lippincott <spectral@google.com>
parents: 46057
diff changeset
   927
            addedinm2 = m2.filesnotin(mb, repo.narrowmatch())
2f357d053df2 copies: make calculating lazy for dir move detection's "addedfiles"
Kyle Lippincott <spectral@google.com>
parents: 46057
diff changeset
   928
            u1 = sorted(addedinm1 - addedinm2)
2f357d053df2 copies: make calculating lazy for dir move detection's "addedfiles"
Kyle Lippincott <spectral@google.com>
parents: 46057
diff changeset
   929
            u2 = sorted(addedinm2 - addedinm1)
2f357d053df2 copies: make calculating lazy for dir move detection's "addedfiles"
Kyle Lippincott <spectral@google.com>
parents: 46057
diff changeset
   930
            cache.extend((u1, u2))
2f357d053df2 copies: make calculating lazy for dir move detection's "addedfiles"
Kyle Lippincott <spectral@google.com>
parents: 46057
diff changeset
   931
        return cache[idx]
42223
d69bc8ffbe6f copies: inline _computenonoverlap() in mergecopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42222
diff changeset
   932
46109
2f357d053df2 copies: make calculating lazy for dir move detection's "addedfiles"
Kyle Lippincott <spectral@google.com>
parents: 46057
diff changeset
   933
    u1fn = lambda: _get_addedfiles(0)
2f357d053df2 copies: make calculating lazy for dir move detection's "addedfiles"
Kyle Lippincott <spectral@google.com>
parents: 46057
diff changeset
   934
    u2fn = lambda: _get_addedfiles(1)
2f357d053df2 copies: make calculating lazy for dir move detection's "addedfiles"
Kyle Lippincott <spectral@google.com>
parents: 46057
diff changeset
   935
    if repo.ui.debugflag:
2f357d053df2 copies: make calculating lazy for dir move detection's "addedfiles"
Kyle Lippincott <spectral@google.com>
parents: 46057
diff changeset
   936
        u1 = u1fn()
2f357d053df2 copies: make calculating lazy for dir move detection's "addedfiles"
Kyle Lippincott <spectral@google.com>
parents: 46057
diff changeset
   937
        u2 = u2fn()
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   938
46109
2f357d053df2 copies: make calculating lazy for dir move detection's "addedfiles"
Kyle Lippincott <spectral@google.com>
parents: 46057
diff changeset
   939
        header = b"  unmatched files in %s"
2f357d053df2 copies: make calculating lazy for dir move detection's "addedfiles"
Kyle Lippincott <spectral@google.com>
parents: 46057
diff changeset
   940
        if u1:
2f357d053df2 copies: make calculating lazy for dir move detection's "addedfiles"
Kyle Lippincott <spectral@google.com>
parents: 46057
diff changeset
   941
            repo.ui.debug(
2f357d053df2 copies: make calculating lazy for dir move detection's "addedfiles"
Kyle Lippincott <spectral@google.com>
parents: 46057
diff changeset
   942
                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: 46057
diff changeset
   943
            )
2f357d053df2 copies: make calculating lazy for dir move detection's "addedfiles"
Kyle Lippincott <spectral@google.com>
parents: 46057
diff changeset
   944
        if u2:
2f357d053df2 copies: make calculating lazy for dir move detection's "addedfiles"
Kyle Lippincott <spectral@google.com>
parents: 46057
diff changeset
   945
            repo.ui.debug(
2f357d053df2 copies: make calculating lazy for dir move detection's "addedfiles"
Kyle Lippincott <spectral@google.com>
parents: 46057
diff changeset
   946
                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: 46057
diff changeset
   947
            )
2f357d053df2 copies: make calculating lazy for dir move detection's "addedfiles"
Kyle Lippincott <spectral@google.com>
parents: 46057
diff changeset
   948
44163
782e0d9c3b74 copies: avoid calculating debug-only stuff without --debug
Martin von Zweigbergk <martinvonz@google.com>
parents: 44162
diff changeset
   949
        renamedeleteset = set()
782e0d9c3b74 copies: avoid calculating debug-only stuff without --debug
Martin von Zweigbergk <martinvonz@google.com>
parents: 44162
diff changeset
   950
        divergeset = set()
782e0d9c3b74 copies: avoid calculating debug-only stuff without --debug
Martin von Zweigbergk <martinvonz@google.com>
parents: 44162
diff changeset
   951
        for dsts in diverge.values():
782e0d9c3b74 copies: avoid calculating debug-only stuff without --debug
Martin von Zweigbergk <martinvonz@google.com>
parents: 44162
diff changeset
   952
            divergeset.update(dsts)
44196
6ca9f45b32b0 copies: make mergecopies() distinguish between copies on each side
Martin von Zweigbergk <martinvonz@google.com>
parents: 44164
diff changeset
   953
        for dsts in renamedelete1.values():
6ca9f45b32b0 copies: make mergecopies() distinguish between copies on each side
Martin von Zweigbergk <martinvonz@google.com>
parents: 44164
diff changeset
   954
            renamedeleteset.update(dsts)
6ca9f45b32b0 copies: make mergecopies() distinguish between copies on each side
Martin von Zweigbergk <martinvonz@google.com>
parents: 44164
diff changeset
   955
        for dsts in renamedelete2.values():
44163
782e0d9c3b74 copies: avoid calculating debug-only stuff without --debug
Martin von Zweigbergk <martinvonz@google.com>
parents: 44162
diff changeset
   956
            renamedeleteset.update(dsts)
782e0d9c3b74 copies: avoid calculating debug-only stuff without --debug
Martin von Zweigbergk <martinvonz@google.com>
parents: 44162
diff changeset
   957
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
   958
        repo.ui.debug(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   959
            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
   960
            b"% = renamed and deleted):\n"
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
   961
        )
44197
17e12938f8e7 copies: print debug information about copies per side/branch
Martin von Zweigbergk <martinvonz@google.com>
parents: 44196
diff changeset
   962
        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: 44196
diff changeset
   963
            if not copies:
17e12938f8e7 copies: print debug information about copies per side/branch
Martin von Zweigbergk <martinvonz@google.com>
parents: 44196
diff changeset
   964
                continue
17e12938f8e7 copies: print debug information about copies per side/branch
Martin von Zweigbergk <martinvonz@google.com>
parents: 44196
diff changeset
   965
            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: 44196
diff changeset
   966
            for f in sorted(copies):
17e12938f8e7 copies: print debug information about copies per side/branch
Martin von Zweigbergk <martinvonz@google.com>
parents: 44196
diff changeset
   967
                note = b""
17e12938f8e7 copies: print debug information about copies per side/branch
Martin von Zweigbergk <martinvonz@google.com>
parents: 44196
diff changeset
   968
                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: 44196
diff changeset
   969
                    note += b"*"
17e12938f8e7 copies: print debug information about copies per side/branch
Martin von Zweigbergk <martinvonz@google.com>
parents: 44196
diff changeset
   970
                if f in divergeset:
17e12938f8e7 copies: print debug information about copies per side/branch
Martin von Zweigbergk <martinvonz@google.com>
parents: 44196
diff changeset
   971
                    note += b"!"
17e12938f8e7 copies: print debug information about copies per side/branch
Martin von Zweigbergk <martinvonz@google.com>
parents: 44196
diff changeset
   972
                if f in renamedeleteset:
17e12938f8e7 copies: print debug information about copies per side/branch
Martin von Zweigbergk <martinvonz@google.com>
parents: 44196
diff changeset
   973
                    note += b"%"
17e12938f8e7 copies: print debug information about copies per side/branch
Martin von Zweigbergk <martinvonz@google.com>
parents: 44196
diff changeset
   974
                repo.ui.debug(
17e12938f8e7 copies: print debug information about copies per side/branch
Martin von Zweigbergk <martinvonz@google.com>
parents: 44196
diff changeset
   975
                    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: 44196
diff changeset
   976
                )
44163
782e0d9c3b74 copies: avoid calculating debug-only stuff without --debug
Martin von Zweigbergk <martinvonz@google.com>
parents: 44162
diff changeset
   977
        del renamedeleteset
782e0d9c3b74 copies: avoid calculating debug-only stuff without --debug
Martin von Zweigbergk <martinvonz@google.com>
parents: 44162
diff changeset
   978
        del divergeset
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   979
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   980
    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
   981
46109
2f357d053df2 copies: make calculating lazy for dir move detection's "addedfiles"
Kyle Lippincott <spectral@google.com>
parents: 46057
diff changeset
   982
    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: 46057
diff changeset
   983
    dirmove2, movewithdir1 = _dir_renames(repo, c2, copy2, copies2, u1fn)
44164
45192589555c copies: extract function for finding directory renames
Martin von Zweigbergk <martinvonz@google.com>
parents: 44163
diff changeset
   984
44200
fa9ad1da2e77 merge: start using the per-side copy dicts
Martin von Zweigbergk <martinvonz@google.com>
parents: 44199
diff changeset
   985
    branch_copies1 = branch_copies(copy1, renamedelete1, dirmove1, movewithdir1)
fa9ad1da2e77 merge: start using the per-side copy dicts
Martin von Zweigbergk <martinvonz@google.com>
parents: 44199
diff changeset
   986
    branch_copies2 = branch_copies(copy2, renamedelete2, dirmove2, movewithdir2)
44196
6ca9f45b32b0 copies: make mergecopies() distinguish between copies on each side
Martin von Zweigbergk <martinvonz@google.com>
parents: 44164
diff changeset
   987
44200
fa9ad1da2e77 merge: start using the per-side copy dicts
Martin von Zweigbergk <martinvonz@google.com>
parents: 44199
diff changeset
   988
    return branch_copies1, branch_copies2, diverge
44164
45192589555c copies: extract function for finding directory renames
Martin von Zweigbergk <martinvonz@google.com>
parents: 44163
diff changeset
   989
45192589555c copies: extract function for finding directory renames
Martin von Zweigbergk <martinvonz@google.com>
parents: 44163
diff changeset
   990
46109
2f357d053df2 copies: make calculating lazy for dir move detection's "addedfiles"
Kyle Lippincott <spectral@google.com>
parents: 46057
diff changeset
   991
def _dir_renames(repo, ctx, copy, fullcopy, addedfilesfn):
44196
6ca9f45b32b0 copies: make mergecopies() distinguish between copies on each side
Martin von Zweigbergk <martinvonz@google.com>
parents: 44164
diff changeset
   992
    """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: 44164
diff changeset
   993
6ca9f45b32b0 copies: make mergecopies() distinguish between copies on each side
Martin von Zweigbergk <martinvonz@google.com>
parents: 44164
diff changeset
   994
    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: 44164
diff changeset
   995
    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: 44164
diff changeset
   996
    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: 44164
diff changeset
   997
              merge.manifestmerge() won't care about
46109
2f357d053df2 copies: make calculating lazy for dir move detection's "addedfiles"
Kyle Lippincott <spectral@google.com>
parents: 46057
diff changeset
   998
    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: 46057
diff changeset
   999
                  ctx)
44196
6ca9f45b32b0 copies: make mergecopies() distinguish between copies on each side
Martin von Zweigbergk <martinvonz@google.com>
parents: 44164
diff changeset
  1000
    """
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1001
    # 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
  1002
    invalid = set()
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1003
    dirmove = {}
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1004
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1005
    # 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
  1006
    # 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
  1007
    for dst, src in pycompat.iteritems(fullcopy):
25282
0f28815ef066 copies: switch to using pathutil.dirname
Durham Goode <durham@fb.com>
parents: 24782
diff changeset
  1008
        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
  1009
        if dsrc in invalid:
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1010
            # already seen to be uninteresting
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1011
            continue
46011
b9588ff9b66a copies: avoid materializing a full directory map during copy tracing
Kyle Lippincott <spectral@google.com>
parents: 45986
diff changeset
  1012
        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
  1013
            # directory wasn't entirely moved locally
39263
eebd591803ab copies: correctly skip directories that have already been considered
Kyle Lippincott <spectral@google.com>
parents: 38670
diff changeset
  1014
            invalid.add(dsrc)
eebd591803ab copies: correctly skip directories that have already been considered
Kyle Lippincott <spectral@google.com>
parents: 38670
diff changeset
  1015
        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
  1016
            # files from the same directory moved to two different places
39263
eebd591803ab copies: correctly skip directories that have already been considered
Kyle Lippincott <spectral@google.com>
parents: 38670
diff changeset
  1017
            invalid.add(dsrc)
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1018
        else:
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1019
            # looks good so far
39263
eebd591803ab copies: correctly skip directories that have already been considered
Kyle Lippincott <spectral@google.com>
parents: 38670
diff changeset
  1020
            dirmove[dsrc] = ddst
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1021
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1022
    for i in invalid:
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1023
        if i in dirmove:
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1024
            del dirmove[i]
46011
b9588ff9b66a copies: avoid materializing a full directory map during copy tracing
Kyle Lippincott <spectral@google.com>
parents: 45986
diff changeset
  1025
    del invalid
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1026
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1027
    if not dirmove:
44164
45192589555c copies: extract function for finding directory renames
Martin von Zweigbergk <martinvonz@google.com>
parents: 44163
diff changeset
  1028
        return {}, {}
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1029
43106
d783f945a701 py3: finish porting iteritems() to pycompat and remove source transformer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43077
diff changeset
  1030
    dirmove = {k + b"/": v + b"/" for k, v in pycompat.iteritems(dirmove)}
39263
eebd591803ab copies: correctly skip directories that have already been considered
Kyle Lippincott <spectral@google.com>
parents: 38670
diff changeset
  1031
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1032
    for d in dirmove:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
  1033
        repo.ui.debug(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1034
            b"   discovered dir src: '%s' -> dst: '%s'\n" % (d, dirmove[d])
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
  1035
        )
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1036
30183
0106f93ca1d5 checkcopies: move 'movewithdir' initialisation right before its usage
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30138
diff changeset
  1037
    movewithdir = {}
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1038
    # check unaccounted nonoverlapping files against directory moves
46109
2f357d053df2 copies: make calculating lazy for dir move detection's "addedfiles"
Kyle Lippincott <spectral@google.com>
parents: 46057
diff changeset
  1039
    for f in addedfilesfn():
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1040
        if f not in fullcopy:
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1041
            for d in dirmove:
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1042
                if f.startswith(d):
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1043
                    # new file added in a directory that was moved, move it
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
  1044
                    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
  1045
                    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
  1046
                        movewithdir[f] = df
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
  1047
                        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
  1048
                            b"   pending file src: '%s' -> dst: '%s'\n"
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
  1049
                            % (f, df)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
  1050
                        )
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1051
                    break
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
  1052
44164
45192589555c copies: extract function for finding directory renames
Martin von Zweigbergk <martinvonz@google.com>
parents: 44163
diff changeset
  1053
    return dirmove, movewithdir
19178
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
  1054
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
  1055
34179
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
  1056
def _heuristicscopytracing(repo, c1, c2, base):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45892
diff changeset
  1057
    """Fast copytracing using filename heuristics
34179
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
  1058
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
  1059
    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: 34078
diff changeset
  1060
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
  1061
    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: 34078
diff changeset
  1062
    2) Move from one directory to another
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
  1063
                    (same filenames but different directory names)
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
  1064
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
  1065
    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: 34078
diff changeset
  1066
    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: 34078
diff changeset
  1067
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
  1068
    If merge is involved it fallbacks to _fullcopytracing().
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
  1069
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
  1070
    Can be used by setting the following config:
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
  1071
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
  1072
        [experimental]
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
  1073
        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
  1074
f05a6e015ecc copies: add a config to limit the number of candidates to check in heuristics
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34787
diff changeset
  1075
    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
  1076
    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
  1077
    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
  1078
    `experimental.copytrace.movecandidateslimit` which defaults to 100.
34179
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
  1079
    """
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
  1080
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
  1081
    if c1.rev() is None:
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
  1082
        c1 = c1.p1()
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
  1083
    if c2.rev() is None:
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
  1084
        c2 = c2.p1()
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
  1085
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
  1086
    changedfiles = set()
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
  1087
    m1 = c1.manifest()
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1088
    if not repo.revs(b'%d::%d', base.rev(), c2.rev()):
34179
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
  1089
        # If base is not in c2 branch, we switch to fullcopytracing
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
  1090
        repo.ui.debug(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1091
            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
  1092
            b"an ancestor of c2\n"
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
  1093
        )
34179
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
  1094
        return _fullcopytracing(repo, c1, c2, base)
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
  1095
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
  1096
    ctx = c2
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
  1097
    while ctx != base:
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
  1098
        if len(ctx.parents()) == 2:
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
  1099
            # 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
  1100
            repo.ui.debug(b"switching to full copytracing because of merges\n")
34179
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
  1101
            return _fullcopytracing(repo, c1, c2, base)
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
  1102
        changedfiles.update(ctx.files())
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
  1103
        ctx = ctx.p1()
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
  1104
44200
fa9ad1da2e77 merge: start using the per-side copy dicts
Martin von Zweigbergk <martinvonz@google.com>
parents: 44199
diff changeset
  1105
    copies2 = {}
34179
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
  1106
    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
  1107
    for dst, src in pycompat.iteritems(cp):
34179
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
  1108
        if src in m1:
44200
fa9ad1da2e77 merge: start using the per-side copy dicts
Martin von Zweigbergk <martinvonz@google.com>
parents: 44199
diff changeset
  1109
            copies2[dst] = src
34179
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
  1110
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
  1111
    # 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: 34078
diff changeset
  1112
    # the base and present in the source.
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
  1113
    # 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: 34078
diff changeset
  1114
    # source is important to exclude removed files.
36346
f62369667a7c py3: use list comprehensions instead of filter where we need to eagerly filter
Augie Fackler <augie@google.com>
parents: 36117
diff changeset
  1115
    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: 36117
diff changeset
  1116
    missingfiles = [f for f in changedfiles if filt(f)]
34179
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
  1117
44200
fa9ad1da2e77 merge: start using the per-side copy dicts
Martin von Zweigbergk <martinvonz@google.com>
parents: 44199
diff changeset
  1118
    copies1 = {}
34179
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
  1119
    if missingfiles:
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
  1120
        basenametofilename = collections.defaultdict(list)
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
  1121
        dirnametofilename = collections.defaultdict(list)
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
  1122
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
  1123
        for f in m1.filesnotin(base.manifest()):
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
  1124
            basename = os.path.basename(f)
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
  1125
            dirname = os.path.dirname(f)
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
  1126
            basenametofilename[basename].append(f)
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
  1127
            dirnametofilename[dirname].append(f)
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
  1128
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
  1129
        for f in missingfiles:
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
  1130
            basename = os.path.basename(f)
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
  1131
            dirname = os.path.dirname(f)
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
  1132
            samebasename = basenametofilename[basename]
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
  1133
            samedirname = dirnametofilename[dirname]
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
  1134
            movecandidates = samebasename + samedirname
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
  1135
            # 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: 34078
diff changeset
  1136
            # c2.filectx(f) won't fail
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
  1137
            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
  1138
            # 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
  1139
            # config value to limit the number of candidates moves to check
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
  1140
            maxcandidates = repo.ui.configint(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1141
                b'experimental', b'copytrace.movecandidateslimit'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
  1142
            )
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
  1143
f05a6e015ecc copies: add a config to limit the number of candidates to check in heuristics
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34787
diff changeset
  1144
            if len(movecandidates) > maxcandidates:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
  1145
                repo.ui.status(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
  1146
                    _(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1147
                        b"skipping copytracing for '%s', more "
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
  1148
                        b"candidates than the limit: %d\n"
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
  1149
                    )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
  1150
                    % (f, len(movecandidates))
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
  1151
                )
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
  1152
                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
  1153
34179
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
  1154
            for candidate in movecandidates:
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
  1155
                f1 = c1.filectx(candidate)
37392
a4f02a17420d copies: clean up _related logic
G?bor Stefanik <gabor.stefanik@nng.com>
parents: 36346
diff changeset
  1156
                if _related(f1, f2):
34179
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
  1157
                    # 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: 34078
diff changeset
  1158
                    # changes into all of them. This matches the behaviour
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
  1159
                    # of upstream copytracing
44200
fa9ad1da2e77 merge: start using the per-side copy dicts
Martin von Zweigbergk <martinvonz@google.com>
parents: 44199
diff changeset
  1160
                    copies1[candidate] = f
34179
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
  1161
44200
fa9ad1da2e77 merge: start using the per-side copy dicts
Martin von Zweigbergk <martinvonz@google.com>
parents: 44199
diff changeset
  1162
    return branch_copies(copies1), branch_copies(copies2), {}
34179
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
  1163
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
  1164
37392
a4f02a17420d copies: clean up _related logic
G?bor Stefanik <gabor.stefanik@nng.com>
parents: 36346
diff changeset
  1165
def _related(f1, f2):
30138
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
  1166
    """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
  1167
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
  1168
    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
  1169
    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
  1170
    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
  1171
    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
  1172
    """
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
  1173
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
  1174
    if f1 == f2:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
  1175
        return True  # a match
30138
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
  1176
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
  1177
    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
  1178
    try:
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
  1179
        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
  1180
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
  1181
        if f1r is None:
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
  1182
            f1 = next(g1)
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
  1183
        if f2r is None:
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
  1184
            f2 = next(g2)
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
  1185
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
  1186
        while True:
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
  1187
            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
  1188
            if f1r > f2r:
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
  1189
                f1 = next(g1)
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
  1190
            elif f2r > f1r:
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
  1191
                f2 = next(g2)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
  1192
            else:  # f1 and f2 point to files in the same linkrev
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
  1193
                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
  1194
    except StopIteration:
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
  1195
        return False
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
  1196
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
  1197
44092
833210fbd900 graftcopies: remove `skip` and `repo` arguments
Martin von Zweigbergk <martinvonz@google.com>
parents: 44091
diff changeset
  1198
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
  1199
    """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
  1200
06e7e7652ac0 graftcopies: document why the function is useful at all
Martin von Zweigbergk <martinvonz@google.com>
parents: 44092
diff changeset
  1201
    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
  1202
    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
  1203
    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
  1204
    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
  1205
    (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
  1206
    experimental.copytrace=off.
06e7e7652ac0 graftcopies: document why the function is useful at all
Martin von Zweigbergk <martinvonz@google.com>
parents: 44092
diff changeset
  1207
06e7e7652ac0 graftcopies: document why the function is useful at all
Martin von Zweigbergk <martinvonz@google.com>
parents: 44092
diff changeset
  1208
    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
  1209
    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
  1210
    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
  1211
    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
  1212
    by merge.update().
06e7e7652ac0 graftcopies: document why the function is useful at all
Martin von Zweigbergk <martinvonz@google.com>
parents: 44092
diff changeset
  1213
    """
44091
3df0bd706c40 graftcopies: use _filter() for filtering out invalid copies
Martin von Zweigbergk <martinvonz@google.com>
parents: 44090
diff changeset
  1214
    new_copies = pathcopies(base, ctx)
3df0bd706c40 graftcopies: use _filter() for filtering out invalid copies
Martin von Zweigbergk <martinvonz@google.com>
parents: 44090
diff changeset
  1215
    _filter(wctx.p1(), wctx, new_copies)
3df0bd706c40 graftcopies: use _filter() for filtering out invalid copies
Martin von Zweigbergk <martinvonz@google.com>
parents: 44090
diff changeset
  1216
    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
  1217
        wctx[dst].markcopied(src)