annotate mercurial/copies.py @ 46650:2803f94b7431

copies: filter out copies grafted from another branch Consider this simple history: ``` @ 3 modify y | o 2 copy x to y, modify x | | o 1 copy x to y, modify x |/ o 0 add x ``` If we now rebase commit 3 onto 1, Mercurial will look for copies between commit 2 and commit 1. It does that by going backwards from 2 to 0 and then forwards from 0 to 1. It will find that x was copied to y, since that was what happened on the path between them (namely in commit 1). That leads Mercurial to do a 3-way merge between y@3 and y@1 with x@2 as base. We want to use y@2 as base instead. That's also what happened until commit 1d6d1a15. This patch fixes the regression by adding another filtering step when chaining copies via a diffbase. The new filtering step removes copies that were the same between the two branches (same source and destination, but not necessarily the same contents). Differential Revision: https://phab.mercurial-scm.org/D10120
author Martin von Zweigbergk <martinvonz@google.com>
date Thu, 04 Mar 2021 08:20:19 -0800
parents 324ded1aa2ab
children d4ba4d51f85f
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
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
46302
599d247af600 copies: fix some comment in _filter
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46184
diff changeset
44 # in the following table (not including trivial cases). For example, case 6
42593
11ceb1b8fd74 copies: inline _chainandfilter() to prepare for next patch
Martin von Zweigbergk <martinvonz@google.com>
parents: 42592
diff changeset
45 # is where a file existed in 'src' and remained under that name in 'mid' and
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()):
46399
1d6d1a15a963 copies: simplify the conditional for _filter's case 3
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46398
diff changeset
62 if k == v: # case 3
42373
f3d06d37e194 copies: split up _chain() in naive chaining and filtering steps
Martin von Zweigbergk <martinvonz@google.com>
parents: 42344
diff changeset
63 del t[k]
46399
1d6d1a15a963 copies: simplify the conditional for _filter's case 3
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46398
diff changeset
64 elif v not in src: # case 5
1d6d1a15a963 copies: simplify the conditional for _filter's case 3
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46398
diff changeset
65 # remove copies from files that didn't exist
42373
f3d06d37e194 copies: split up _chain() in naive chaining and filtering steps
Martin von Zweigbergk <martinvonz@google.com>
parents: 42344
diff changeset
66 del t[k]
46398
154ded9104f1 copies: clarify which case some conditional are handling
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46397
diff changeset
67 elif k not in dst: # case 1
46399
1d6d1a15a963 copies: simplify the conditional for _filter's case 3
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46398
diff changeset
68 # remove copies to files that were then removed
42373
f3d06d37e194 copies: split up _chain() in naive chaining and filtering steps
Martin von Zweigbergk <martinvonz@google.com>
parents: 42344
diff changeset
69 del t[k]
f3d06d37e194 copies: split up _chain() in naive chaining and filtering steps
Martin von Zweigbergk <martinvonz@google.com>
parents: 42344
diff changeset
70
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
71
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
72 def _chain(prefix, suffix):
995066c41bb2 copies: expand `_chain` variable name to make the function easier to read
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43783
diff changeset
73 """chain two sets of copies 'prefix' and 'suffix'"""
995066c41bb2 copies: expand `_chain` variable name to make the function easier to read
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43783
diff changeset
74 result = prefix.copy()
995066c41bb2 copies: expand `_chain` variable name to make the function easier to read
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43783
diff changeset
75 for key, value in pycompat.iteritems(suffix):
995066c41bb2 copies: expand `_chain` variable name to make the function easier to read
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43783
diff changeset
76 result[key] = prefix.get(value, value)
995066c41bb2 copies: expand `_chain` variable name to make the function easier to read
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43783
diff changeset
77 return result
15775
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
78
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
79
43199
069cbbb53cdf copies: drop the findlimit logic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43198
diff changeset
80 def _tracefile(fctx, am, basemf):
35421
9cf37d111acb copies: consistently use """ for docstrings
Martin von Zweigbergk <martinvonz@google.com>
parents: 35420
diff changeset
81 """return file context that is the ancestor of fctx present in ancestor
43198
c16fe77e340a pathcopies: give up any optimization based on `introrev`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43148
diff changeset
82 manifest am
c16fe77e340a pathcopies: give up any optimization based on `introrev`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43148
diff changeset
83
c16fe77e340a pathcopies: give up any optimization based on `introrev`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43148
diff changeset
84 Note: we used to try and stop after a given limit, however checking if that
c16fe77e340a pathcopies: give up any optimization based on `introrev`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43148
diff changeset
85 limit is reached turned out to be very expensive. we are better off
c16fe77e340a pathcopies: give up any optimization based on `introrev`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43148
diff changeset
86 disabling that feature."""
15775
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
87
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
88 for f in fctx.ancestors():
42548
4ebbd7c4a3c5 copies: return only path from _tracefile() since that's all caller needs
Martin von Zweigbergk <martinvonz@google.com>
parents: 42520
diff changeset
89 path = f.path()
4ebbd7c4a3c5 copies: return only path from _tracefile() since that's all caller needs
Martin von Zweigbergk <martinvonz@google.com>
parents: 42520
diff changeset
90 if am.get(path, None) == f.filenode():
4ebbd7c4a3c5 copies: return only path from _tracefile() since that's all caller needs
Martin von Zweigbergk <martinvonz@google.com>
parents: 42520
diff changeset
91 return path
42595
819712deac69 copies: follow copies across merge base without source file (issue6163)
Martin von Zweigbergk <martinvonz@google.com>
parents: 42594
diff changeset
92 if basemf and basemf.get(path, None) == f.filenode():
819712deac69 copies: follow copies across merge base without source file (issue6163)
Martin von Zweigbergk <martinvonz@google.com>
parents: 42594
diff changeset
93 return path
15775
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
94
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
95
41752
012f695546aa copies: respect narrowmatcher in "parent -> working dir" case
Martin von Zweigbergk <martinvonz@google.com>
parents: 41724
diff changeset
96 def _dirstatecopies(repo, match=None):
012f695546aa copies: respect narrowmatcher in "parent -> working dir" case
Martin von Zweigbergk <martinvonz@google.com>
parents: 41724
diff changeset
97 ds = repo.dirstate
15775
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
98 c = ds.copies().copy()
34348
1a5abc45e2fa py3: explicitly convert dict.keys() and dict.items() into a list
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34311
diff changeset
99 for k in list(c):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
100 if ds[k] not in b'anm' or (match and not match(k)):
15775
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
101 del c[k]
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
102 return c
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
103
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
104
24782
4906dc0e038c copies: add matcher parameter to copy logic
Durham Goode <durham@fb.com>
parents: 24625
diff changeset
105 def _computeforwardmissing(a, b, match=None):
24011
d7d08337b3f6 copy: move _forwardcopies file logic to a function
Durham Goode <durham@fb.com>
parents: 24010
diff changeset
106 """Computes which files are in b but not a.
d7d08337b3f6 copy: move _forwardcopies file logic to a function
Durham Goode <durham@fb.com>
parents: 24010
diff changeset
107 This is its own function so extensions can easily wrap this call to see what
d7d08337b3f6 copy: move _forwardcopies file logic to a function
Durham Goode <durham@fb.com>
parents: 24010
diff changeset
108 files _forwardcopies is about to process.
d7d08337b3f6 copy: move _forwardcopies file logic to a function
Durham Goode <durham@fb.com>
parents: 24010
diff changeset
109 """
24782
4906dc0e038c copies: add matcher parameter to copy logic
Durham Goode <durham@fb.com>
parents: 24625
diff changeset
110 ma = a.manifest()
4906dc0e038c copies: add matcher parameter to copy logic
Durham Goode <durham@fb.com>
parents: 24625
diff changeset
111 mb = b.manifest()
31256
5a909a8098a1 copies: remove use of manifest.matches
Durham Goode <durham@fb.com>
parents: 30581
diff changeset
112 return mb.filesnotin(ma, match=match)
24011
d7d08337b3f6 copy: move _forwardcopies file logic to a function
Durham Goode <durham@fb.com>
parents: 24010
diff changeset
113
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
114
42115
27475ae67676 copies: extract function for deciding whether to use changeset-centric algos
Martin von Zweigbergk <martinvonz@google.com>
parents: 41936
diff changeset
115 def usechangesetcentricalgo(repo):
27475ae67676 copies: extract function for deciding whether to use changeset-centric algos
Martin von Zweigbergk <martinvonz@google.com>
parents: 41936
diff changeset
116 """Checks if we should use changeset-centric copy algorithms"""
43146
0171483b082f sidedatacopies: read rename information from sidedata
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43117
diff changeset
117 if repo.filecopiesmode == b'changeset-sidedata':
0171483b082f sidedatacopies: read rename information from sidedata
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43117
diff changeset
118 return True
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
119 readfrom = repo.ui.config(b'experimental', b'copies.read-from')
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
120 changesetsource = (b'changeset-only', b'compatibility')
43020
f3bcae1e9e23 copies: expand the logic of usechangesetcentricalgo
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 42707
diff changeset
121 return readfrom in changesetsource
42115
27475ae67676 copies: extract function for deciding whether to use changeset-centric algos
Martin von Zweigbergk <martinvonz@google.com>
parents: 41936
diff changeset
122
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
123
42595
819712deac69 copies: follow copies across merge base without source file (issue6163)
Martin von Zweigbergk <martinvonz@google.com>
parents: 42594
diff changeset
124 def _committedforwardcopies(a, b, base, match):
35422
8801cdcea01f copies: extract method for getting non-wdir forward copies
Martin von Zweigbergk <martinvonz@google.com>
parents: 35421
diff changeset
125 """Like _forwardcopies(), but b.rev() cannot be None (working copy)"""
20294
243ea5ffdf31 diff: search beyond ancestor when detecting renames
Mads Kiilerich <madski@unity3d.com>
parents: 19178
diff changeset
126 # files might have to be traced back to the fctx parent of the last
243ea5ffdf31 diff: search beyond ancestor when detecting renames
Mads Kiilerich <madski@unity3d.com>
parents: 19178
diff changeset
127 # one-side-only changeset, but not further back than that
40057
25b2868206e2 copies: add a devel debug mode to trace what copy tracing does
Boris Feld <boris.feld@octobus.net>
parents: 39966
diff changeset
128 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
129
42115
27475ae67676 copies: extract function for deciding whether to use changeset-centric algos
Martin von Zweigbergk <martinvonz@google.com>
parents: 41936
diff changeset
130 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
131 return _changesetforwardcopies(a, b, match)
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
132
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
133 debug = repo.ui.debugflag and repo.ui.configbool(b'devel', b'debug.copies')
40057
25b2868206e2 copies: add a devel debug mode to trace what copy tracing does
Boris Feld <boris.feld@octobus.net>
parents: 39966
diff changeset
134 dbg = repo.ui.debug
25b2868206e2 copies: add a devel debug mode to trace what copy tracing does
Boris Feld <boris.feld@octobus.net>
parents: 39966
diff changeset
135 if debug:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
136 dbg(b'debug.copies: looking into rename from %s to %s\n' % (a, b))
20294
243ea5ffdf31 diff: search beyond ancestor when detecting renames
Mads Kiilerich <madski@unity3d.com>
parents: 19178
diff changeset
137 am = a.manifest()
42595
819712deac69 copies: follow copies across merge base without source file (issue6163)
Martin von Zweigbergk <martinvonz@google.com>
parents: 42594
diff changeset
138 basemf = None if base is None else base.manifest()
20294
243ea5ffdf31 diff: search beyond ancestor when detecting renames
Mads Kiilerich <madski@unity3d.com>
parents: 19178
diff changeset
139
15775
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
140 # find where new files came from
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
141 # we currently don't try to find where old files went, too expensive
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
142 # this means we can miss a case like 'hg rm b; hg cp a b'
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
143 cm = {}
28000
d4247c306d82 copies: optimize forward copy detection logic for rebases
Durham Goode <durham@fb.com>
parents: 27876
diff changeset
144
d4247c306d82 copies: optimize forward copy detection logic for rebases
Durham Goode <durham@fb.com>
parents: 27876
diff changeset
145 # Computing the forward missing is quite expensive on large manifests, since
d4247c306d82 copies: optimize forward copy detection logic for rebases
Durham Goode <durham@fb.com>
parents: 27876
diff changeset
146 # it compares the entire manifests. We can optimize it in the common use
d4247c306d82 copies: optimize forward copy detection logic for rebases
Durham Goode <durham@fb.com>
parents: 27876
diff changeset
147 # case of computing what copies are in a commit versus its parent (like
d4247c306d82 copies: optimize forward copy detection logic for rebases
Durham Goode <durham@fb.com>
parents: 27876
diff changeset
148 # during a rebase or histedit). Note, we exclude merge commits from this
d4247c306d82 copies: optimize forward copy detection logic for rebases
Durham Goode <durham@fb.com>
parents: 27876
diff changeset
149 # optimization, since the ctx.files() for a merge commit is not correct for
d4247c306d82 copies: optimize forward copy detection logic for rebases
Durham Goode <durham@fb.com>
parents: 27876
diff changeset
150 # this comparison.
d4247c306d82 copies: optimize forward copy detection logic for rebases
Durham Goode <durham@fb.com>
parents: 27876
diff changeset
151 forwardmissingmatch = match
46113
59fa3890d40a node: import symbols explicitly
Joerg Sonnenberger <joerg@bec.de>
parents: 46109
diff changeset
152 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
153 filesmatcher = matchmod.exact(b.files())
33867
252fb66ee5bb copies: use intersectmatchers() in non-merge p1 optimization
Yuya Nishihara <yuya@tcha.org>
parents: 33822
diff changeset
154 forwardmissingmatch = matchmod.intersectmatchers(match, filesmatcher)
46408
e948ad0dcbe2 copies: add an devel option to trace all files
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46399
diff changeset
155 if repo.ui.configbool(b'devel', b'copy-tracing.trace-all-files'):
e948ad0dcbe2 copies: add an devel option to trace all files
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46399
diff changeset
156 missing = list(b.walk(match))
e948ad0dcbe2 copies: add an devel option to trace all files
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46399
diff changeset
157 # _computeforwardmissing(a, b, match=forwardmissingmatch)
e948ad0dcbe2 copies: add an devel option to trace all files
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46399
diff changeset
158 if debug:
e948ad0dcbe2 copies: add an devel option to trace all files
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46399
diff changeset
159 dbg(b'debug.copies: searching all files: %d\n' % len(missing))
e948ad0dcbe2 copies: add an devel option to trace all files
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46399
diff changeset
160 else:
e948ad0dcbe2 copies: add an devel option to trace all files
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46399
diff changeset
161 missing = _computeforwardmissing(a, b, match=forwardmissingmatch)
e948ad0dcbe2 copies: add an devel option to trace all files
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46399
diff changeset
162 if debug:
e948ad0dcbe2 copies: add an devel option to trace all files
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46399
diff changeset
163 dbg(
e948ad0dcbe2 copies: add an devel option to trace all files
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46399
diff changeset
164 b'debug.copies: missing files to search: %d\n'
e948ad0dcbe2 copies: add an devel option to trace all files
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46399
diff changeset
165 % len(missing)
e948ad0dcbe2 copies: add an devel option to trace all files
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46399
diff changeset
166 )
28000
d4247c306d82 copies: optimize forward copy detection logic for rebases
Durham Goode <durham@fb.com>
parents: 27876
diff changeset
167
23980
c1ce5442453f _adjustlinkrev: reuse ancestors set during rename detection (issue4514)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23139
diff changeset
168 ancestrycontext = a._repo.changelog.ancestors([b.rev()], inclusive=True)
40057
25b2868206e2 copies: add a devel debug mode to trace what copy tracing does
Boris Feld <boris.feld@octobus.net>
parents: 39966
diff changeset
169
42210
390ec72b8ea4 copies: process files in deterministic order for stable tests
Martin von Zweigbergk <martinvonz@google.com>
parents: 42169
diff changeset
170 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
171 if debug:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
172 dbg(b'debug.copies: tracing file: %s\n' % f)
23980
c1ce5442453f _adjustlinkrev: reuse ancestors set during rename detection (issue4514)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23139
diff changeset
173 fctx = b[f]
c1ce5442453f _adjustlinkrev: reuse ancestors set during rename detection (issue4514)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23139
diff changeset
174 fctx._ancestrycontext = ancestrycontext
40057
25b2868206e2 copies: add a devel debug mode to trace what copy tracing does
Boris Feld <boris.feld@octobus.net>
parents: 39966
diff changeset
175
40058
cf01616f8d96 copies: add time information to the debug information
Boris Feld <boris.feld@octobus.net>
parents: 40057
diff changeset
176 if debug:
cf01616f8d96 copies: add time information to the debug information
Boris Feld <boris.feld@octobus.net>
parents: 40057
diff changeset
177 start = util.timer()
43199
069cbbb53cdf copies: drop the findlimit logic
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43198
diff changeset
178 opath = _tracefile(fctx, am, basemf)
42548
4ebbd7c4a3c5 copies: return only path from _tracefile() since that's all caller needs
Martin von Zweigbergk <martinvonz@google.com>
parents: 42520
diff changeset
179 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
180 if debug:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
181 dbg(b'debug.copies: rename of: %s\n' % opath)
42548
4ebbd7c4a3c5 copies: return only path from _tracefile() since that's all caller needs
Martin von Zweigbergk <martinvonz@google.com>
parents: 42520
diff changeset
182 cm[f] = opath
40058
cf01616f8d96 copies: add time information to the debug information
Boris Feld <boris.feld@octobus.net>
parents: 40057
diff changeset
183 if debug:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
184 dbg(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
185 b'debug.copies: time: %f seconds\n'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
186 % (util.timer() - start)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
187 )
35422
8801cdcea01f copies: extract method for getting non-wdir forward copies
Martin von Zweigbergk <martinvonz@google.com>
parents: 35421
diff changeset
188 return cm
8801cdcea01f copies: extract method for getting non-wdir forward copies
Martin von Zweigbergk <martinvonz@google.com>
parents: 35421
diff changeset
189
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
190
46057
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46036
diff changeset
191 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
192 """returns a function that returns the following data given a <rev>"
43255
b8d60845fa5d copies: extract data extraction into a `revinfo` function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43254
diff changeset
193
b8d60845fa5d copies: extract data extraction into a `revinfo` function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43254
diff changeset
194 * p1: revision number of first parent
b8d60845fa5d copies: extract data extraction into a `revinfo` function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43254
diff changeset
195 * p2: revision number of first parent
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
196 * changes: a ChangingFiles object
43255
b8d60845fa5d copies: extract data extraction into a `revinfo` function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43254
diff changeset
197 """
b8d60845fa5d copies: extract data extraction into a `revinfo` function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43254
diff changeset
198 cl = repo.changelog
b8d60845fa5d copies: extract data extraction into a `revinfo` function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43254
diff changeset
199 parents = cl.parentrevs
45672
f877b3628015 copies: return None instead of ChangingFiles when relevant
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45670
diff changeset
200 flags = cl.flags
f877b3628015 copies: return None instead of ChangingFiles when relevant
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45670
diff changeset
201
f877b3628015 copies: return None instead of ChangingFiles when relevant
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45670
diff changeset
202 HASCOPIESINFO = flagutil.REVIDX_HASCOPIESINFO
43255
b8d60845fa5d copies: extract data extraction into a `revinfo` function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43254
diff changeset
203
45638
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45637
diff changeset
204 changelogrevision = cl.changelogrevision
43257
675c776fbcd1 sidedatacopies: directly fetch copies information from sidedata
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43256
diff changeset
205
46159
929054848d6c copies: properly match result during changeset centric copy tracing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46158
diff changeset
206 if rustmod is not None:
46057
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46036
diff changeset
207
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46036
diff changeset
208 def revinfo(rev):
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46036
diff changeset
209 p1, p2 = parents(rev)
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46036
diff changeset
210 if flags(rev) & HASCOPIESINFO:
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46036
diff changeset
211 raw = changelogrevision(rev)._sidedata.get(sidedatamod.SD_FILES)
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46036
diff changeset
212 else:
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46036
diff changeset
213 raw = None
46150
a132aa5979ec copies: no longer cache the ChangedFiles during copy tracing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
214 return (p1, p2, raw)
46057
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46036
diff changeset
215
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46036
diff changeset
216 else:
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46036
diff changeset
217
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46036
diff changeset
218 def revinfo(rev):
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46036
diff changeset
219 p1, p2 = parents(rev)
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46036
diff changeset
220 if flags(rev) & HASCOPIESINFO:
e0313b0a6f7e copies-rust: parse the changed-file sidedata directly in rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46036
diff changeset
221 changes = changelogrevision(rev).changes
46150
a132aa5979ec copies: no longer cache the ChangedFiles during copy tracing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
222 else:
a132aa5979ec copies: no longer cache the ChangedFiles during copy tracing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
223 changes = None
a132aa5979ec copies: no longer cache the ChangedFiles during copy tracing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46149
diff changeset
224 return (p1, p2, changes)
43255
b8d60845fa5d copies: extract data extraction into a `revinfo` function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43254
diff changeset
225
b8d60845fa5d copies: extract data extraction into a `revinfo` function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43254
diff changeset
226 return revinfo
b8d60845fa5d copies: extract data extraction into a `revinfo` function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43254
diff changeset
227
b8d60845fa5d copies: extract data extraction into a `revinfo` function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43254
diff changeset
228
45892
06b64fabf91c copies: cache the ancestor checking call when tracing copy
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45798
diff changeset
229 def cached_is_ancestor(is_ancestor):
06b64fabf91c copies: cache the ancestor checking call when tracing copy
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45798
diff changeset
230 """return a cached version of is_ancestor"""
06b64fabf91c copies: cache the ancestor checking call when tracing copy
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45798
diff changeset
231 cache = {}
06b64fabf91c copies: cache the ancestor checking call when tracing copy
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45798
diff changeset
232
06b64fabf91c copies: cache the ancestor checking call when tracing copy
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45798
diff changeset
233 def _is_ancestor(anc, desc):
06b64fabf91c copies: cache the ancestor checking call when tracing copy
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45798
diff changeset
234 if anc > desc:
06b64fabf91c copies: cache the ancestor checking call when tracing copy
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45798
diff changeset
235 return False
06b64fabf91c copies: cache the ancestor checking call when tracing copy
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45798
diff changeset
236 elif anc == desc:
06b64fabf91c copies: cache the ancestor checking call when tracing copy
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45798
diff changeset
237 return True
06b64fabf91c copies: cache the ancestor checking call when tracing copy
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45798
diff changeset
238 key = (anc, desc)
06b64fabf91c copies: cache the ancestor checking call when tracing copy
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45798
diff changeset
239 ret = cache.get(key)
06b64fabf91c copies: cache the ancestor checking call when tracing copy
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45798
diff changeset
240 if ret is None:
06b64fabf91c copies: cache the ancestor checking call when tracing copy
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45798
diff changeset
241 ret = cache[key] = is_ancestor(anc, desc)
06b64fabf91c copies: cache the ancestor checking call when tracing copy
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45798
diff changeset
242 return ret
06b64fabf91c copies: cache the ancestor checking call when tracing copy
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45798
diff changeset
243
06b64fabf91c copies: cache the ancestor checking call when tracing copy
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45798
diff changeset
244 return _is_ancestor
06b64fabf91c copies: cache the ancestor checking call when tracing copy
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45798
diff changeset
245
06b64fabf91c copies: cache the ancestor checking call when tracing copy
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45798
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 def _changesetforwardcopies(a, b, match):
46113
59fa3890d40a node: import symbols explicitly
Joerg Sonnenberger <joerg@bec.de>
parents: 46109
diff changeset
248 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
249 return {}
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
250
43256
00de32aa834e copies: use an unfiltered repository for the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43255
diff changeset
251 repo = a.repo().unfiltered()
41756
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
252 children = {}
43255
b8d60845fa5d copies: extract data extraction into a `revinfo` function
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43254
diff changeset
253
41756
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
254 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
255 isancestor = cl.isancestorrev
46149
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
256
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
257 # To track rename from "A" to B, we need to gather all parent → children
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
258 # edges that are contains in `::B` but not in `::A`.
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
259 #
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
260 #
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
261 # To do so, we need to gather all revisions exclusive¹ to "B" (ie¹: `::b -
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
262 # ::a`) and also all the "roots point", ie the parents of the exclusive set
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
263 # that belong to ::a. These are exactly all the revisions needed to express
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
264 # the parent → children we need to combine.
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
265 #
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
266 # [1] actually, we need to gather all the edges within `(::a)::b`, ie:
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
267 # excluding paths that leads to roots that are not ancestors of `a`. We
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
268 # keep this out of the explanation because it is hard enough without this special case..
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
269
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
270 parents = cl._uncheckedparentrevs
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
271 graph_roots = (nullrev, nullrev)
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
272
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
273 ancestors = cl.ancestors([a.rev()], inclusive=True)
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
274 revs = cl.findmissingrevs(common=[a.rev()], heads=[b.rev()])
43299
83bb1e89ab9b copies: compute the exact set of revision to walk
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43297
diff changeset
275 roots = set()
46149
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
276 has_graph_roots = False
46588
47557ea79fc7 copies-rust: move CPU-heavy Rust processing into a child thread
Simon Sapin <simon.sapin@octobus.net>
parents: 46569
diff changeset
277 multi_thread = repo.ui.configbool(b'devel', b'copy-tracing.multi-thread')
46149
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 # 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
280 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
281 ps = parents(r)
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
282 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
283 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
284 else:
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
285 p1, p2 = ps
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
286
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
287 # 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
288 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
289 roots.add(p1)
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
290 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
291 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
292 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
293 # 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
294 return {}
46149
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
295 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
296 # 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
297 # 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
298 roots = list(roots)
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
299 m = min(roots)
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
300 h = [b.rev()]
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
301 roots_to_head = 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
302 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
303 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
304
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
305 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
306 # 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
307 # 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
308 # 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
309 # 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
310 #
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
311 # 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
312 # 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
313 # 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
314 # processed.
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
315 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
316 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
317 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
318 if p == nullrev:
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
319 continue
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
320 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
321 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
322 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
323 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
324 return _combine_changeset_copies(
46588
47557ea79fc7 copies-rust: move CPU-heavy Rust processing into a child thread
Simon Sapin <simon.sapin@octobus.net>
parents: 46569
diff changeset
325 revs,
47557ea79fc7 copies-rust: move CPU-heavy Rust processing into a child thread
Simon Sapin <simon.sapin@octobus.net>
parents: 46569
diff changeset
326 children_count,
47557ea79fc7 copies-rust: move CPU-heavy Rust processing into a child thread
Simon Sapin <simon.sapin@octobus.net>
parents: 46569
diff changeset
327 b.rev(),
47557ea79fc7 copies-rust: move CPU-heavy Rust processing into a child thread
Simon Sapin <simon.sapin@octobus.net>
parents: 46569
diff changeset
328 revinfo,
47557ea79fc7 copies-rust: move CPU-heavy Rust processing into a child thread
Simon Sapin <simon.sapin@octobus.net>
parents: 46569
diff changeset
329 match,
47557ea79fc7 copies-rust: move CPU-heavy Rust processing into a child thread
Simon Sapin <simon.sapin@octobus.net>
parents: 46569
diff changeset
330 isancestor,
47557ea79fc7 copies-rust: move CPU-heavy Rust processing into a child thread
Simon Sapin <simon.sapin@octobus.net>
parents: 46569
diff changeset
331 multi_thread,
45637
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
332 )
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
333 else:
46149
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
334 # 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
335 # 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
336 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
337 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
338 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
339 if p == nullrev:
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
340 continue
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
341 children[r] = []
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
342 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
343 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
344 x = revs.pop()
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
345 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
346 revs.extend(roots)
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
347 revs.sort()
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
348
45638
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45637
diff changeset
349 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
350 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
351 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
352 )
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
353
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
354
45624
fb000408bca5 copies: rename some function to the new naming scheme
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44994
diff changeset
355 def _combine_changeset_copies(
46588
47557ea79fc7 copies-rust: move CPU-heavy Rust processing into a child thread
Simon Sapin <simon.sapin@octobus.net>
parents: 46569
diff changeset
356 revs, children_count, targetrev, revinfo, match, isancestor, multi_thread
44758
45f3f35cefe7 copies: fix the changeset based algorithm regarding merge
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44276
diff changeset
357 ):
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
358 """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
359
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
360 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
361 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
362 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
363 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
364 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
365
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
366 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
367 """
45962
a66568f20ddc copies: use the rust code for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45942
diff changeset
368
a66568f20ddc copies: use the rust code for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45942
diff changeset
369 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
370
46159
929054848d6c copies: properly match result during changeset centric copy tracing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46158
diff changeset
371 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
372 final_copies = rustmod.combine_changeset_copies(
46588
47557ea79fc7 copies-rust: move CPU-heavy Rust processing into a child thread
Simon Sapin <simon.sapin@octobus.net>
parents: 46569
diff changeset
373 list(revs), children_count, targetrev, revinfo, multi_thread
45962
a66568f20ddc copies: use the rust code for `combine_changeset_copies`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45942
diff changeset
374 )
46158
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
375 else:
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
376 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
377
46158
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
378 all_copies = {}
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
379 # 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
380 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
381 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
382 current_copies = None
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
383 # 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
384 # 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
385 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
386 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
387 continue
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
388 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
389 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
390 continue
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
391 remaining_children -= 1
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
392 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
393 if remaining_children:
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
394 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
395 else:
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
396 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
397
46158
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
398 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
399 # this is a root
46184
cb8b2ee89a5d copies: stop attempt to avoid extra dict copies around branching
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46183
diff changeset
400 newcopies = copies = {}
cb8b2ee89a5d copies: stop attempt to avoid extra dict copies around branching
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46183
diff changeset
401 elif remaining_children:
cb8b2ee89a5d copies: stop attempt to avoid extra dict copies around branching
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46183
diff changeset
402 newcopies = copies.copy()
cb8b2ee89a5d copies: stop attempt to avoid extra dict copies around branching
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46183
diff changeset
403 else:
cb8b2ee89a5d copies: stop attempt to avoid extra dict copies around branching
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46183
diff changeset
404 newcopies = copies
46158
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
405 # 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
406 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
407 childcopies = {}
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
408 if parent == 1:
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
409 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
410 elif parent == 2:
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
411 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
412
46158
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
413 if childcopies:
46149
294d5aca4ff5 copies: iterate over children directly (instead of parents)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46148
diff changeset
414 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
415 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
416 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
417 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
418 source = prev[1]
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
419 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
420 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
421 if changes.removed:
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
422 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
423 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
424 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
425 # 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
426 # 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
427 # could be avoided.
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
428 newcopies = copies.copy()
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
429 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
430 # 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
431 # 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
432 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
433 current_copies = newcopies
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
434 else:
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
435 # 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
436 # 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
437 #
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
438 # 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
439 # 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
440 # 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
441 # 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
442 assert parent == 2
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
443 current_copies = _merge_copies_dict(
46563
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
444 newcopies,
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
445 current_copies,
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
446 isancestor,
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
447 changes,
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
448 current_rev,
46158
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
449 )
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
450 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
451
46158
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
452 # 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
453 final_copies = {}
1fcfff09cac5 copies: avoid early return in _combine_changeset_copies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46150
diff changeset
454 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
455 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
456 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
457 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
458 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
459 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
460 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
461 return final_copies
45f3f35cefe7 copies: fix the changeset based algorithm regarding merge
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44276
diff changeset
462
45f3f35cefe7 copies: fix the changeset based algorithm regarding merge
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44276
diff changeset
463
46161
3a0c41336961 copies: extract value comparison in the python copy tracing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46159
diff changeset
464 # constant to decide which side to pick with _merge_copies_dict
3a0c41336961 copies: extract value comparison in the python copy tracing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46159
diff changeset
465 PICK_MINOR = 0
3a0c41336961 copies: extract value comparison in the python copy tracing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46159
diff changeset
466 PICK_MAJOR = 1
3a0c41336961 copies: extract value comparison in the python copy tracing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46159
diff changeset
467 PICK_EITHER = 2
3a0c41336961 copies: extract value comparison in the python copy tracing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46159
diff changeset
468
3a0c41336961 copies: extract value comparison in the python copy tracing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46159
diff changeset
469
46563
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
470 def _merge_copies_dict(minor, major, isancestor, changes, current_merge):
44758
45f3f35cefe7 copies: fix the changeset based algorithm regarding merge
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44276
diff changeset
471 """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
472
45f3f35cefe7 copies: fix the changeset based algorithm regarding merge
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44276
diff changeset
473 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
474
45f3f35cefe7 copies: fix the changeset based algorithm regarding merge
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44276
diff changeset
475 - `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
476 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
477
45f3f35cefe7 copies: fix the changeset based algorithm regarding merge
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44276
diff changeset
478 - `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
479 current revision,
45986
f9f8d8aa9a92 copies: clarify the return of _merge_copies_dict
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45985
diff changeset
480
f9f8d8aa9a92 copies: clarify the return of _merge_copies_dict
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45985
diff changeset
481 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
482 """
45f3f35cefe7 copies: fix the changeset based algorithm regarding merge
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44276
diff changeset
483 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
484 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
485 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
486 minor[dest] = value
45f3f35cefe7 copies: fix the changeset based algorithm regarding merge
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44276
diff changeset
487 else:
46563
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
488 pick, overwrite = _compare_values(
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
489 changes, isancestor, dest, other, value
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
490 )
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
491 if overwrite:
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
492 if pick == PICK_MAJOR:
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
493 minor[dest] = (current_merge, value[1])
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
494 else:
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
495 minor[dest] = (current_merge, other[1])
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
496 elif pick == PICK_MAJOR:
45670
a8fb29b05f92 salvaged: properly deal with salvaged file during copy tracing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45640
diff changeset
497 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
498 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
499
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
500
46162
6b9d65298484 copies: rename value/other variable to minor/major for clarity
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46161
diff changeset
501 def _compare_values(changes, isancestor, dest, minor, major):
46562
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46410
diff changeset
502 """compare two value within a _merge_copies_dict loop iteration
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46410
diff changeset
503
46563
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
504 return (pick, overwrite).
46562
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46410
diff changeset
505
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46410
diff changeset
506 - pick is one of PICK_MINOR, PICK_MAJOR or PICK_EITHER
46563
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
507 - overwrite is True if pick is a return of an ambiguity that needs resolution.
46562
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46410
diff changeset
508 """
46183
ee63c1173c1b copies: deal with the "same revision" special case earlier
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46162
diff changeset
509 major_tt, major_value = major
ee63c1173c1b copies: deal with the "same revision" special case earlier
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46162
diff changeset
510 minor_tt, minor_value = minor
46161
3a0c41336961 copies: extract value comparison in the python copy tracing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46159
diff changeset
511
46183
ee63c1173c1b copies: deal with the "same revision" special case earlier
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46162
diff changeset
512 if major_tt == minor_tt:
ee63c1173c1b copies: deal with the "same revision" special case earlier
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46162
diff changeset
513 # if it comes from the same revision it must be the same value
ee63c1173c1b copies: deal with the "same revision" special case earlier
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46162
diff changeset
514 assert major_value == minor_value
46563
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
515 return PICK_EITHER, False
46562
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46410
diff changeset
516 elif (
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46410
diff changeset
517 changes is not None
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46410
diff changeset
518 and minor_value is not None
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46410
diff changeset
519 and major_value is None
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46410
diff changeset
520 and dest in changes.salvaged
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46410
diff changeset
521 ):
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46410
diff changeset
522 # In this case, a deletion was reverted, the "alive" value overwrite
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46410
diff changeset
523 # the deleted one.
46563
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
524 return PICK_MINOR, True
46562
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46410
diff changeset
525 elif (
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46410
diff changeset
526 changes is not None
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46410
diff changeset
527 and major_value is not None
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46410
diff changeset
528 and minor_value is None
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46410
diff changeset
529 and dest in changes.salvaged
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46410
diff changeset
530 ):
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46410
diff changeset
531 # In this case, a deletion was reverted, the "alive" value overwrite
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46410
diff changeset
532 # the deleted one.
46563
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
533 return PICK_MAJOR, True
46562
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46410
diff changeset
534 elif isancestor(minor_tt, major_tt):
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46410
diff changeset
535 if changes is not None and dest in changes.merged:
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46410
diff changeset
536 # change to dest happened on the branch without copy-source change,
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46410
diff changeset
537 # so both source are valid and "major" wins.
46563
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
538 return PICK_MAJOR, True
46562
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46410
diff changeset
539 else:
46563
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
540 return PICK_MAJOR, False
46562
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46410
diff changeset
541 elif isancestor(major_tt, minor_tt):
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46410
diff changeset
542 if changes is not None and dest in changes.merged:
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46410
diff changeset
543 # change to dest happened on the branch without copy-source change,
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46410
diff changeset
544 # so both source are valid and "major" wins.
46563
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
545 return PICK_MAJOR, True
46562
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46410
diff changeset
546 else:
46563
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
547 return PICK_MINOR, False
46562
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46410
diff changeset
548 elif minor_value is None:
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46410
diff changeset
549 # in case of conflict, the "alive" side wins.
46563
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
550 return PICK_MAJOR, True
46562
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46410
diff changeset
551 elif major_value is None:
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46410
diff changeset
552 # in case of conflict, the "alive" side wins.
46563
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
553 return PICK_MINOR, True
46562
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46410
diff changeset
554 else:
c692384bb559 copies: rearrange all value comparison conditional
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46410
diff changeset
555 # in case of conflict where both side are alive, major wins.
46563
c19c662097e1 copies: detect case when a merge decision overwrite previous data
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46562
diff changeset
556 return PICK_MAJOR, True
46161
3a0c41336961 copies: extract value comparison in the python copy tracing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46159
diff changeset
557
3a0c41336961 copies: extract value comparison in the python copy tracing
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46159
diff changeset
558
45638
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45637
diff changeset
559 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
560 """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
561
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45637
diff changeset
562 * 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
563 * 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
564 * 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
565 * 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
566 * 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
567 * 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
568 """
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45637
diff changeset
569 cl = repo.changelog
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45637
diff changeset
570 parents = cl.parentrevs
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45637
diff changeset
571
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45637
diff changeset
572 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
573 ctx = repo[rev]
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45637
diff changeset
574
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45637
diff changeset
575 def ismerged(path):
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45637
diff changeset
576 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
577 return False
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45637
diff changeset
578 fctx = ctx[path]
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45637
diff changeset
579 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
580 nb_parents = 0
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45637
diff changeset
581 for n in parents:
46113
59fa3890d40a node: import symbols explicitly
Joerg Sonnenberger <joerg@bec.de>
parents: 46109
diff changeset
582 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
583 nb_parents += 1
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45637
diff changeset
584 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
585
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45637
diff changeset
586 return ismerged
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45637
diff changeset
587
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45637
diff changeset
588 def revinfo(rev):
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45637
diff changeset
589 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
590 ctx = repo[rev]
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45637
diff changeset
591 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
592 removed = ctx.filesremoved()
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45637
diff changeset
593 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
594
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45637
diff changeset
595 return revinfo
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45637
diff changeset
596
4f876e6b30fa copies: use dedicated `_revinfo_getter` function and call
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45637
diff changeset
597
45637
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
598 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
599 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
600 ):
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
601 """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
602 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
603 all_copies = {}
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
604 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
605 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
606 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
607 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
608 # 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
609 copies = {}
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
610 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
611 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
612 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
613 parent = 1
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
614 childcopies = p1copies
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
615 else:
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
616 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
617 parent = 2
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
618 childcopies = p2copies
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
619 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
620 childcopies = {
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
621 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
622 }
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
623 newcopies = copies
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
624 if childcopies:
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
625 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
626 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
627 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
628 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
629 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
630 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
631 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
632 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
633 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
634 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
635 # 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
636 # 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
637 # 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
638 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
639 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
640 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
641 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
642 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
643 else:
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
644 # 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
645 # 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
646 #
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
647 # 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
648 # 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
649 # 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
650 # 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
651 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
652 _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
653 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
654 )
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
655 else:
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
656 _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
657 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
658 )
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
659 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
660
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
661 final_copies = {}
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
662 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
663 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
664 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
665 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
666
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
667
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
668 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
669 """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
670 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
671 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
672 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
673 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
674 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
675 else:
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
676 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
677 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
678 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
679 continue
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
680 # 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
681 # 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
682 if (
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
683 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
684 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
685 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
686 ):
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
687 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
688
ad6ebb6f0dfe copies: make two version of the changeset centric algorithm
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 45624
diff changeset
689
42595
819712deac69 copies: follow copies across merge base without source file (issue6163)
Martin von Zweigbergk <martinvonz@google.com>
parents: 42594
diff changeset
690 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
691 """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
692
42595
819712deac69 copies: follow copies across merge base without source file (issue6163)
Martin von Zweigbergk <martinvonz@google.com>
parents: 42594
diff changeset
693 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
694 base = a
40448
873f3682c8af narrow: make copies.pathcopies() filter with narrowspec again
Martin von Zweigbergk <martinvonz@google.com>
parents: 40076
diff changeset
695 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
696 # check for working copy
8801cdcea01f copies: extract method for getting non-wdir forward copies
Martin von Zweigbergk <martinvonz@google.com>
parents: 35421
diff changeset
697 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
698 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
699 # 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
700 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
701 else:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
702 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
703 return copies
15775
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
704
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
705
41753
3158cb74fbca copies: make _backwardrenames() filter out copies by destination
Martin von Zweigbergk <martinvonz@google.com>
parents: 41752
diff changeset
706 def _backwardrenames(a, b, match):
46648
eca88f5fbcb2 copies: extract function _backwardcopies() for reversing renames
Martin von Zweigbergk <martinvonz@google.com>
parents: 46634
diff changeset
707 """find renames from a to b"""
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
708 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
709 return {}
38f92d12357c copy: add flag for disabling copy tracing
Durham Goode <durham@fb.com>
parents: 25924
diff changeset
710
46648
eca88f5fbcb2 copies: extract function _backwardcopies() for reversing renames
Martin von Zweigbergk <martinvonz@google.com>
parents: 46634
diff changeset
711 # We don't want to pass in "match" here, since that would filter
eca88f5fbcb2 copies: extract function _backwardcopies() for reversing renames
Martin von Zweigbergk <martinvonz@google.com>
parents: 46634
diff changeset
712 # the destination by it. Since we're reversing the copies, we want
eca88f5fbcb2 copies: extract function _backwardcopies() for reversing renames
Martin von Zweigbergk <martinvonz@google.com>
parents: 46634
diff changeset
713 # to filter the source instead.
eca88f5fbcb2 copies: extract function _backwardcopies() for reversing renames
Martin von Zweigbergk <martinvonz@google.com>
parents: 46634
diff changeset
714 copies = _forwardcopies(b, a)
eca88f5fbcb2 copies: extract function _backwardcopies() for reversing renames
Martin von Zweigbergk <martinvonz@google.com>
parents: 46634
diff changeset
715 return _reverse_renames(copies, a, match)
eca88f5fbcb2 copies: extract function _backwardcopies() for reversing renames
Martin von Zweigbergk <martinvonz@google.com>
parents: 46634
diff changeset
716
eca88f5fbcb2 copies: extract function _backwardcopies() for reversing renames
Martin von Zweigbergk <martinvonz@google.com>
parents: 46634
diff changeset
717
eca88f5fbcb2 copies: extract function _backwardcopies() for reversing renames
Martin von Zweigbergk <martinvonz@google.com>
parents: 46634
diff changeset
718 def _reverse_renames(copies, dst, match):
eca88f5fbcb2 copies: extract function _backwardcopies() for reversing renames
Martin von Zweigbergk <martinvonz@google.com>
parents: 46634
diff changeset
719 """given copies to context 'dst', finds renames from that context"""
18136
f23dea2b296e copies: do not track backward copies, only renames (issue3739)
Siddharth Agarwal <sid0@fb.com>
parents: 18135
diff changeset
720 # 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
721 # 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
722 # arbitrarily pick one of the renames.
15775
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
723 r = {}
46648
eca88f5fbcb2 copies: extract function _backwardcopies() for reversing renames
Martin von Zweigbergk <martinvonz@google.com>
parents: 46634
diff changeset
724 for k, v in sorted(pycompat.iteritems(copies)):
41753
3158cb74fbca copies: make _backwardrenames() filter out copies by destination
Martin von Zweigbergk <martinvonz@google.com>
parents: 41752
diff changeset
725 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
726 continue
18136
f23dea2b296e copies: do not track backward copies, only renames (issue3739)
Siddharth Agarwal <sid0@fb.com>
parents: 18135
diff changeset
727 # remove copies
46648
eca88f5fbcb2 copies: extract function _backwardcopies() for reversing renames
Martin von Zweigbergk <martinvonz@google.com>
parents: 46634
diff changeset
728 if v in dst:
18136
f23dea2b296e copies: do not track backward copies, only renames (issue3739)
Siddharth Agarwal <sid0@fb.com>
parents: 18135
diff changeset
729 continue
15775
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
730 r[v] = k
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
731 return r
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
732
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
733
24782
4906dc0e038c copies: add matcher parameter to copy logic
Durham Goode <durham@fb.com>
parents: 24625
diff changeset
734 def pathcopies(x, y, match=None):
35421
9cf37d111acb copies: consistently use """ for docstrings
Martin von Zweigbergk <martinvonz@google.com>
parents: 35420
diff changeset
735 """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
736 repo = x._repo
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
737 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
738 if debug:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
739 repo.ui.debug(
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
740 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
741 )
15775
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
742 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
743 return {}
44276
30862e226339 copies: avoid filtering by short-circuit dirstate-only copies earlier
Martin von Zweigbergk <martinvonz@google.com>
parents: 44237
diff changeset
744 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
745 if debug:
30862e226339 copies: avoid filtering by short-circuit dirstate-only copies earlier
Martin von Zweigbergk <martinvonz@google.com>
parents: 44237
diff changeset
746 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
747 # 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
748 return _dirstatecopies(repo, match)
15775
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
749 a = y.ancestor(x)
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
750 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
751 if debug:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
752 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
753 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
754 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
755 if debug:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
756 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
757 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
758 else:
a48f6f18dc6d copies: remove most early returns from pathcopies() and _forwardcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42591
diff changeset
759 if debug:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
760 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
761 base = None
46113
59fa3890d40a node: import symbols explicitly
Joerg Sonnenberger <joerg@bec.de>
parents: 46109
diff changeset
762 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
763 base = x
46649
324ded1aa2ab copies: inline _backwardrenames() in pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 46648
diff changeset
764 x_copies = _forwardcopies(a, x)
324ded1aa2ab copies: inline _backwardrenames() in pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 46648
diff changeset
765 y_copies = _forwardcopies(a, y, base, match=match)
46650
2803f94b7431 copies: filter out copies grafted from another branch
Martin von Zweigbergk <martinvonz@google.com>
parents: 46649
diff changeset
766 same_keys = set(x_copies) & set(y_copies)
2803f94b7431 copies: filter out copies grafted from another branch
Martin von Zweigbergk <martinvonz@google.com>
parents: 46649
diff changeset
767 for k in same_keys:
2803f94b7431 copies: filter out copies grafted from another branch
Martin von Zweigbergk <martinvonz@google.com>
parents: 46649
diff changeset
768 if x_copies.get(k) == y_copies.get(k):
2803f94b7431 copies: filter out copies grafted from another branch
Martin von Zweigbergk <martinvonz@google.com>
parents: 46649
diff changeset
769 del x_copies[k]
2803f94b7431 copies: filter out copies grafted from another branch
Martin von Zweigbergk <martinvonz@google.com>
parents: 46649
diff changeset
770 del y_copies[k]
46649
324ded1aa2ab copies: inline _backwardrenames() in pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 46648
diff changeset
771 x_backward_renames = _reverse_renames(x_copies, x, match)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
772 copies = _chain(
46649
324ded1aa2ab copies: inline _backwardrenames() in pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 46648
diff changeset
773 x_backward_renames,
324ded1aa2ab copies: inline _backwardrenames() in pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 46648
diff changeset
774 y_copies,
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
775 )
42594
d013099c551b copies: filter invalid copies only at end of pathcopies() (issue6163)
Martin von Zweigbergk <martinvonz@google.com>
parents: 42593
diff changeset
776 _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
777 return copies
15774
0bd17a4bed88 copies: split the copies api for "normal" and merge cases (API)
Matt Mackall <mpm@selenic.com>
parents: 14494
diff changeset
778
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
779
30186
f7ed5af31242 mergecopies: rename 'ca' to 'base'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30185
diff changeset
780 def mergecopies(repo, c1, c2, base):
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
781 """
42118
967c098eed33 copies: move comment about implementation of mergecopies() to end
Martin von Zweigbergk <martinvonz@google.com>
parents: 42115
diff changeset
782 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
783 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
784
b4b196092cc3 copytrace: move the default copytracing algorithm in a new function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34077
diff changeset
785 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
786 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
787 For example:
33822
42ad7cc645a4 copies: add more details to the documentation of mergecopies()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32640
diff changeset
788
42ad7cc645a4 copies: add more details to the documentation of mergecopies()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32640
diff changeset
789 o ---> 4 another commit
42ad7cc645a4 copies: add more details to the documentation of mergecopies()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32640
diff changeset
790 |
42ad7cc645a4 copies: add more details to the documentation of mergecopies()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32640
diff changeset
791 | 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
792 | /
42ad7cc645a4 copies: add more details to the documentation of mergecopies()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32640
diff changeset
793 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
794 |/
42ad7cc645a4 copies: add more details to the documentation of mergecopies()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32640
diff changeset
795 o ---> 1 merge base
42ad7cc645a4 copies: add more details to the documentation of mergecopies()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32640
diff changeset
796
42ad7cc645a4 copies: add more details to the documentation of mergecopies()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32640
diff changeset
797 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
798 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
799 message:
42ad7cc645a4 copies: add more details to the documentation of mergecopies()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32640
diff changeset
800
42ad7cc645a4 copies: add more details to the documentation of mergecopies()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32640
diff changeset
801 ```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
802
44199
7f8bdee0034e copies: define a type to return from mergecopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 44197
diff changeset
803 Returns a tuple where:
16168
7bbabfe25321 copies: add docstring for mergecopies
Matt Mackall <mpm@selenic.com>
parents: 15994
diff changeset
804
44199
7f8bdee0034e copies: define a type to return from mergecopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 44197
diff changeset
805 "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
806
16168
7bbabfe25321 copies: add docstring for mergecopies
Matt Mackall <mpm@selenic.com>
parents: 15994
diff changeset
807 "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
808 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
809
42118
967c098eed33 copies: move comment about implementation of mergecopies() to end
Martin von Zweigbergk <martinvonz@google.com>
parents: 42115
diff changeset
810 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
811 """
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
812 # 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
813 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
814 return branch_copies(), branch_copies(), {}
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
815
41752
012f695546aa copies: respect narrowmatcher in "parent -> working dir" case
Martin von Zweigbergk <martinvonz@google.com>
parents: 41724
diff changeset
816 narrowmatch = c1.repo().narrowmatch()
012f695546aa copies: respect narrowmatcher in "parent -> working dir" case
Martin von Zweigbergk <martinvonz@google.com>
parents: 41724
diff changeset
817
6646
9eb274d773d9 copies: teach copies about dirstate.copies
Matt Mackall <mpm@selenic.com>
parents: 6431
diff changeset
818 # avoid silly behavior for parent -> working dir
13878
a8d13ee0ce68 misc: replace .parents()[0] with p1()
Matt Mackall <mpm@selenic.com>
parents: 12683
diff changeset
819 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
820 return (
fa9ad1da2e77 merge: start using the per-side copy dicts
Martin von Zweigbergk <martinvonz@google.com>
parents: 44199
diff changeset
821 branch_copies(_dirstatecopies(repo, narrowmatch)),
fa9ad1da2e77 merge: start using the per-side copy dicts
Martin von Zweigbergk <martinvonz@google.com>
parents: 44199
diff changeset
822 branch_copies(),
fa9ad1da2e77 merge: start using the per-side copy dicts
Martin von Zweigbergk <martinvonz@google.com>
parents: 44199
diff changeset
823 {},
fa9ad1da2e77 merge: start using the per-side copy dicts
Martin von Zweigbergk <martinvonz@google.com>
parents: 44199
diff changeset
824 )
6646
9eb274d773d9 copies: teach copies about dirstate.copies
Matt Mackall <mpm@selenic.com>
parents: 6431
diff changeset
825
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
826 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
827 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
828 # 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
829 # 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
830 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
831
42226
a6be3af3a397 copies: ignore heuristics copytracing when using changeset-centric algos
Martin von Zweigbergk <martinvonz@google.com>
parents: 42225
diff changeset
832 if usechangesetcentricalgo(repo):
a6be3af3a397 copies: ignore heuristics copytracing when using changeset-centric algos
Martin von Zweigbergk <martinvonz@google.com>
parents: 42225
diff changeset
833 # 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
834 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
835
26013
38f92d12357c copy: add flag for disabling copy tracing
Durham Goode <durham@fb.com>
parents: 25924
diff changeset
836 # 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
837 # 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
838 # rebase.
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
839 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
840 # 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
841 # 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
842 # 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
843 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
844 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
845 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
846 else:
b4b196092cc3 copytrace: move the default copytracing algorithm in a new function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34077
diff changeset
847 return _fullcopytracing(repo, c1, c2, base)
26013
38f92d12357c copy: add flag for disabling copy tracing
Durham Goode <durham@fb.com>
parents: 25924
diff changeset
848
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
849
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
850 def _isfullcopytraceable(repo, c1, base):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45892
diff changeset
851 """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
852 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
853 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
854
e79b3611223b copies: add docs for config `experimental.copytrace.sourcecommitlimit`
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34366
diff changeset
855 `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
856 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
857 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
858 """
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
859 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
860 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
861 if c1.mutable() and base.mutable():
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
862 sourcecommitlimit = repo.ui.configint(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
863 b'experimental', b'copytrace.sourcecommitlimit'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
864 )
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
865 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
866 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
867 return False
fc3b8483c6cb copytrace: use the full copytracing method if only drafts are involved
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34179
diff changeset
868
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
869
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
870 def _checksinglesidecopies(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
871 src, dsts1, m1, m2, mb, c2, base, copy, renamedelete
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
872 ):
42222
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
873 if src not in m2:
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
874 # deleted on side 2
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
875 if src not in m1:
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
876 # 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
877 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
878 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
879 # 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
880 # 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
881 # 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
882 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
883 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
884 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
885 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
886 # modified on side 2
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
887 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
888 copy[dst] = src
42222
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
889
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
890
44199
7f8bdee0034e copies: define a type to return from mergecopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 44197
diff changeset
891 class branch_copies(object):
7f8bdee0034e copies: define a type to return from mergecopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 44197
diff changeset
892 """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
893
7f8bdee0034e copies: define a type to return from mergecopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 44197
diff changeset
894 "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
895 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
896
7f8bdee0034e copies: define a type to return from mergecopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 44197
diff changeset
897 "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
898 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
899 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
900 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
901
7f8bdee0034e copies: define a type to return from mergecopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 44197
diff changeset
902 "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
903 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
904
7f8bdee0034e copies: define a type to return from mergecopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 44197
diff changeset
905 "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
906 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
907 renamed directories.
7f8bdee0034e copies: define a type to return from mergecopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 44197
diff changeset
908 """
7f8bdee0034e copies: define a type to return from mergecopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 44197
diff changeset
909
7f8bdee0034e copies: define a type to return from mergecopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 44197
diff changeset
910 def __init__(
7f8bdee0034e copies: define a type to return from mergecopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 44197
diff changeset
911 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
912 ):
7f8bdee0034e copies: define a type to return from mergecopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 44197
diff changeset
913 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
914 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
915 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
916 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
917
44994
cfd06649a1b8 copies: implement __repr__ on branch_copies for debugging
Martin von Zweigbergk <martinvonz@google.com>
parents: 44940
diff changeset
918 def __repr__(self):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45892
diff changeset
919 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
920 self.copy,
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45892
diff changeset
921 self.renamedelete,
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45892
diff changeset
922 self.dirmove,
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45892
diff changeset
923 self.movewithdir,
44994
cfd06649a1b8 copies: implement __repr__ on branch_copies for debugging
Martin von Zweigbergk <martinvonz@google.com>
parents: 44940
diff changeset
924 )
cfd06649a1b8 copies: implement __repr__ on branch_copies for debugging
Martin von Zweigbergk <martinvonz@google.com>
parents: 44940
diff changeset
925
44199
7f8bdee0034e copies: define a type to return from mergecopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 44197
diff changeset
926
34078
b4b196092cc3 copytrace: move the default copytracing algorithm in a new function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34077
diff changeset
927 def _fullcopytracing(repo, c1, c2, base):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45892
diff changeset
928 """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
929 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
930 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
931
b4b196092cc3 copytrace: move the default copytracing algorithm in a new function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34077
diff changeset
932 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
933 the copies.
b4b196092cc3 copytrace: move the default copytracing algorithm in a new function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34077
diff changeset
934 """
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
935 m1 = c1.manifest()
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
936 m2 = c2.manifest()
30186
f7ed5af31242 mergecopies: rename 'ca' to 'base'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30185
diff changeset
937 mb = base.manifest()
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
938
42222
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
939 copies1 = pathcopies(base, c1)
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
940 copies2 = pathcopies(base, c2)
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
941
44162
baf3fe2977cc copies: move early return in mergecopies() earlier
Martin von Zweigbergk <martinvonz@google.com>
parents: 44093
diff changeset
942 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
943 return branch_copies(), branch_copies(), {}
44162
baf3fe2977cc copies: move early return in mergecopies() earlier
Martin von Zweigbergk <martinvonz@google.com>
parents: 44093
diff changeset
944
42222
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
945 inversecopies1 = {}
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
946 inversecopies2 = {}
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
947 for dst, src in copies1.items():
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
948 inversecopies1.setdefault(src, []).append(dst)
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
949 for dst, src in copies2.items():
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
950 inversecopies2.setdefault(src, []).append(dst)
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
951
44196
6ca9f45b32b0 copies: make mergecopies() distinguish between copies on each side
Martin von Zweigbergk <martinvonz@google.com>
parents: 44164
diff changeset
952 copy1 = {}
6ca9f45b32b0 copies: make mergecopies() distinguish between copies on each side
Martin von Zweigbergk <martinvonz@google.com>
parents: 44164
diff changeset
953 copy2 = {}
42222
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
954 diverge = {}
44196
6ca9f45b32b0 copies: make mergecopies() distinguish between copies on each side
Martin von Zweigbergk <martinvonz@google.com>
parents: 44164
diff changeset
955 renamedelete1 = {}
6ca9f45b32b0 copies: make mergecopies() distinguish between copies on each side
Martin von Zweigbergk <martinvonz@google.com>
parents: 44164
diff changeset
956 renamedelete2 = {}
42222
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
957 allsources = set(inversecopies1) | set(inversecopies2)
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
958 for src in allsources:
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
959 dsts1 = inversecopies1.get(src)
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
960 dsts2 = inversecopies2.get(src)
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
961 if dsts1 and dsts2:
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
962 # copied/renamed on both sides
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
963 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
964 # renamed on both sides
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
965 dsts1 = set(dsts1)
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
966 dsts2 = set(dsts2)
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
967 # 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
968 # 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
969 # 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
970 # and 'd' and deletes 'a'.
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
971 if dsts1 & dsts2:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
972 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
973 copy1[dst] = src
6ca9f45b32b0 copies: make mergecopies() distinguish between copies on each side
Martin von Zweigbergk <martinvonz@google.com>
parents: 44164
diff changeset
974 copy2[dst] = src
42222
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
975 else:
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
976 diverge[src] = sorted(dsts1 | dsts2)
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
977 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
978 # copied on both sides
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
979 dsts1 = set(dsts1)
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
980 dsts2 = set(dsts2)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
981 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
982 copy1[dst] = src
6ca9f45b32b0 copies: make mergecopies() distinguish between copies on each side
Martin von Zweigbergk <martinvonz@google.com>
parents: 44164
diff changeset
983 copy2[dst] = src
42222
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
984 # 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
985 # on the other side
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
986 elif dsts1:
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
987 # copied/renamed only on side 1
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
988 _checksinglesidecopies(
44196
6ca9f45b32b0 copies: make mergecopies() distinguish between copies on each side
Martin von Zweigbergk <martinvonz@google.com>
parents: 44164
diff changeset
989 src, dsts1, m1, m2, mb, c2, base, copy1, renamedelete1
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
990 )
42222
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
991 elif dsts2:
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
992 # copied/renamed only on side 2
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
993 _checksinglesidecopies(
44196
6ca9f45b32b0 copies: make mergecopies() distinguish between copies on each side
Martin von Zweigbergk <martinvonz@google.com>
parents: 44164
diff changeset
994 src, dsts2, m2, m1, mb, c1, base, copy2, renamedelete2
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
995 )
42222
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
996
26659
df66736a128e copies: group bothnew with other sets
Matt Mackall <mpm@selenic.com>
parents: 26658
diff changeset
997 # 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
998 cache = []
2f357d053df2 copies: make calculating lazy for dir move detection's "addedfiles"
Kyle Lippincott <spectral@google.com>
parents: 46057
diff changeset
999
2f357d053df2 copies: make calculating lazy for dir move detection's "addedfiles"
Kyle Lippincott <spectral@google.com>
parents: 46057
diff changeset
1000 def _get_addedfiles(idx):
2f357d053df2 copies: make calculating lazy for dir move detection's "addedfiles"
Kyle Lippincott <spectral@google.com>
parents: 46057
diff changeset
1001 if not cache:
2f357d053df2 copies: make calculating lazy for dir move detection's "addedfiles"
Kyle Lippincott <spectral@google.com>
parents: 46057
diff changeset
1002 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
1003 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
1004 u1 = sorted(addedinm1 - addedinm2)
2f357d053df2 copies: make calculating lazy for dir move detection's "addedfiles"
Kyle Lippincott <spectral@google.com>
parents: 46057
diff changeset
1005 u2 = sorted(addedinm2 - addedinm1)
2f357d053df2 copies: make calculating lazy for dir move detection's "addedfiles"
Kyle Lippincott <spectral@google.com>
parents: 46057
diff changeset
1006 cache.extend((u1, u2))
2f357d053df2 copies: make calculating lazy for dir move detection's "addedfiles"
Kyle Lippincott <spectral@google.com>
parents: 46057
diff changeset
1007 return cache[idx]
42223
d69bc8ffbe6f copies: inline _computenonoverlap() in mergecopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42222
diff changeset
1008
46109
2f357d053df2 copies: make calculating lazy for dir move detection's "addedfiles"
Kyle Lippincott <spectral@google.com>
parents: 46057
diff changeset
1009 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
1010 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
1011 if repo.ui.debugflag:
2f357d053df2 copies: make calculating lazy for dir move detection's "addedfiles"
Kyle Lippincott <spectral@google.com>
parents: 46057
diff changeset
1012 u1 = u1fn()
2f357d053df2 copies: make calculating lazy for dir move detection's "addedfiles"
Kyle Lippincott <spectral@google.com>
parents: 46057
diff changeset
1013 u2 = u2fn()
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
1014
46109
2f357d053df2 copies: make calculating lazy for dir move detection's "addedfiles"
Kyle Lippincott <spectral@google.com>
parents: 46057
diff changeset
1015 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
1016 if u1:
2f357d053df2 copies: make calculating lazy for dir move detection's "addedfiles"
Kyle Lippincott <spectral@google.com>
parents: 46057
diff changeset
1017 repo.ui.debug(
2f357d053df2 copies: make calculating lazy for dir move detection's "addedfiles"
Kyle Lippincott <spectral@google.com>
parents: 46057
diff changeset
1018 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
1019 )
2f357d053df2 copies: make calculating lazy for dir move detection's "addedfiles"
Kyle Lippincott <spectral@google.com>
parents: 46057
diff changeset
1020 if u2:
2f357d053df2 copies: make calculating lazy for dir move detection's "addedfiles"
Kyle Lippincott <spectral@google.com>
parents: 46057
diff changeset
1021 repo.ui.debug(
2f357d053df2 copies: make calculating lazy for dir move detection's "addedfiles"
Kyle Lippincott <spectral@google.com>
parents: 46057
diff changeset
1022 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
1023 )
2f357d053df2 copies: make calculating lazy for dir move detection's "addedfiles"
Kyle Lippincott <spectral@google.com>
parents: 46057
diff changeset
1024
44163
782e0d9c3b74 copies: avoid calculating debug-only stuff without --debug
Martin von Zweigbergk <martinvonz@google.com>
parents: 44162
diff changeset
1025 renamedeleteset = set()
782e0d9c3b74 copies: avoid calculating debug-only stuff without --debug
Martin von Zweigbergk <martinvonz@google.com>
parents: 44162
diff changeset
1026 divergeset = set()
782e0d9c3b74 copies: avoid calculating debug-only stuff without --debug
Martin von Zweigbergk <martinvonz@google.com>
parents: 44162
diff changeset
1027 for dsts in diverge.values():
782e0d9c3b74 copies: avoid calculating debug-only stuff without --debug
Martin von Zweigbergk <martinvonz@google.com>
parents: 44162
diff changeset
1028 divergeset.update(dsts)
44196
6ca9f45b32b0 copies: make mergecopies() distinguish between copies on each side
Martin von Zweigbergk <martinvonz@google.com>
parents: 44164
diff changeset
1029 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
1030 renamedeleteset.update(dsts)
6ca9f45b32b0 copies: make mergecopies() distinguish between copies on each side
Martin von Zweigbergk <martinvonz@google.com>
parents: 44164
diff changeset
1031 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
1032 renamedeleteset.update(dsts)
782e0d9c3b74 copies: avoid calculating debug-only stuff without --debug
Martin von Zweigbergk <martinvonz@google.com>
parents: 44162
diff changeset
1033
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
1034 repo.ui.debug(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
1035 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
1036 b"% = renamed and deleted):\n"
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
1037 )
44197
17e12938f8e7 copies: print debug information about copies per side/branch
Martin von Zweigbergk <martinvonz@google.com>
parents: 44196
diff changeset
1038 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
1039 if not copies:
17e12938f8e7 copies: print debug information about copies per side/branch
Martin von Zweigbergk <martinvonz@google.com>
parents: 44196
diff changeset
1040 continue
17e12938f8e7 copies: print debug information about copies per side/branch
Martin von Zweigbergk <martinvonz@google.com>
parents: 44196
diff changeset
1041 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
1042 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
1043 note = b""
17e12938f8e7 copies: print debug information about copies per side/branch
Martin von Zweigbergk <martinvonz@google.com>
parents: 44196
diff changeset
1044 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
1045 note += b"*"
17e12938f8e7 copies: print debug information about copies per side/branch
Martin von Zweigbergk <martinvonz@google.com>
parents: 44196
diff changeset
1046 if f in divergeset:
17e12938f8e7 copies: print debug information about copies per side/branch
Martin von Zweigbergk <martinvonz@google.com>
parents: 44196
diff changeset
1047 note += b"!"
17e12938f8e7 copies: print debug information about copies per side/branch
Martin von Zweigbergk <martinvonz@google.com>
parents: 44196
diff changeset
1048 if f in renamedeleteset:
17e12938f8e7 copies: print debug information about copies per side/branch
Martin von Zweigbergk <martinvonz@google.com>
parents: 44196
diff changeset
1049 note += b"%"
17e12938f8e7 copies: print debug information about copies per side/branch
Martin von Zweigbergk <martinvonz@google.com>
parents: 44196
diff changeset
1050 repo.ui.debug(
17e12938f8e7 copies: print debug information about copies per side/branch
Martin von Zweigbergk <martinvonz@google.com>
parents: 44196
diff changeset
1051 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
1052 )
44163
782e0d9c3b74 copies: avoid calculating debug-only stuff without --debug
Martin von Zweigbergk <martinvonz@google.com>
parents: 44162
diff changeset
1053 del renamedeleteset
782e0d9c3b74 copies: avoid calculating debug-only stuff without --debug
Martin von Zweigbergk <martinvonz@google.com>
parents: 44162
diff changeset
1054 del divergeset
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
1055
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
1056 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
1057
46109
2f357d053df2 copies: make calculating lazy for dir move detection's "addedfiles"
Kyle Lippincott <spectral@google.com>
parents: 46057
diff changeset
1058 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
1059 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
1060
44200
fa9ad1da2e77 merge: start using the per-side copy dicts
Martin von Zweigbergk <martinvonz@google.com>
parents: 44199
diff changeset
1061 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
1062 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
1063
44200
fa9ad1da2e77 merge: start using the per-side copy dicts
Martin von Zweigbergk <martinvonz@google.com>
parents: 44199
diff changeset
1064 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
1065
45192589555c copies: extract function for finding directory renames
Martin von Zweigbergk <martinvonz@google.com>
parents: 44163
diff changeset
1066
46109
2f357d053df2 copies: make calculating lazy for dir move detection's "addedfiles"
Kyle Lippincott <spectral@google.com>
parents: 46057
diff changeset
1067 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
1068 """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
1069
6ca9f45b32b0 copies: make mergecopies() distinguish between copies on each side
Martin von Zweigbergk <martinvonz@google.com>
parents: 44164
diff changeset
1070 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
1071 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
1072 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
1073 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
1074 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
1075 ctx)
44196
6ca9f45b32b0 copies: make mergecopies() distinguish between copies on each side
Martin von Zweigbergk <martinvonz@google.com>
parents: 44164
diff changeset
1076 """
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
1077 # 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
1078 invalid = set()
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
1079 dirmove = {}
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
1080
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
1081 # 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
1082 # 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
1083 for dst, src in pycompat.iteritems(fullcopy):
25282
0f28815ef066 copies: switch to using pathutil.dirname
Durham Goode <durham@fb.com>
parents: 24782
diff changeset
1084 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
1085 if dsrc in invalid:
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
1086 # already seen to be uninteresting
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
1087 continue
46011
b9588ff9b66a copies: avoid materializing a full directory map during copy tracing
Kyle Lippincott <spectral@google.com>
parents: 45986
diff changeset
1088 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
1089 # 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
1090 invalid.add(dsrc)
eebd591803ab copies: correctly skip directories that have already been considered
Kyle Lippincott <spectral@google.com>
parents: 38670
diff changeset
1091 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
1092 # 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
1093 invalid.add(dsrc)
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
1094 else:
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
1095 # looks good so far
39263
eebd591803ab copies: correctly skip directories that have already been considered
Kyle Lippincott <spectral@google.com>
parents: 38670
diff changeset
1096 dirmove[dsrc] = ddst
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
1097
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
1098 for i in invalid:
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
1099 if i in dirmove:
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
1100 del dirmove[i]
46011
b9588ff9b66a copies: avoid materializing a full directory map during copy tracing
Kyle Lippincott <spectral@google.com>
parents: 45986
diff changeset
1101 del invalid
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
1102
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
1103 if not dirmove:
44164
45192589555c copies: extract function for finding directory renames
Martin von Zweigbergk <martinvonz@google.com>
parents: 44163
diff changeset
1104 return {}, {}
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
1105
43106
d783f945a701 py3: finish porting iteritems() to pycompat and remove source transformer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43077
diff changeset
1106 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
1107
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
1108 for d in dirmove:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
1109 repo.ui.debug(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
1110 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
1111 )
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
1112
46634
ad30b29bc23d copies: choose target directory based on longest match
Martin von Zweigbergk <martinvonz@google.com>
parents: 46588
diff changeset
1113 # Sort the directories in reverse order, so we find children first
ad30b29bc23d copies: choose target directory based on longest match
Martin von Zweigbergk <martinvonz@google.com>
parents: 46588
diff changeset
1114 # For example, if dir1/ was renamed to dir2/, and dir1/subdir1/
ad30b29bc23d copies: choose target directory based on longest match
Martin von Zweigbergk <martinvonz@google.com>
parents: 46588
diff changeset
1115 # was renamed to dir2/subdir2/, we want to move dir1/subdir1/file
ad30b29bc23d copies: choose target directory based on longest match
Martin von Zweigbergk <martinvonz@google.com>
parents: 46588
diff changeset
1116 # to dir2/subdir2/file (not dir2/subdir1/file)
ad30b29bc23d copies: choose target directory based on longest match
Martin von Zweigbergk <martinvonz@google.com>
parents: 46588
diff changeset
1117 dirmove_children_first = sorted(dirmove, reverse=True)
ad30b29bc23d copies: choose target directory based on longest match
Martin von Zweigbergk <martinvonz@google.com>
parents: 46588
diff changeset
1118
30183
0106f93ca1d5 checkcopies: move 'movewithdir' initialisation right before its usage
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30138
diff changeset
1119 movewithdir = {}
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
1120 # 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
1121 for f in addedfilesfn():
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
1122 if f not in fullcopy:
46634
ad30b29bc23d copies: choose target directory based on longest match
Martin von Zweigbergk <martinvonz@google.com>
parents: 46588
diff changeset
1123 for d in dirmove_children_first:
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
1124 if f.startswith(d):
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
1125 # 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
1126 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
1127 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
1128 movewithdir[f] = df
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
1129 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
1130 b" pending file src: '%s' -> dst: '%s'\n"
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
1131 % (f, df)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
1132 )
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
1133 break
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
1134
44164
45192589555c copies: extract function for finding directory renames
Martin von Zweigbergk <martinvonz@google.com>
parents: 44163
diff changeset
1135 return dirmove, movewithdir
19178
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
1136
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
1137
34179
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
1138 def _heuristicscopytracing(repo, c1, c2, base):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45892
diff changeset
1139 """Fast copytracing using filename heuristics
34179
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
1140
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
1141 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
1142
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
1143 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
1144 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
1145 (same filenames but different directory names)
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
1146
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
1147 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
1148 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
1149
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
1150 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
1151
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
1152 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
1153
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
1154 [experimental]
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
1155 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
1156
f05a6e015ecc copies: add a config to limit the number of candidates to check in heuristics
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34787
diff changeset
1157 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
1158 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
1159 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
1160 `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
1161 """
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
1162
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
1163 if c1.rev() is None:
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
1164 c1 = c1.p1()
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
1165 if c2.rev() is None:
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
1166 c2 = c2.p1()
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
1167
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
1168 changedfiles = set()
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
1169 m1 = c1.manifest()
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
1170 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
1171 # 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
1172 repo.ui.debug(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
1173 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
1174 b"an ancestor of c2\n"
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
1175 )
34179
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
1176 return _fullcopytracing(repo, c1, c2, base)
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
1177
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
1178 ctx = c2
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
1179 while ctx != base:
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
1180 if len(ctx.parents()) == 2:
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
1181 # 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
1182 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
1183 return _fullcopytracing(repo, c1, c2, base)
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
1184 changedfiles.update(ctx.files())
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
1185 ctx = ctx.p1()
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
1186
44200
fa9ad1da2e77 merge: start using the per-side copy dicts
Martin von Zweigbergk <martinvonz@google.com>
parents: 44199
diff changeset
1187 copies2 = {}
34179
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
1188 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
1189 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
1190 if src in m1:
44200
fa9ad1da2e77 merge: start using the per-side copy dicts
Martin von Zweigbergk <martinvonz@google.com>
parents: 44199
diff changeset
1191 copies2[dst] = src
34179
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
1192
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
1193 # 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
1194 # 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
1195 # 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
1196 # 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
1197 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
1198 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
1199
44200
fa9ad1da2e77 merge: start using the per-side copy dicts
Martin von Zweigbergk <martinvonz@google.com>
parents: 44199
diff changeset
1200 copies1 = {}
34179
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
1201 if missingfiles:
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
1202 basenametofilename = collections.defaultdict(list)
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
1203 dirnametofilename = collections.defaultdict(list)
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
1204
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
1205 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
1206 basename = os.path.basename(f)
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
1207 dirname = os.path.dirname(f)
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
1208 basenametofilename[basename].append(f)
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
1209 dirnametofilename[dirname].append(f)
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
1210
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
1211 for f in missingfiles:
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
1212 basename = os.path.basename(f)
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
1213 dirname = os.path.dirname(f)
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
1214 samebasename = basenametofilename[basename]
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
1215 samedirname = dirnametofilename[dirname]
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
1216 movecandidates = samebasename + samedirname
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
1217 # 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
1218 # c2.filectx(f) won't fail
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
1219 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
1220 # 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
1221 # 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
1222 maxcandidates = repo.ui.configint(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
1223 b'experimental', b'copytrace.movecandidateslimit'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
1224 )
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
1225
f05a6e015ecc copies: add a config to limit the number of candidates to check in heuristics
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34787
diff changeset
1226 if len(movecandidates) > maxcandidates:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
1227 repo.ui.status(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
1228 _(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
1229 b"skipping copytracing for '%s', more "
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
1230 b"candidates than the limit: %d\n"
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
1231 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
1232 % (f, len(movecandidates))
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
1233 )
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
1234 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
1235
34179
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
1236 for candidate in movecandidates:
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
1237 f1 = c1.filectx(candidate)
37392
a4f02a17420d copies: clean up _related logic
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 36346
diff changeset
1238 if _related(f1, f2):
34179
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
1239 # 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
1240 # 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
1241 # of upstream copytracing
44200
fa9ad1da2e77 merge: start using the per-side copy dicts
Martin von Zweigbergk <martinvonz@google.com>
parents: 44199
diff changeset
1242 copies1[candidate] = f
34179
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
1243
44200
fa9ad1da2e77 merge: start using the per-side copy dicts
Martin von Zweigbergk <martinvonz@google.com>
parents: 44199
diff changeset
1244 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
1245
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
1246
37392
a4f02a17420d copies: clean up _related logic
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 36346
diff changeset
1247 def _related(f1, f2):
30138
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
1248 """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
1249
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
1250 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
1251 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
1252 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
1253 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
1254 """
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
1255
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
1256 if f1 == f2:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
1257 return True # a match
30138
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
1258
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
1259 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
1260 try:
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
1261 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
1262
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
1263 if f1r is None:
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
1264 f1 = next(g1)
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
1265 if f2r is None:
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
1266 f2 = next(g2)
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
1267
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
1268 while True:
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
1269 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
1270 if f1r > f2r:
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
1271 f1 = next(g1)
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
1272 elif f2r > f1r:
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
1273 f2 = next(g2)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
1274 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
1275 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
1276 except StopIteration:
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
1277 return False
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
1278
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
1279
44092
833210fbd900 graftcopies: remove `skip` and `repo` arguments
Martin von Zweigbergk <martinvonz@google.com>
parents: 44091
diff changeset
1280 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
1281 """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
1282
06e7e7652ac0 graftcopies: document why the function is useful at all
Martin von Zweigbergk <martinvonz@google.com>
parents: 44092
diff changeset
1283 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
1284 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
1285 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
1286 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
1287 (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
1288 experimental.copytrace=off.
06e7e7652ac0 graftcopies: document why the function is useful at all
Martin von Zweigbergk <martinvonz@google.com>
parents: 44092
diff changeset
1289
06e7e7652ac0 graftcopies: document why the function is useful at all
Martin von Zweigbergk <martinvonz@google.com>
parents: 44092
diff changeset
1290 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
1291 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
1292 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
1293 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
1294 by merge.update().
06e7e7652ac0 graftcopies: document why the function is useful at all
Martin von Zweigbergk <martinvonz@google.com>
parents: 44092
diff changeset
1295 """
44091
3df0bd706c40 graftcopies: use _filter() for filtering out invalid copies
Martin von Zweigbergk <martinvonz@google.com>
parents: 44090
diff changeset
1296 new_copies = pathcopies(base, ctx)
46397
f213b250fed0 copies: explicitly filter out existing file in graftcopies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46302
diff changeset
1297 parent = wctx.p1()
f213b250fed0 copies: explicitly filter out existing file in graftcopies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46302
diff changeset
1298 _filter(parent, wctx, new_copies)
46410
892eb7c5edaa copies: fix an incorrect comment in graftcopies() from recent D9802
Martin von Zweigbergk <martinvonz@google.com>
parents: 46408
diff changeset
1299 # Extra filtering to drop copy information for files that existed before
892eb7c5edaa copies: fix an incorrect comment in graftcopies() from recent D9802
Martin von Zweigbergk <martinvonz@google.com>
parents: 46408
diff changeset
1300 # the graft. This is to handle the case of grafting a rename onto a commit
892eb7c5edaa copies: fix an incorrect comment in graftcopies() from recent D9802
Martin von Zweigbergk <martinvonz@google.com>
parents: 46408
diff changeset
1301 # that already has the rename. Otherwise the presence of copy information
892eb7c5edaa copies: fix an incorrect comment in graftcopies() from recent D9802
Martin von Zweigbergk <martinvonz@google.com>
parents: 46408
diff changeset
1302 # would result in the creation of an empty commit where we would prefer to
892eb7c5edaa copies: fix an incorrect comment in graftcopies() from recent D9802
Martin von Zweigbergk <martinvonz@google.com>
parents: 46408
diff changeset
1303 # not create one.
46397
f213b250fed0 copies: explicitly filter out existing file in graftcopies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46302
diff changeset
1304 for dest, __ in list(new_copies.items()):
f213b250fed0 copies: explicitly filter out existing file in graftcopies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46302
diff changeset
1305 if dest in parent:
f213b250fed0 copies: explicitly filter out existing file in graftcopies
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46302
diff changeset
1306 del new_copies[dest]
44091
3df0bd706c40 graftcopies: use _filter() for filtering out invalid copies
Martin von Zweigbergk <martinvonz@google.com>
parents: 44090
diff changeset
1307 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
1308 wctx[dst].markcopied(src)