annotate mercurial/copies.py @ 43117:8ff1ecfadcd1

cleanup: join string literals that are already on one line Thanks to Kyle for noticing this and for providing the regular expression to run on the codebase. This patch has been reviewed by the test suite and they approved of it. # skip-blame: fallout from mass reformatting Differential Revision: https://phab.mercurial-scm.org/D7028
author Martin von Zweigbergk <martinvonz@google.com>
date Tue, 08 Oct 2019 15:06:18 -0700
parents d783f945a701
children 0171483b082f
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
1 # copies.py - copy detection for Mercurial
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
2 #
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
3 # Copyright 2008 Matt Mackall <mpm@selenic.com>
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
4 #
8225
46293a0c7e9f updated license to be explicit about GPL version 2
Martin Geisler <mg@lazybytes.net>
parents: 8209
diff changeset
5 # 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
6 # 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
7
25924
cfc24c22454e copies: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25289
diff changeset
8 from __future__ import absolute_import
cfc24c22454e copies: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25289
diff changeset
9
34179
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
10 import collections
8312
b87a50b7125c separate import lines from mercurial and general python modules
Simon Heimberg <simohe@besonet.ch>
parents: 8225
diff changeset
11 import heapq
34179
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 _
f05a6e015ecc copies: add a config to limit the number of candidates to check in heuristics
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34787
diff changeset
15
25924
cfc24c22454e copies: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25289
diff changeset
16 from . import (
33867
252fb66ee5bb copies: use intersectmatchers() in non-merge p1 optimization
Yuya Nishihara <yuya@tcha.org>
parents: 33822
diff changeset
17 match as matchmod,
28000
d4247c306d82 copies: optimize forward copy detection logic for rebases
Durham Goode <durham@fb.com>
parents: 27876
diff changeset
18 node,
25924
cfc24c22454e copies: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25289
diff changeset
19 pathutil,
43106
d783f945a701 py3: finish porting iteritems() to pycompat and remove source transformer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43077
diff changeset
20 pycompat,
25924
cfc24c22454e copies: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25289
diff changeset
21 util,
cfc24c22454e copies: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25289
diff changeset
22 )
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
23 from .utils import stringutil
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
24
25924
cfc24c22454e copies: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25289
diff changeset
25
41393
dc50121126ae copies: pass contexts into _findlimit()
Martin von Zweigbergk <martinvonz@google.com>
parents: 41392
diff changeset
26 def _findlimit(repo, ctxa, ctxb):
23071
652ab726ba93 amend: fix amending rename commit with diverged topologies (issue4405)
Ryan McElroy <rmcelroy@fb.com>
parents: 22901
diff changeset
27 """
652ab726ba93 amend: fix amending rename commit with diverged topologies (issue4405)
Ryan McElroy <rmcelroy@fb.com>
parents: 22901
diff changeset
28 Find the last revision that needs to be checked to ensure that a full
652ab726ba93 amend: fix amending rename commit with diverged topologies (issue4405)
Ryan McElroy <rmcelroy@fb.com>
parents: 22901
diff changeset
29 transitive closure for file copies can be properly calculated.
652ab726ba93 amend: fix amending rename commit with diverged topologies (issue4405)
Ryan McElroy <rmcelroy@fb.com>
parents: 22901
diff changeset
30 Generally, this means finding the earliest revision number that's an
652ab726ba93 amend: fix amending rename commit with diverged topologies (issue4405)
Ryan McElroy <rmcelroy@fb.com>
parents: 22901
diff changeset
31 ancestor of a or b but not both, except when a or b is a direct descendent
652ab726ba93 amend: fix amending rename commit with diverged topologies (issue4405)
Ryan McElroy <rmcelroy@fb.com>
parents: 22901
diff changeset
32 of the other, in which case we can return the minimum revnum of a and b.
10179
83cfa1baf8ad copies: don't report copies with unrelated branch
Patrick Mezard <pmezard@gmail.com>
parents: 9467
diff changeset
33 """
23071
652ab726ba93 amend: fix amending rename commit with diverged topologies (issue4405)
Ryan McElroy <rmcelroy@fb.com>
parents: 22901
diff changeset
34
6429
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
35 # basic idea:
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
36 # - mark a and b with different sides
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
37 # - if a parent's children are all on the same side, the parent is
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
38 # on that side, otherwise it is on no side
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
39 # - walk the graph in topological order with the help of a heap;
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
40 # - add unseen parents to side map
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
41 # - clear side of any parent that has children on different sides
6431
a42d8d3e6ea9 copies: refactor symmetricdifference as _findlimit
Matt Mackall <mpm@selenic.com>
parents: 6430
diff changeset
42 # - track number of interesting revs that might still be on a side
a42d8d3e6ea9 copies: refactor symmetricdifference as _findlimit
Matt Mackall <mpm@selenic.com>
parents: 6430
diff changeset
43 # - track the lowest interesting rev seen
a42d8d3e6ea9 copies: refactor symmetricdifference as _findlimit
Matt Mackall <mpm@selenic.com>
parents: 6430
diff changeset
44 # - quit when interesting revs is zero
6430
a6a66e812c34 copies: teach symmetric difference about working revisions
Matt Mackall <mpm@selenic.com>
parents: 6429
diff changeset
45
a6a66e812c34 copies: teach symmetric difference about working revisions
Matt Mackall <mpm@selenic.com>
parents: 6429
diff changeset
46 cl = repo.changelog
41394
75e753a26806 copies: get working copy parents from wctx, not dirstate, to make in-mem work
Martin von Zweigbergk <martinvonz@google.com>
parents: 41393
diff changeset
47 wdirparents = None
41393
dc50121126ae copies: pass contexts into _findlimit()
Martin von Zweigbergk <martinvonz@google.com>
parents: 41392
diff changeset
48 a = ctxa.rev()
dc50121126ae copies: pass contexts into _findlimit()
Martin von Zweigbergk <martinvonz@google.com>
parents: 41392
diff changeset
49 b = ctxb.rev()
6430
a6a66e812c34 copies: teach symmetric difference about working revisions
Matt Mackall <mpm@selenic.com>
parents: 6429
diff changeset
50 if a is None:
41394
75e753a26806 copies: get working copy parents from wctx, not dirstate, to make in-mem work
Martin von Zweigbergk <martinvonz@google.com>
parents: 41393
diff changeset
51 wdirparents = (ctxa.p1(), ctxa.p2())
41231
e3e1b0639375 copies: use node.wdirrev instead of inventing another constant for it
Martin von Zweigbergk <martinvonz@google.com>
parents: 40694
diff changeset
52 a = node.wdirrev
6430
a6a66e812c34 copies: teach symmetric difference about working revisions
Matt Mackall <mpm@selenic.com>
parents: 6429
diff changeset
53 if b is None:
41394
75e753a26806 copies: get working copy parents from wctx, not dirstate, to make in-mem work
Martin von Zweigbergk <martinvonz@google.com>
parents: 41393
diff changeset
54 assert not wdirparents
75e753a26806 copies: get working copy parents from wctx, not dirstate, to make in-mem work
Martin von Zweigbergk <martinvonz@google.com>
parents: 41393
diff changeset
55 wdirparents = (ctxb.p1(), ctxb.p2())
41231
e3e1b0639375 copies: use node.wdirrev instead of inventing another constant for it
Martin von Zweigbergk <martinvonz@google.com>
parents: 40694
diff changeset
56 b = node.wdirrev
6429
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
57
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
58 side = {a: -1, b: 1}
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
59 visit = [-a, -b]
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
60 heapq.heapify(visit)
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
61 interesting = len(visit)
41231
e3e1b0639375 copies: use node.wdirrev instead of inventing another constant for it
Martin von Zweigbergk <martinvonz@google.com>
parents: 40694
diff changeset
62 limit = node.wdirrev
6429
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
63
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
64 while interesting:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
65 r = -(heapq.heappop(visit))
41231
e3e1b0639375 copies: use node.wdirrev instead of inventing another constant for it
Martin von Zweigbergk <martinvonz@google.com>
parents: 40694
diff changeset
66 if r == node.wdirrev:
41394
75e753a26806 copies: get working copy parents from wctx, not dirstate, to make in-mem work
Martin von Zweigbergk <martinvonz@google.com>
parents: 41393
diff changeset
67 parents = [pctx.rev() for pctx in wdirparents]
6430
a6a66e812c34 copies: teach symmetric difference about working revisions
Matt Mackall <mpm@selenic.com>
parents: 6429
diff changeset
68 else:
a6a66e812c34 copies: teach symmetric difference about working revisions
Matt Mackall <mpm@selenic.com>
parents: 6429
diff changeset
69 parents = cl.parentrevs(r)
41392
b80af0707066 copies: consider nullrev a common ancestor
Martin von Zweigbergk <martinvonz@google.com>
parents: 41232
diff changeset
70 if parents[1] == node.nullrev:
b80af0707066 copies: consider nullrev a common ancestor
Martin von Zweigbergk <martinvonz@google.com>
parents: 41232
diff changeset
71 parents = parents[:1]
6430
a6a66e812c34 copies: teach symmetric difference about working revisions
Matt Mackall <mpm@selenic.com>
parents: 6429
diff changeset
72 for p in parents:
6429
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
73 if p not in side:
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
74 # first time we see p; add it to visit
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
75 side[p] = side[r]
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
76 if side[p]:
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
77 interesting += 1
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
78 heapq.heappush(visit, -p)
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
79 elif side[p] and side[p] != side[r]:
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
80 # p was interesting but now we know better
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
81 side[p] = 0
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
82 interesting -= 1
6430
a6a66e812c34 copies: teach symmetric difference about working revisions
Matt Mackall <mpm@selenic.com>
parents: 6429
diff changeset
83 if side[r]:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
84 limit = r # lowest rev visited
6430
a6a66e812c34 copies: teach symmetric difference about working revisions
Matt Mackall <mpm@selenic.com>
parents: 6429
diff changeset
85 interesting -= 1
10179
83cfa1baf8ad copies: don't report copies with unrelated branch
Patrick Mezard <pmezard@gmail.com>
parents: 9467
diff changeset
86
23071
652ab726ba93 amend: fix amending rename commit with diverged topologies (issue4405)
Ryan McElroy <rmcelroy@fb.com>
parents: 22901
diff changeset
87 # Consider the following flow (see test-commit-amend.t under issue4405):
652ab726ba93 amend: fix amending rename commit with diverged topologies (issue4405)
Ryan McElroy <rmcelroy@fb.com>
parents: 22901
diff changeset
88 # 1/ File 'a0' committed
652ab726ba93 amend: fix amending rename commit with diverged topologies (issue4405)
Ryan McElroy <rmcelroy@fb.com>
parents: 22901
diff changeset
89 # 2/ File renamed from 'a0' to 'a1' in a new commit (call it 'a1')
652ab726ba93 amend: fix amending rename commit with diverged topologies (issue4405)
Ryan McElroy <rmcelroy@fb.com>
parents: 22901
diff changeset
90 # 3/ Move back to first commit
652ab726ba93 amend: fix amending rename commit with diverged topologies (issue4405)
Ryan McElroy <rmcelroy@fb.com>
parents: 22901
diff changeset
91 # 4/ Create a new commit via revert to contents of 'a1' (call it 'a1-amend')
652ab726ba93 amend: fix amending rename commit with diverged topologies (issue4405)
Ryan McElroy <rmcelroy@fb.com>
parents: 22901
diff changeset
92 # 5/ Rename file from 'a1' to 'a2' and commit --amend 'a1-msg'
652ab726ba93 amend: fix amending rename commit with diverged topologies (issue4405)
Ryan McElroy <rmcelroy@fb.com>
parents: 22901
diff changeset
93 #
652ab726ba93 amend: fix amending rename commit with diverged topologies (issue4405)
Ryan McElroy <rmcelroy@fb.com>
parents: 22901
diff changeset
94 # During the amend in step five, we will be in this state:
652ab726ba93 amend: fix amending rename commit with diverged topologies (issue4405)
Ryan McElroy <rmcelroy@fb.com>
parents: 22901
diff changeset
95 #
652ab726ba93 amend: fix amending rename commit with diverged topologies (issue4405)
Ryan McElroy <rmcelroy@fb.com>
parents: 22901
diff changeset
96 # @ 3 temporary amend commit for a1-amend
652ab726ba93 amend: fix amending rename commit with diverged topologies (issue4405)
Ryan McElroy <rmcelroy@fb.com>
parents: 22901
diff changeset
97 # |
652ab726ba93 amend: fix amending rename commit with diverged topologies (issue4405)
Ryan McElroy <rmcelroy@fb.com>
parents: 22901
diff changeset
98 # o 2 a1-amend
652ab726ba93 amend: fix amending rename commit with diverged topologies (issue4405)
Ryan McElroy <rmcelroy@fb.com>
parents: 22901
diff changeset
99 # |
652ab726ba93 amend: fix amending rename commit with diverged topologies (issue4405)
Ryan McElroy <rmcelroy@fb.com>
parents: 22901
diff changeset
100 # | o 1 a1
652ab726ba93 amend: fix amending rename commit with diverged topologies (issue4405)
Ryan McElroy <rmcelroy@fb.com>
parents: 22901
diff changeset
101 # |/
652ab726ba93 amend: fix amending rename commit with diverged topologies (issue4405)
Ryan McElroy <rmcelroy@fb.com>
parents: 22901
diff changeset
102 # o 0 a0
652ab726ba93 amend: fix amending rename commit with diverged topologies (issue4405)
Ryan McElroy <rmcelroy@fb.com>
parents: 22901
diff changeset
103 #
23139
e53f6b72a0e4 spelling: fixes from proofreading of spell checker issues
Mads Kiilerich <madski@unity3d.com>
parents: 23071
diff changeset
104 # When _findlimit is called, a and b are revs 3 and 0, so limit will be 2,
23071
652ab726ba93 amend: fix amending rename commit with diverged topologies (issue4405)
Ryan McElroy <rmcelroy@fb.com>
parents: 22901
diff changeset
105 # yet the filelog has the copy information in rev 1 and we will not look
652ab726ba93 amend: fix amending rename commit with diverged topologies (issue4405)
Ryan McElroy <rmcelroy@fb.com>
parents: 22901
diff changeset
106 # back far enough unless we also look at the a and b as candidates.
652ab726ba93 amend: fix amending rename commit with diverged topologies (issue4405)
Ryan McElroy <rmcelroy@fb.com>
parents: 22901
diff changeset
107 # This only occurs when a is a descendent of b or visa-versa.
652ab726ba93 amend: fix amending rename commit with diverged topologies (issue4405)
Ryan McElroy <rmcelroy@fb.com>
parents: 22901
diff changeset
108 return min(limit, a, b)
6429
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
109
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
110
42593
11ceb1b8fd74 copies: inline _chainandfilter() to prepare for next patch
Martin von Zweigbergk <martinvonz@google.com>
parents: 42592
diff changeset
111 def _filter(src, dst, t):
11ceb1b8fd74 copies: inline _chainandfilter() to prepare for next patch
Martin von Zweigbergk <martinvonz@google.com>
parents: 42592
diff changeset
112 """filters out invalid copies after chaining"""
42227
d1c2688eda80 copies: document cases in _chain()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42226
diff changeset
113
42593
11ceb1b8fd74 copies: inline _chainandfilter() to prepare for next patch
Martin von Zweigbergk <martinvonz@google.com>
parents: 42592
diff changeset
114 # 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
115 # with copies in 'b' (from 'mid' to 'dst'), we can get the different cases
11ceb1b8fd74 copies: inline _chainandfilter() to prepare for next patch
Martin von Zweigbergk <martinvonz@google.com>
parents: 42592
diff changeset
116 # in the following table (not including trivial cases). For example, case 2
11ceb1b8fd74 copies: inline _chainandfilter() to prepare for next patch
Martin von Zweigbergk <martinvonz@google.com>
parents: 42592
diff changeset
117 # 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
118 # then was renamed between 'mid' and 'dst'.
d1c2688eda80 copies: document cases in _chain()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42226
diff changeset
119 #
d1c2688eda80 copies: document cases in _chain()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42226
diff changeset
120 # case src mid dst result
d1c2688eda80 copies: document cases in _chain()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42226
diff changeset
121 # 1 x y - -
d1c2688eda80 copies: document cases in _chain()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42226
diff changeset
122 # 2 x y y x->y
d1c2688eda80 copies: document cases in _chain()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42226
diff changeset
123 # 3 x y x -
d1c2688eda80 copies: document cases in _chain()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42226
diff changeset
124 # 4 x y z x->z
d1c2688eda80 copies: document cases in _chain()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42226
diff changeset
125 # 5 - x y -
d1c2688eda80 copies: document cases in _chain()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42226
diff changeset
126 # 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
127 #
f3d06d37e194 copies: split up _chain() in naive chaining and filtering steps
Martin von Zweigbergk <martinvonz@google.com>
parents: 42344
diff changeset
128 # _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
129 # 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
130 # 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
131 # 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
132
42373
f3d06d37e194 copies: split up _chain() in naive chaining and filtering steps
Martin von Zweigbergk <martinvonz@google.com>
parents: 42344
diff changeset
133 for k, v in list(t.items()):
f3d06d37e194 copies: split up _chain() in naive chaining and filtering steps
Martin von Zweigbergk <martinvonz@google.com>
parents: 42344
diff changeset
134 # remove copies from files that didn't exist
f3d06d37e194 copies: split up _chain() in naive chaining and filtering steps
Martin von Zweigbergk <martinvonz@google.com>
parents: 42344
diff changeset
135 if v not in src:
f3d06d37e194 copies: split up _chain() in naive chaining and filtering steps
Martin von Zweigbergk <martinvonz@google.com>
parents: 42344
diff changeset
136 del t[k]
f3d06d37e194 copies: split up _chain() in naive chaining and filtering steps
Martin von Zweigbergk <martinvonz@google.com>
parents: 42344
diff changeset
137 # remove criss-crossed copies
f3d06d37e194 copies: split up _chain() in naive chaining and filtering steps
Martin von Zweigbergk <martinvonz@google.com>
parents: 42344
diff changeset
138 elif k in src and v in dst:
f3d06d37e194 copies: split up _chain() in naive chaining and filtering steps
Martin von Zweigbergk <martinvonz@google.com>
parents: 42344
diff changeset
139 del t[k]
f3d06d37e194 copies: split up _chain() in naive chaining and filtering steps
Martin von Zweigbergk <martinvonz@google.com>
parents: 42344
diff changeset
140 # remove copies to files that were then removed
f3d06d37e194 copies: split up _chain() in naive chaining and filtering steps
Martin von Zweigbergk <martinvonz@google.com>
parents: 42344
diff changeset
141 elif k not in dst:
f3d06d37e194 copies: split up _chain() in naive chaining and filtering steps
Martin von Zweigbergk <martinvonz@google.com>
parents: 42344
diff changeset
142 del t[k]
f3d06d37e194 copies: split up _chain() in naive chaining and filtering steps
Martin von Zweigbergk <martinvonz@google.com>
parents: 42344
diff changeset
143
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
144
42373
f3d06d37e194 copies: split up _chain() in naive chaining and filtering steps
Martin von Zweigbergk <martinvonz@google.com>
parents: 42344
diff changeset
145 def _chain(a, b):
f3d06d37e194 copies: split up _chain() in naive chaining and filtering steps
Martin von Zweigbergk <martinvonz@google.com>
parents: 42344
diff changeset
146 """chain two sets of copies 'a' and 'b'"""
15775
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
147 t = a.copy()
43106
d783f945a701 py3: finish porting iteritems() to pycompat and remove source transformer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43077
diff changeset
148 for k, v in pycompat.iteritems(b):
15775
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
149 if v in t:
42255
00e065fb1469 copies: remove redundant filtering of ping-pong renames in _chain()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42241
diff changeset
150 t[k] = t[v]
42230
fdbeacb9d456 copies: filter out copies from non-existent source later in _chain()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42229
diff changeset
151 else:
15775
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
152 t[k] = v
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
153 return t
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
154
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
155
42595
819712deac69 copies: follow copies across merge base without source file (issue6163)
Martin von Zweigbergk <martinvonz@google.com>
parents: 42594
diff changeset
156 def _tracefile(fctx, am, basemf, limit):
35421
9cf37d111acb copies: consistently use """ for docstrings
Martin von Zweigbergk <martinvonz@google.com>
parents: 35420
diff changeset
157 """return file context that is the ancestor of fctx present in ancestor
9cf37d111acb copies: consistently use """ for docstrings
Martin von Zweigbergk <martinvonz@google.com>
parents: 35420
diff changeset
158 manifest am, stopping after the first ancestor lower than limit"""
15775
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
159
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
160 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
161 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
162 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
163 return path
42595
819712deac69 copies: follow copies across merge base without source file (issue6163)
Martin von Zweigbergk <martinvonz@google.com>
parents: 42594
diff changeset
164 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
165 return path
42241
c74226916c8c copies: make "limit" argument to _tracefile() mandatory
Martin von Zweigbergk <martinvonz@google.com>
parents: 42230
diff changeset
166 if not f.isintroducedafter(limit):
15775
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
167 return None
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
168
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
169
41752
012f695546aa copies: respect narrowmatcher in "parent -> working dir" case
Martin von Zweigbergk <martinvonz@google.com>
parents: 41724
diff changeset
170 def _dirstatecopies(repo, match=None):
012f695546aa copies: respect narrowmatcher in "parent -> working dir" case
Martin von Zweigbergk <martinvonz@google.com>
parents: 41724
diff changeset
171 ds = repo.dirstate
15775
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
172 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
173 for k in list(c):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
174 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
175 del c[k]
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
176 return c
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
177
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
178
24782
4906dc0e038c copies: add matcher parameter to copy logic
Durham Goode <durham@fb.com>
parents: 24625
diff changeset
179 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
180 """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
181 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
182 files _forwardcopies is about to process.
d7d08337b3f6 copy: move _forwardcopies file logic to a function
Durham Goode <durham@fb.com>
parents: 24010
diff changeset
183 """
24782
4906dc0e038c copies: add matcher parameter to copy logic
Durham Goode <durham@fb.com>
parents: 24625
diff changeset
184 ma = a.manifest()
4906dc0e038c copies: add matcher parameter to copy logic
Durham Goode <durham@fb.com>
parents: 24625
diff changeset
185 mb = b.manifest()
31256
5a909a8098a1 copies: remove use of manifest.matches
Durham Goode <durham@fb.com>
parents: 30581
diff changeset
186 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
187
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
188
42115
27475ae67676 copies: extract function for deciding whether to use changeset-centric algos
Martin von Zweigbergk <martinvonz@google.com>
parents: 41936
diff changeset
189 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
190 """Checks if we should use changeset-centric copy algorithms"""
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
191 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
192 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
193 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
194
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
195
42595
819712deac69 copies: follow copies across merge base without source file (issue6163)
Martin von Zweigbergk <martinvonz@google.com>
parents: 42594
diff changeset
196 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
197 """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
198 # 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
199 # 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
200 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
201
42115
27475ae67676 copies: extract function for deciding whether to use changeset-centric algos
Martin von Zweigbergk <martinvonz@google.com>
parents: 41936
diff changeset
202 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
203 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
204
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
205 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
206 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
207 if debug:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
208 dbg(b'debug.copies: looking into rename from %s to %s\n' % (a, b))
41393
dc50121126ae copies: pass contexts into _findlimit()
Martin von Zweigbergk <martinvonz@google.com>
parents: 41392
diff changeset
209 limit = _findlimit(repo, a, b)
40057
25b2868206e2 copies: add a devel debug mode to trace what copy tracing does
Boris Feld <boris.feld@octobus.net>
parents: 39966
diff changeset
210 if debug:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
211 dbg(b'debug.copies: search limit: %d\n' % limit)
20294
243ea5ffdf31 diff: search beyond ancestor when detecting renames
Mads Kiilerich <madski@unity3d.com>
parents: 19178
diff changeset
212 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
213 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
214
15775
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
215 # find where new files came from
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
216 # 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
217 # 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
218 cm = {}
28000
d4247c306d82 copies: optimize forward copy detection logic for rebases
Durham Goode <durham@fb.com>
parents: 27876
diff changeset
219
d4247c306d82 copies: optimize forward copy detection logic for rebases
Durham Goode <durham@fb.com>
parents: 27876
diff changeset
220 # 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
221 # 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
222 # 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
223 # 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
224 # 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
225 # this comparison.
d4247c306d82 copies: optimize forward copy detection logic for rebases
Durham Goode <durham@fb.com>
parents: 27876
diff changeset
226 forwardmissingmatch = match
33867
252fb66ee5bb copies: use intersectmatchers() in non-merge p1 optimization
Yuya Nishihara <yuya@tcha.org>
parents: 33822
diff changeset
227 if b.p1() == a and b.p2().node() == node.nullid:
41936
a791623458ef copies: remove dependency on scmutil by directly using match.exact()
Martin von Zweigbergk <martinvonz@google.com>
parents: 41932
diff changeset
228 filesmatcher = matchmod.exact(b.files())
33867
252fb66ee5bb copies: use intersectmatchers() in non-merge p1 optimization
Yuya Nishihara <yuya@tcha.org>
parents: 33822
diff changeset
229 forwardmissingmatch = matchmod.intersectmatchers(match, filesmatcher)
28000
d4247c306d82 copies: optimize forward copy detection logic for rebases
Durham Goode <durham@fb.com>
parents: 27876
diff changeset
230 missing = _computeforwardmissing(a, b, match=forwardmissingmatch)
d4247c306d82 copies: optimize forward copy detection logic for rebases
Durham Goode <durham@fb.com>
parents: 27876
diff changeset
231
23980
c1ce5442453f _adjustlinkrev: reuse ancestors set during rename detection (issue4514)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23139
diff changeset
232 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
233
25b2868206e2 copies: add a devel debug mode to trace what copy tracing does
Boris Feld <boris.feld@octobus.net>
parents: 39966
diff changeset
234 if debug:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
235 dbg(b'debug.copies: missing files to search: %d\n' % len(missing))
40057
25b2868206e2 copies: add a devel debug mode to trace what copy tracing does
Boris Feld <boris.feld@octobus.net>
parents: 39966
diff changeset
236
42210
390ec72b8ea4 copies: process files in deterministic order for stable tests
Martin von Zweigbergk <martinvonz@google.com>
parents: 42169
diff changeset
237 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
238 if debug:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
239 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
240 fctx = b[f]
c1ce5442453f _adjustlinkrev: reuse ancestors set during rename detection (issue4514)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23139
diff changeset
241 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
242
40058
cf01616f8d96 copies: add time information to the debug information
Boris Feld <boris.feld@octobus.net>
parents: 40057
diff changeset
243 if debug:
cf01616f8d96 copies: add time information to the debug information
Boris Feld <boris.feld@octobus.net>
parents: 40057
diff changeset
244 start = util.timer()
42595
819712deac69 copies: follow copies across merge base without source file (issue6163)
Martin von Zweigbergk <martinvonz@google.com>
parents: 42594
diff changeset
245 opath = _tracefile(fctx, am, basemf, limit)
42548
4ebbd7c4a3c5 copies: return only path from _tracefile() since that's all caller needs
Martin von Zweigbergk <martinvonz@google.com>
parents: 42520
diff changeset
246 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
247 if debug:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
248 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
249 cm[f] = opath
40058
cf01616f8d96 copies: add time information to the debug information
Boris Feld <boris.feld@octobus.net>
parents: 40057
diff changeset
250 if debug:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
251 dbg(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
252 b'debug.copies: time: %f seconds\n'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
253 % (util.timer() - start)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
254 )
35422
8801cdcea01f copies: extract method for getting non-wdir forward copies
Martin von Zweigbergk <martinvonz@google.com>
parents: 35421
diff changeset
255 return cm
8801cdcea01f copies: extract method for getting non-wdir forward copies
Martin von Zweigbergk <martinvonz@google.com>
parents: 35421
diff changeset
256
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
257
41756
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
258 def _changesetforwardcopies(a, b, match):
42645
8c5a36805d5d copies: fix crash on in changeset-centric tracing from commit to itself
Martin von Zweigbergk <martinvonz@google.com>
parents: 42595
diff changeset
259 if a.rev() in (node.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
260 return {}
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
261
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
262 repo = a.repo()
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
263 children = {}
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
264 cl = repo.changelog
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
265 missingrevs = cl.findmissingrevs(common=[a.rev()], heads=[b.rev()])
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
266 for r in missingrevs:
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
267 for p in cl.parentrevs(r):
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
268 if p == node.nullrev:
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
269 continue
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
270 if p not in children:
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
271 children[p] = [r]
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
272 else:
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
273 children[p].append(r)
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
274
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
275 roots = set(children) - set(missingrevs)
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
276 # 'work' contains 3-tuples of a (revision number, parent number, copies).
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
277 # The parent number is only used for knowing which parent the copies dict
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
278 # came from.
42520
898b36f74f75 copies: document how 'copies' dict instances are reused
Martin von Zweigbergk <martinvonz@google.com>
parents: 42519
diff changeset
279 # NOTE: To reduce costly copying the 'copies' dicts, we reuse the same
898b36f74f75 copies: document how 'copies' dict instances are reused
Martin von Zweigbergk <martinvonz@google.com>
parents: 42519
diff changeset
280 # instance for *one* of the child nodes (the last one). Once an instance
898b36f74f75 copies: document how 'copies' dict instances are reused
Martin von Zweigbergk <martinvonz@google.com>
parents: 42519
diff changeset
281 # has been put on the queue, it is thus no longer safe to modify it.
898b36f74f75 copies: document how 'copies' dict instances are reused
Martin von Zweigbergk <martinvonz@google.com>
parents: 42519
diff changeset
282 # Conversely, it *is* safe to modify an instance popped off the queue.
41756
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
283 work = [(r, 1, {}) for r in roots]
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
284 heapq.heapify(work)
42488
c0b51449bf6b copies: avoid calling matcher if matcher.always()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42487
diff changeset
285 alwaysmatch = match.always()
41756
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
286 while work:
42519
907cef396635 copies: simplify merging of copy dicts on merge commits
Martin von Zweigbergk <martinvonz@google.com>
parents: 42518
diff changeset
287 r, i1, copies = heapq.heappop(work)
41756
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
288 if work and work[0][0] == r:
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
289 # We are tracing copies from both parents
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
290 r, i2, copies2 = heapq.heappop(work)
42519
907cef396635 copies: simplify merging of copy dicts on merge commits
Martin von Zweigbergk <martinvonz@google.com>
parents: 42518
diff changeset
291 for dst, src in copies2.items():
42486
35d674a3d5db copies: don't filter out copy targets created on other side of merge commit
Martin von Zweigbergk <martinvonz@google.com>
parents: 42485
diff changeset
292 # Unlike when copies are stored in the filelog, we consider
35d674a3d5db copies: don't filter out copy targets created on other side of merge commit
Martin von Zweigbergk <martinvonz@google.com>
parents: 42485
diff changeset
293 # it a copy even if the destination already existed on the
35d674a3d5db copies: don't filter out copy targets created on other side of merge commit
Martin von Zweigbergk <martinvonz@google.com>
parents: 42485
diff changeset
294 # other branch. It's simply too expensive to check if the
35d674a3d5db copies: don't filter out copy targets created on other side of merge commit
Martin von Zweigbergk <martinvonz@google.com>
parents: 42485
diff changeset
295 # file existed in the manifest.
42519
907cef396635 copies: simplify merging of copy dicts on merge commits
Martin von Zweigbergk <martinvonz@google.com>
parents: 42518
diff changeset
296 if dst not in copies:
907cef396635 copies: simplify merging of copy dicts on merge commits
Martin von Zweigbergk <martinvonz@google.com>
parents: 42518
diff changeset
297 # If it was copied on the p1 side, leave it as copied from
42486
35d674a3d5db copies: don't filter out copy targets created on other side of merge commit
Martin von Zweigbergk <martinvonz@google.com>
parents: 42485
diff changeset
298 # that side, even if it was also copied on the p2 side.
35d674a3d5db copies: don't filter out copy targets created on other side of merge commit
Martin von Zweigbergk <martinvonz@google.com>
parents: 42485
diff changeset
299 copies[dst] = copies2[dst]
41756
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
300 if r == b.rev():
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
301 return copies
42487
5ceb91136ebe copies: avoid unnecessary copying of copy dict
Martin von Zweigbergk <martinvonz@google.com>
parents: 42486
diff changeset
302 for i, c in enumerate(children[r]):
41756
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
303 childctx = repo[c]
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
304 if r == childctx.p1().rev():
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
305 parent = 1
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
306 childcopies = childctx.p1copies()
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
307 else:
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
308 assert r == childctx.p2().rev()
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
309 parent = 2
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
310 childcopies = childctx.p2copies()
42488
c0b51449bf6b copies: avoid calling matcher if matcher.always()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42487
diff changeset
311 if not alwaysmatch:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
312 childcopies = {
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
313 dst: src for dst, src in childcopies.items() if match(dst)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
314 }
42487
5ceb91136ebe copies: avoid unnecessary copying of copy dict
Martin von Zweigbergk <martinvonz@google.com>
parents: 42486
diff changeset
315 # Copy the dict only if later iterations will also need it
5ceb91136ebe copies: avoid unnecessary copying of copy dict
Martin von Zweigbergk <martinvonz@google.com>
parents: 42486
diff changeset
316 if i != len(children[r]) - 1:
42514
e7c55e24d6bf copies: avoid reusing the same variable for two different copy dicts
Martin von Zweigbergk <martinvonz@google.com>
parents: 42488
diff changeset
317 newcopies = copies.copy()
42487
5ceb91136ebe copies: avoid unnecessary copying of copy dict
Martin von Zweigbergk <martinvonz@google.com>
parents: 42486
diff changeset
318 else:
42514
e7c55e24d6bf copies: avoid reusing the same variable for two different copy dicts
Martin von Zweigbergk <martinvonz@google.com>
parents: 42488
diff changeset
319 newcopies = copies
e7c55e24d6bf copies: avoid reusing the same variable for two different copy dicts
Martin von Zweigbergk <martinvonz@google.com>
parents: 42488
diff changeset
320 if childcopies:
e7c55e24d6bf copies: avoid reusing the same variable for two different copy dicts
Martin von Zweigbergk <martinvonz@google.com>
parents: 42488
diff changeset
321 newcopies = _chain(newcopies, childcopies)
42485
4c39c99d9492 copies: do full filtering at end of _changesetforwardcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42373
diff changeset
322 for f in childctx.filesremoved():
42514
e7c55e24d6bf copies: avoid reusing the same variable for two different copy dicts
Martin von Zweigbergk <martinvonz@google.com>
parents: 42488
diff changeset
323 if f in newcopies:
e7c55e24d6bf copies: avoid reusing the same variable for two different copy dicts
Martin von Zweigbergk <martinvonz@google.com>
parents: 42488
diff changeset
324 del newcopies[f]
e7c55e24d6bf copies: avoid reusing the same variable for two different copy dicts
Martin von Zweigbergk <martinvonz@google.com>
parents: 42488
diff changeset
325 heapq.heappush(work, (c, parent, newcopies))
41756
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
326 assert False
49ad315b39ee copies: do copy tracing based on ctx.p[12]copies() if configured
Martin von Zweigbergk <martinvonz@google.com>
parents: 41754
diff changeset
327
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
328
42595
819712deac69 copies: follow copies across merge base without source file (issue6163)
Martin von Zweigbergk <martinvonz@google.com>
parents: 42594
diff changeset
329 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
330 """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
331
42595
819712deac69 copies: follow copies across merge base without source file (issue6163)
Martin von Zweigbergk <martinvonz@google.com>
parents: 42594
diff changeset
332 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
333 base = a
40448
873f3682c8af narrow: make copies.pathcopies() filter with narrowspec again
Martin von Zweigbergk <martinvonz@google.com>
parents: 40076
diff changeset
334 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
335 # check for working copy
8801cdcea01f copies: extract method for getting non-wdir forward copies
Martin von Zweigbergk <martinvonz@google.com>
parents: 35421
diff changeset
336 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
337 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
338 # 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
339 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
340 else:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
341 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
342 return copies
15775
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
343
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
344
41753
3158cb74fbca copies: make _backwardrenames() filter out copies by destination
Martin von Zweigbergk <martinvonz@google.com>
parents: 41752
diff changeset
345 def _backwardrenames(a, b, match):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
346 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
347 return {}
38f92d12357c copy: add flag for disabling copy tracing
Durham Goode <durham@fb.com>
parents: 25924
diff changeset
348
18136
f23dea2b296e copies: do not track backward copies, only renames (issue3739)
Siddharth Agarwal <sid0@fb.com>
parents: 18135
diff changeset
349 # 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
350 # 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
351 # arbitrarily pick one of the renames.
41753
3158cb74fbca copies: make _backwardrenames() filter out copies by destination
Martin von Zweigbergk <martinvonz@google.com>
parents: 41752
diff changeset
352 # We don't want to pass in "match" here, since that would filter
3158cb74fbca copies: make _backwardrenames() filter out copies by destination
Martin von Zweigbergk <martinvonz@google.com>
parents: 41752
diff changeset
353 # the destination by it. Since we're reversing the copies, we want
3158cb74fbca copies: make _backwardrenames() filter out copies by destination
Martin von Zweigbergk <martinvonz@google.com>
parents: 41752
diff changeset
354 # to filter the source instead.
15775
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
355 f = _forwardcopies(b, a)
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
356 r = {}
43106
d783f945a701 py3: finish porting iteritems() to pycompat and remove source transformer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43077
diff changeset
357 for k, v in sorted(pycompat.iteritems(f)):
41753
3158cb74fbca copies: make _backwardrenames() filter out copies by destination
Martin von Zweigbergk <martinvonz@google.com>
parents: 41752
diff changeset
358 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
359 continue
18136
f23dea2b296e copies: do not track backward copies, only renames (issue3739)
Siddharth Agarwal <sid0@fb.com>
parents: 18135
diff changeset
360 # remove copies
f23dea2b296e copies: do not track backward copies, only renames (issue3739)
Siddharth Agarwal <sid0@fb.com>
parents: 18135
diff changeset
361 if v in a:
f23dea2b296e copies: do not track backward copies, only renames (issue3739)
Siddharth Agarwal <sid0@fb.com>
parents: 18135
diff changeset
362 continue
15775
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
363 r[v] = k
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
364 return r
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
365
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
366
24782
4906dc0e038c copies: add matcher parameter to copy logic
Durham Goode <durham@fb.com>
parents: 24625
diff changeset
367 def pathcopies(x, y, match=None):
35421
9cf37d111acb copies: consistently use """ for docstrings
Martin von Zweigbergk <martinvonz@google.com>
parents: 35420
diff changeset
368 """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
369 repo = x._repo
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
370 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
371 if debug:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
372 repo.ui.debug(
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
373 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
374 )
15775
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
375 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
376 return {}
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
377 a = y.ancestor(x)
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
378 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
379 if debug:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
380 repo.ui.debug(b'debug.copies: search mode: forward\n')
42591
bcb4b5c5964b copies: move short-circuiting of dirstate copies out of _forwardcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42548
diff changeset
381 if y.rev() is None and x == y.p1():
bcb4b5c5964b copies: move short-circuiting of dirstate copies out of _forwardcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42548
diff changeset
382 # short-circuit to avoid issues with merge states
bcb4b5c5964b copies: move short-circuiting of dirstate copies out of _forwardcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42548
diff changeset
383 return _dirstatecopies(repo, match)
42592
a48f6f18dc6d copies: remove most early returns from pathcopies() and _forwardcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42591
diff changeset
384 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
385 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
386 if debug:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
387 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
388 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
389 else:
a48f6f18dc6d copies: remove most early returns from pathcopies() and _forwardcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42591
diff changeset
390 if debug:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
391 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
392 base = None
819712deac69 copies: follow copies across merge base without source file (issue6163)
Martin von Zweigbergk <martinvonz@google.com>
parents: 42594
diff changeset
393 if a.rev() != node.nullrev:
819712deac69 copies: follow copies across merge base without source file (issue6163)
Martin von Zweigbergk <martinvonz@google.com>
parents: 42594
diff changeset
394 base = x
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
395 copies = _chain(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
396 _backwardrenames(x, a, match=match),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
397 _forwardcopies(a, y, base, match=match),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
398 )
42594
d013099c551b copies: filter invalid copies only at end of pathcopies() (issue6163)
Martin von Zweigbergk <martinvonz@google.com>
parents: 42593
diff changeset
399 _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
400 return copies
15774
0bd17a4bed88 copies: split the copies api for "normal" and merge cases (API)
Matt Mackall <mpm@selenic.com>
parents: 14494
diff changeset
401
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
402
30186
f7ed5af31242 mergecopies: rename 'ca' to 'base'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30185
diff changeset
403 def mergecopies(repo, c1, c2, base):
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
404 """
42118
967c098eed33 copies: move comment about implementation of mergecopies() to end
Martin von Zweigbergk <martinvonz@google.com>
parents: 42115
diff changeset
405 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
406 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
407
b4b196092cc3 copytrace: move the default copytracing algorithm in a new function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34077
diff changeset
408 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
409 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
410 For example:
33822
42ad7cc645a4 copies: add more details to the documentation of mergecopies()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32640
diff changeset
411
42ad7cc645a4 copies: add more details to the documentation of mergecopies()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32640
diff changeset
412 o ---> 4 another commit
42ad7cc645a4 copies: add more details to the documentation of mergecopies()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32640
diff changeset
413 |
42ad7cc645a4 copies: add more details to the documentation of mergecopies()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32640
diff changeset
414 | 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
415 | /
42ad7cc645a4 copies: add more details to the documentation of mergecopies()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32640
diff changeset
416 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
417 |/
42ad7cc645a4 copies: add more details to the documentation of mergecopies()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32640
diff changeset
418 o ---> 1 merge base
42ad7cc645a4 copies: add more details to the documentation of mergecopies()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32640
diff changeset
419
42ad7cc645a4 copies: add more details to the documentation of mergecopies()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32640
diff changeset
420 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
421 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
422 message:
42ad7cc645a4 copies: add more details to the documentation of mergecopies()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32640
diff changeset
423
42ad7cc645a4 copies: add more details to the documentation of mergecopies()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32640
diff changeset
424 ```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
425
30581
43a9e02a7b7f graft: support grafting changes to new file in renamed directory (issue5436)
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30361
diff changeset
426 Returns five dicts: "copy", "movewithdir", "diverge", "renamedelete" and
43a9e02a7b7f graft: support grafting changes to new file in renamed directory (issue5436)
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30361
diff changeset
427 "dirmove".
16168
7bbabfe25321 copies: add docstring for mergecopies
Matt Mackall <mpm@selenic.com>
parents: 15994
diff changeset
428
16177
b8c1a8a57540 copies: fix mergecopies doc mapping direction
Matt Mackall <mpm@selenic.com>
parents: 16169
diff changeset
429 "copy" is a mapping from destination name -> source name,
16168
7bbabfe25321 copies: add docstring for mergecopies
Matt Mackall <mpm@selenic.com>
parents: 15994
diff changeset
430 where source is in c1 and destination is in c2 or vice-versa.
7bbabfe25321 copies: add docstring for mergecopies
Matt Mackall <mpm@selenic.com>
parents: 15994
diff changeset
431
18134
6c35b53cd28b copies: separate moves via directory renames from explicit copies
Siddharth Agarwal <sid0@fb.com>
parents: 17055
diff changeset
432 "movewithdir" is a mapping from source name -> destination name,
6c35b53cd28b copies: separate moves via directory renames from explicit copies
Siddharth Agarwal <sid0@fb.com>
parents: 17055
diff changeset
433 where the file at source present in one context but not the other
6c35b53cd28b copies: separate moves via directory renames from explicit copies
Siddharth Agarwal <sid0@fb.com>
parents: 17055
diff changeset
434 needs to be moved to destination by the merge process, because the
6c35b53cd28b copies: separate moves via directory renames from explicit copies
Siddharth Agarwal <sid0@fb.com>
parents: 17055
diff changeset
435 other context moved the directory it is in.
6c35b53cd28b copies: separate moves via directory renames from explicit copies
Siddharth Agarwal <sid0@fb.com>
parents: 17055
diff changeset
436
16168
7bbabfe25321 copies: add docstring for mergecopies
Matt Mackall <mpm@selenic.com>
parents: 15994
diff changeset
437 "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
438 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
439
98687cdddcb1 merge: warn about file deleted in one branch and renamed in other (issue3074)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 16792
diff changeset
440 "renamedelete" is a mapping of source name -> list of destination
98687cdddcb1 merge: warn about file deleted in one branch and renamed in other (issue3074)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 16792
diff changeset
441 names for files deleted in c1 that were renamed in c2 or vice-versa.
30581
43a9e02a7b7f graft: support grafting changes to new file in renamed directory (issue5436)
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30361
diff changeset
442
43a9e02a7b7f graft: support grafting changes to new file in renamed directory (issue5436)
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30361
diff changeset
443 "dirmove" is a mapping of detected source dir -> destination dir renames.
43a9e02a7b7f graft: support grafting changes to new file in renamed directory (issue5436)
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30361
diff changeset
444 This is needed for handling changes to new files previously grafted into
43a9e02a7b7f graft: support grafting changes to new file in renamed directory (issue5436)
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30361
diff changeset
445 renamed directories.
42118
967c098eed33 copies: move comment about implementation of mergecopies() to end
Martin von Zweigbergk <martinvonz@google.com>
parents: 42115
diff changeset
446
967c098eed33 copies: move comment about implementation of mergecopies() to end
Martin von Zweigbergk <martinvonz@google.com>
parents: 42115
diff changeset
447 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
448 """
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
449 # 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
450 if not c1 or not c2 or c1 == c2:
30581
43a9e02a7b7f graft: support grafting changes to new file in renamed directory (issue5436)
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30361
diff changeset
451 return {}, {}, {}, {}, {}
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
452
41752
012f695546aa copies: respect narrowmatcher in "parent -> working dir" case
Martin von Zweigbergk <martinvonz@google.com>
parents: 41724
diff changeset
453 narrowmatch = c1.repo().narrowmatch()
012f695546aa copies: respect narrowmatcher in "parent -> working dir" case
Martin von Zweigbergk <martinvonz@google.com>
parents: 41724
diff changeset
454
6646
9eb274d773d9 copies: teach copies about dirstate.copies
Matt Mackall <mpm@selenic.com>
parents: 6431
diff changeset
455 # avoid silly behavior for parent -> working dir
13878
a8d13ee0ce68 misc: replace .parents()[0] with p1()
Matt Mackall <mpm@selenic.com>
parents: 12683
diff changeset
456 if c2.node() is None and c1.node() == repo.dirstate.p1():
41752
012f695546aa copies: respect narrowmatcher in "parent -> working dir" case
Martin von Zweigbergk <martinvonz@google.com>
parents: 41724
diff changeset
457 return _dirstatecopies(repo, narrowmatch), {}, {}, {}, {}
6646
9eb274d773d9 copies: teach copies about dirstate.copies
Matt Mackall <mpm@selenic.com>
parents: 6431
diff changeset
458
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
459 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
460 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
461 # 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
462 # value, so we should rely on making sure copytracing is on such cases
d8ca7b99fc51 copies: move check for experimental.copytrace==<falsy> earlier
Martin von Zweigbergk <martinvonz@google.com>
parents: 42224
diff changeset
463 return {}, {}, {}, {}, {}
34078
b4b196092cc3 copytrace: move the default copytracing algorithm in a new function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34077
diff changeset
464
42226
a6be3af3a397 copies: ignore heuristics copytracing when using changeset-centric algos
Martin von Zweigbergk <martinvonz@google.com>
parents: 42225
diff changeset
465 if usechangesetcentricalgo(repo):
a6be3af3a397 copies: ignore heuristics copytracing when using changeset-centric algos
Martin von Zweigbergk <martinvonz@google.com>
parents: 42225
diff changeset
466 # 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
467 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
468
26013
38f92d12357c copy: add flag for disabling copy tracing
Durham Goode <durham@fb.com>
parents: 25924
diff changeset
469 # 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
470 # 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
471 # rebase.
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
472 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
473 # 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
474 # 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
475 # 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
476 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
477 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
478 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
479 else:
b4b196092cc3 copytrace: move the default copytracing algorithm in a new function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34077
diff changeset
480 return _fullcopytracing(repo, c1, c2, base)
26013
38f92d12357c copy: add flag for disabling copy tracing
Durham Goode <durham@fb.com>
parents: 25924
diff changeset
481
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
482
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
483 def _isfullcopytraceable(repo, c1, base):
34366
d00910b286cd copytrace: use ctx.mutable() instead of adhoc constant of non-public phases
Yuya Nishihara <yuya@tcha.org>
parents: 34348
diff changeset
484 """ Checks that if base, source and destination are all no-public branches,
d00910b286cd copytrace: use ctx.mutable() instead of adhoc constant of non-public phases
Yuya Nishihara <yuya@tcha.org>
parents: 34348
diff changeset
485 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
486 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
487
e79b3611223b copies: add docs for config `experimental.copytrace.sourcecommitlimit`
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34366
diff changeset
488 `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
489 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
490 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
491 """
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
492 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
493 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
494 if c1.mutable() and base.mutable():
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
495 sourcecommitlimit = repo.ui.configint(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
496 b'experimental', b'copytrace.sourcecommitlimit'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
497 )
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
498 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
499 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
500 return False
fc3b8483c6cb copytrace: use the full copytracing method if only drafts are involved
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34179
diff changeset
501
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
502
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
503 def _checksinglesidecopies(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
504 src, dsts1, m1, m2, mb, c2, base, copy, renamedelete
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
505 ):
42222
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
506 if src not in m2:
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
507 # deleted on side 2
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
508 if src not in m1:
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
509 # 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
510 renamedelete[src] = dsts1
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
511 elif m2[src] != mb[src]:
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
512 if not _related(c2[src], base[src]):
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
513 return
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
514 # modified on side 2
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
515 for dst in dsts1:
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
516 if dst not in m2:
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
517 # dst not added on side 2 (handle as regular
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
518 # "both created" case in manifestmerge otherwise)
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
519 copy[dst] = src
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
520
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
521
34078
b4b196092cc3 copytrace: move the default copytracing algorithm in a new function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34077
diff changeset
522 def _fullcopytracing(repo, c1, c2, base):
b4b196092cc3 copytrace: move the default copytracing algorithm in a new function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34077
diff changeset
523 """ The full copytracing algorithm which finds all the new files that were
b4b196092cc3 copytrace: move the default copytracing algorithm in a new function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34077
diff changeset
524 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
525 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
526
b4b196092cc3 copytrace: move the default copytracing algorithm in a new function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34077
diff changeset
527 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
528 the copies.
b4b196092cc3 copytrace: move the default copytracing algorithm in a new function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34077
diff changeset
529 """
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
530 m1 = c1.manifest()
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
531 m2 = c2.manifest()
30186
f7ed5af31242 mergecopies: rename 'ca' to 'base'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30185
diff changeset
532 mb = base.manifest()
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
533
42222
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
534 copies1 = pathcopies(base, c1)
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
535 copies2 = pathcopies(base, c2)
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
536
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
537 inversecopies1 = {}
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
538 inversecopies2 = {}
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
539 for dst, src in copies1.items():
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
540 inversecopies1.setdefault(src, []).append(dst)
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
541 for dst, src in copies2.items():
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
542 inversecopies2.setdefault(src, []).append(dst)
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
543
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
544 copy = {}
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
545 diverge = {}
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
546 renamedelete = {}
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
547 allsources = set(inversecopies1) | set(inversecopies2)
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
548 for src in allsources:
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
549 dsts1 = inversecopies1.get(src)
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
550 dsts2 = inversecopies2.get(src)
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
551 if dsts1 and dsts2:
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
552 # copied/renamed on both sides
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
553 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
554 # renamed on both sides
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
555 dsts1 = set(dsts1)
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
556 dsts2 = set(dsts2)
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
557 # 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
558 # 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
559 # 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
560 # and 'd' and deletes 'a'.
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
561 if dsts1 & dsts2:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
562 for dst in dsts1 & dsts2:
42222
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
563 copy[dst] = src
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
564 else:
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
565 diverge[src] = sorted(dsts1 | dsts2)
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
566 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
567 # copied on both sides
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
568 dsts1 = set(dsts1)
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
569 dsts2 = set(dsts2)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
570 for dst in dsts1 & dsts2:
42222
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
571 copy[dst] = src
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
572 # 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
573 # on the other side
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
574 elif dsts1:
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
575 # copied/renamed only on side 1
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
576 _checksinglesidecopies(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
577 src, dsts1, m1, m2, mb, c2, base, copy, renamedelete
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
578 )
42222
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
579 elif dsts2:
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
580 # copied/renamed only on side 2
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
581 _checksinglesidecopies(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
582 src, dsts2, m2, m1, mb, c1, base, copy, renamedelete
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
583 )
42222
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
584
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
585 renamedeleteset = set()
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
586 divergeset = set()
42224
a20d7c6abff2 copies: replace .items() by .values() where appropriate
Martin von Zweigbergk <martinvonz@google.com>
parents: 42223
diff changeset
587 for dsts in diverge.values():
42222
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
588 divergeset.update(dsts)
42224
a20d7c6abff2 copies: replace .items() by .values() where appropriate
Martin von Zweigbergk <martinvonz@google.com>
parents: 42223
diff changeset
589 for dsts in renamedelete.values():
42222
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
590 renamedeleteset.update(dsts)
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
591
26659
df66736a128e copies: group bothnew with other sets
Matt Mackall <mpm@selenic.com>
parents: 26658
diff changeset
592 # find interesting file sets from manifests
39966
707c3804e607 narrow: move copies overrides to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 39945
diff changeset
593 addedinm1 = m1.filesnotin(mb, repo.narrowmatch())
707c3804e607 narrow: move copies overrides to core
Martin von Zweigbergk <martinvonz@google.com>
parents: 39945
diff changeset
594 addedinm2 = m2.filesnotin(mb, repo.narrowmatch())
42223
d69bc8ffbe6f copies: inline _computenonoverlap() in mergecopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42222
diff changeset
595 u1 = sorted(addedinm1 - addedinm2)
d69bc8ffbe6f copies: inline _computenonoverlap() in mergecopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42222
diff changeset
596 u2 = sorted(addedinm2 - addedinm1)
d69bc8ffbe6f copies: inline _computenonoverlap() in mergecopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42222
diff changeset
597
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
598 header = b" unmatched files in %s"
42223
d69bc8ffbe6f copies: inline _computenonoverlap() in mergecopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42222
diff changeset
599 if u1:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
600 repo.ui.debug(b"%s:\n %s\n" % (header % b'local', b"\n ".join(u1)))
42223
d69bc8ffbe6f copies: inline _computenonoverlap() in mergecopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42222
diff changeset
601 if u2:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
602 repo.ui.debug(b"%s:\n %s\n" % (header % b'other', b"\n ".join(u2)))
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
603
42222
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
604 fullcopy = copies1.copy()
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
605 fullcopy.update(copies2)
42166
85f5934016f9 copies: move early return for "no copies" case a little earlier
Martin von Zweigbergk <martinvonz@google.com>
parents: 42165
diff changeset
606 if not fullcopy:
85f5934016f9 copies: move early return for "no copies" case a little earlier
Martin von Zweigbergk <martinvonz@google.com>
parents: 42165
diff changeset
607 return copy, {}, diverge, renamedelete, {}
85f5934016f9 copies: move early return for "no copies" case a little earlier
Martin von Zweigbergk <martinvonz@google.com>
parents: 42165
diff changeset
608
85f5934016f9 copies: move early return for "no copies" case a little earlier
Martin von Zweigbergk <martinvonz@google.com>
parents: 42165
diff changeset
609 if repo.ui.debugflag:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
610 repo.ui.debug(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
611 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
612 b"% = renamed and deleted):\n"
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
613 )
18362
5a4f220fbfca copies: report found copies sorted
Mads Kiilerich <mads@kiilerich.com>
parents: 18355
diff changeset
614 for f in sorted(fullcopy):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
615 note = b""
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
616 if f in copy:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
617 note += b"*"
26317
07ac78ba2e37 copies: rename diverge2 to divergeset for clarity
Matt Mackall <mpm@selenic.com>
parents: 26316
diff changeset
618 if f in divergeset:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
619 note += b"!"
26658
aabfa0fb7e3e copies: rename renamedelete to renamedeleteset for clarity
Matt Mackall <mpm@selenic.com>
parents: 26657
diff changeset
620 if f in renamedeleteset:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
621 note += b"%"
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
622 repo.ui.debug(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
623 b" src: '%s' -> dst: '%s' %s\n" % (fullcopy[f], f, note)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
624 )
26317
07ac78ba2e37 copies: rename diverge2 to divergeset for clarity
Matt Mackall <mpm@selenic.com>
parents: 26316
diff changeset
625 del divergeset
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
626
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
627 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
628
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
629 # generate a directory move map
16178
828fe2ca7cbb copies: use ctx.dirs() for directory rename detection
Matt Mackall <mpm@selenic.com>
parents: 16177
diff changeset
630 d1, d2 = c1.dirs(), c2.dirs()
17055
8b7cd9a998f0 copies: re-include root directory in directory rename detection (issue3511)
Matt Mackall <mpm@selenic.com>
parents: 16795
diff changeset
631 invalid = set()
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
632 dirmove = {}
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
633
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
634 # 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
635 # 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
636 for dst, src in pycompat.iteritems(fullcopy):
25282
0f28815ef066 copies: switch to using pathutil.dirname
Durham Goode <durham@fb.com>
parents: 24782
diff changeset
637 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
638 if dsrc in invalid:
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
639 # already seen to be uninteresting
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
640 continue
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
641 elif dsrc in d1 and ddst in d1:
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
642 # 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
643 invalid.add(dsrc)
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
644 elif dsrc in d2 and ddst in d2:
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
645 # directory wasn't entirely moved remotely
39263
eebd591803ab copies: correctly skip directories that have already been considered
Kyle Lippincott <spectral@google.com>
parents: 38670
diff changeset
646 invalid.add(dsrc)
eebd591803ab copies: correctly skip directories that have already been considered
Kyle Lippincott <spectral@google.com>
parents: 38670
diff changeset
647 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
648 # 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
649 invalid.add(dsrc)
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
650 else:
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
651 # looks good so far
39263
eebd591803ab copies: correctly skip directories that have already been considered
Kyle Lippincott <spectral@google.com>
parents: 38670
diff changeset
652 dirmove[dsrc] = ddst
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
653
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
654 for i in invalid:
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
655 if i in dirmove:
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
656 del dirmove[i]
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
657 del d1, d2, invalid
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
658
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
659 if not dirmove:
30581
43a9e02a7b7f graft: support grafting changes to new file in renamed directory (issue5436)
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30361
diff changeset
660 return copy, {}, diverge, renamedelete, {}
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
661
43106
d783f945a701 py3: finish porting iteritems() to pycompat and remove source transformer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43077
diff changeset
662 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
663
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
664 for d in dirmove:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
665 repo.ui.debug(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
666 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
667 )
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
668
30183
0106f93ca1d5 checkcopies: move 'movewithdir' initialisation right before its usage
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30138
diff changeset
669 movewithdir = {}
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
670 # check unaccounted nonoverlapping files against directory moves
42222
57203e0210f8 copies: calculate mergecopies() based on pathcopies()
Martin von Zweigbergk <martinvonz@google.com>
parents: 42210
diff changeset
671 for f in u1 + u2:
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
672 if f not in fullcopy:
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
673 for d in dirmove:
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
674 if f.startswith(d):
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
675 # 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
676 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
677 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
678 movewithdir[f] = df
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
679 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
680 b" pending file src: '%s' -> dst: '%s'\n"
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
681 % (f, df)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
682 )
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
683 break
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
684
30581
43a9e02a7b7f graft: support grafting changes to new file in renamed directory (issue5436)
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30361
diff changeset
685 return copy, movewithdir, diverge, renamedelete, dirmove
19178
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
686
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
687
34179
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
688 def _heuristicscopytracing(repo, c1, c2, base):
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
689 """ Fast copytracing using filename heuristics
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
690
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
691 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
692
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
693 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
694 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
695 (same filenames but different directory names)
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
696
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
697 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
698 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
699
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
700 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
701
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
702 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
703
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
704 [experimental]
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
705 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
706
f05a6e015ecc copies: add a config to limit the number of candidates to check in heuristics
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34787
diff changeset
707 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
708 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
709 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
710 `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
711 """
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
712
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
713 if c1.rev() is None:
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
714 c1 = c1.p1()
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
715 if c2.rev() is None:
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
716 c2 = c2.p1()
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
717
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
718 copies = {}
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
719
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
720 changedfiles = set()
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
721 m1 = c1.manifest()
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
722 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
723 # 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
724 repo.ui.debug(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
725 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
726 b"an ancestor of c2\n"
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
727 )
34179
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
728 return _fullcopytracing(repo, c1, c2, base)
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
729
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
730 ctx = c2
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
731 while ctx != base:
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
732 if len(ctx.parents()) == 2:
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
733 # 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
734 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
735 return _fullcopytracing(repo, c1, c2, base)
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
736 changedfiles.update(ctx.files())
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
737 ctx = ctx.p1()
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
738
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
739 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
740 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
741 if src in m1:
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
742 copies[dst] = src
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
743
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
744 # 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
745 # 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
746 # 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
747 # 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
748 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
749 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
750
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
751 if missingfiles:
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
752 basenametofilename = collections.defaultdict(list)
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
753 dirnametofilename = collections.defaultdict(list)
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
754
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
755 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
756 basename = os.path.basename(f)
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
757 dirname = os.path.dirname(f)
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
758 basenametofilename[basename].append(f)
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
759 dirnametofilename[dirname].append(f)
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
760
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
761 for f in missingfiles:
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
762 basename = os.path.basename(f)
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
763 dirname = os.path.dirname(f)
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
764 samebasename = basenametofilename[basename]
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
765 samedirname = dirnametofilename[dirname]
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
766 movecandidates = samebasename + samedirname
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
767 # 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
768 # c2.filectx(f) won't fail
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
769 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
770 # 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
771 # 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
772 maxcandidates = repo.ui.configint(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
773 b'experimental', b'copytrace.movecandidateslimit'
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
774 )
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
775
f05a6e015ecc copies: add a config to limit the number of candidates to check in heuristics
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34787
diff changeset
776 if len(movecandidates) > maxcandidates:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
777 repo.ui.status(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
778 _(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
779 b"skipping copytracing for '%s', more "
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
780 b"candidates than the limit: %d\n"
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
781 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
782 % (f, len(movecandidates))
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
783 )
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
784 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
785
34179
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
786 for candidate in movecandidates:
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
787 f1 = c1.filectx(candidate)
37392
a4f02a17420d copies: clean up _related logic
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 36346
diff changeset
788 if _related(f1, f2):
34179
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
789 # 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
790 # 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
791 # of upstream copytracing
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
792 copies[candidate] = f
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
793
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
794 return copies, {}, {}, {}, {}
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34078
diff changeset
795
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
796
37392
a4f02a17420d copies: clean up _related logic
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 36346
diff changeset
797 def _related(f1, f2):
30138
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
798 """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
799
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
800 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
801 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
802 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
803 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
804 """
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
805
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
806 if f1 == f2:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
807 return True # a match
30138
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
808
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
809 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
810 try:
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
811 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
812
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
813 if f1r is None:
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
814 f1 = next(g1)
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
815 if f2r is None:
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
816 f2 = next(g2)
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
817
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
818 while True:
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
819 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
820 if f1r > f2r:
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
821 f1 = next(g1)
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
822 elif f2r > f1r:
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
823 f2 = next(g2)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
824 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
825 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
826 except StopIteration:
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
827 return False
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30137
diff changeset
828
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
829
34787
754b5117622f context: add workingfilectx.markcopied
Phil Cohen <phillco@fb.com>
parents: 34516
diff changeset
830 def duplicatecopies(repo, wctx, rev, fromrev, skiprev=None):
35421
9cf37d111acb copies: consistently use """ for docstrings
Martin von Zweigbergk <martinvonz@google.com>
parents: 35420
diff changeset
831 """reproduce copies from fromrev to rev in the dirstate
22901
722117c8e023 duplicatecopies: move from cmdutil to copies
Matt Mackall <mpm@selenic.com>
parents: 20990
diff changeset
832
722117c8e023 duplicatecopies: move from cmdutil to copies
Matt Mackall <mpm@selenic.com>
parents: 20990
diff changeset
833 If skiprev is specified, it's a revision that should be used to
722117c8e023 duplicatecopies: move from cmdutil to copies
Matt Mackall <mpm@selenic.com>
parents: 20990
diff changeset
834 filter copy records. Any copies that occur between fromrev and
722117c8e023 duplicatecopies: move from cmdutil to copies
Matt Mackall <mpm@selenic.com>
parents: 20990
diff changeset
835 skiprev will not be duplicated, even if they appear in the set of
722117c8e023 duplicatecopies: move from cmdutil to copies
Matt Mackall <mpm@selenic.com>
parents: 20990
diff changeset
836 copies between fromrev and rev.
35421
9cf37d111acb copies: consistently use """ for docstrings
Martin von Zweigbergk <martinvonz@google.com>
parents: 35420
diff changeset
837 """
22901
722117c8e023 duplicatecopies: move from cmdutil to copies
Matt Mackall <mpm@selenic.com>
parents: 20990
diff changeset
838 exclude = {}
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
839 ctraceconfig = repo.ui.config(b'experimental', b'copytrace')
39366
a41497b5117c copies: improve logic of deciding copytracing on based of config options
Pulkit Goyal <pulkit@yandex-team.ru>
parents: 39263
diff changeset
840 bctrace = stringutil.parsebool(ctraceconfig)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
841 if skiprev is not None and (
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
842 ctraceconfig == b'heuristics' or bctrace or bctrace is None
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
843 ):
34077
26531db4647a copytrace: replace experimental.disablecopytrace config with copytrace (BC)
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33880
diff changeset
844 # copytrace='off' skips this line, but not the entire function because
26013
38f92d12357c copy: add flag for disabling copy tracing
Durham Goode <durham@fb.com>
parents: 25924
diff changeset
845 # the line below is O(size of the repo) during a rebase, while the rest
38f92d12357c copy: add flag for disabling copy tracing
Durham Goode <durham@fb.com>
parents: 25924
diff changeset
846 # of the function is much faster (and is required for carrying copy
38f92d12357c copy: add flag for disabling copy tracing
Durham Goode <durham@fb.com>
parents: 25924
diff changeset
847 # metadata across the rebase anyway).
22901
722117c8e023 duplicatecopies: move from cmdutil to copies
Matt Mackall <mpm@selenic.com>
parents: 20990
diff changeset
848 exclude = pathcopies(repo[fromrev], repo[skiprev])
43106
d783f945a701 py3: finish porting iteritems() to pycompat and remove source transformer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43077
diff changeset
849 for dst, src in pycompat.iteritems(pathcopies(repo[fromrev], repo[rev])):
22901
722117c8e023 duplicatecopies: move from cmdutil to copies
Matt Mackall <mpm@selenic.com>
parents: 20990
diff changeset
850 if dst in exclude:
722117c8e023 duplicatecopies: move from cmdutil to copies
Matt Mackall <mpm@selenic.com>
parents: 20990
diff changeset
851 continue
42318
313812cbf4ca copies: fix duplicatecopies() with overlay context
Martin von Zweigbergk <martinvonz@google.com>
parents: 42259
diff changeset
852 if dst in wctx:
313812cbf4ca copies: fix duplicatecopies() with overlay context
Martin von Zweigbergk <martinvonz@google.com>
parents: 42259
diff changeset
853 wctx[dst].markcopied(src)
42707
3cffc7bbec26 copies: extract an explicit `computechangesetcopie` method from context
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 42645
diff changeset
854
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 43020
diff changeset
855
42707
3cffc7bbec26 copies: extract an explicit `computechangesetcopie` method from context
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 42645
diff changeset
856 def computechangesetcopies(ctx):
3cffc7bbec26 copies: extract an explicit `computechangesetcopie` method from context
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 42645
diff changeset
857 """return the copies data for a changeset
3cffc7bbec26 copies: extract an explicit `computechangesetcopie` method from context
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 42645
diff changeset
858
3cffc7bbec26 copies: extract an explicit `computechangesetcopie` method from context
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 42645
diff changeset
859 The copies data are returned as a pair of dictionnary (p1copies, p2copies).
3cffc7bbec26 copies: extract an explicit `computechangesetcopie` method from context
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 42645
diff changeset
860
3cffc7bbec26 copies: extract an explicit `computechangesetcopie` method from context
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 42645
diff changeset
861 Each dictionnary are in the form: `{newname: oldname}`
3cffc7bbec26 copies: extract an explicit `computechangesetcopie` method from context
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 42645
diff changeset
862 """
3cffc7bbec26 copies: extract an explicit `computechangesetcopie` method from context
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 42645
diff changeset
863 p1copies = {}
3cffc7bbec26 copies: extract an explicit `computechangesetcopie` method from context
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 42645
diff changeset
864 p2copies = {}
3cffc7bbec26 copies: extract an explicit `computechangesetcopie` method from context
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 42645
diff changeset
865 p1 = ctx.p1()
3cffc7bbec26 copies: extract an explicit `computechangesetcopie` method from context
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 42645
diff changeset
866 p2 = ctx.p2()
3cffc7bbec26 copies: extract an explicit `computechangesetcopie` method from context
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 42645
diff changeset
867 narrowmatch = ctx._repo.narrowmatch()
3cffc7bbec26 copies: extract an explicit `computechangesetcopie` method from context
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 42645
diff changeset
868 for dst in ctx.files():
3cffc7bbec26 copies: extract an explicit `computechangesetcopie` method from context
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 42645
diff changeset
869 if not narrowmatch(dst) or dst not in ctx:
3cffc7bbec26 copies: extract an explicit `computechangesetcopie` method from context
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 42645
diff changeset
870 continue
3cffc7bbec26 copies: extract an explicit `computechangesetcopie` method from context
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 42645
diff changeset
871 copied = ctx[dst].renamed()
3cffc7bbec26 copies: extract an explicit `computechangesetcopie` method from context
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 42645
diff changeset
872 if not copied:
3cffc7bbec26 copies: extract an explicit `computechangesetcopie` method from context
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 42645
diff changeset
873 continue
3cffc7bbec26 copies: extract an explicit `computechangesetcopie` method from context
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 42645
diff changeset
874 src, srcnode = copied
3cffc7bbec26 copies: extract an explicit `computechangesetcopie` method from context
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 42645
diff changeset
875 if src in p1 and p1[src].filenode() == srcnode:
3cffc7bbec26 copies: extract an explicit `computechangesetcopie` method from context
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 42645
diff changeset
876 p1copies[dst] = src
3cffc7bbec26 copies: extract an explicit `computechangesetcopie` method from context
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 42645
diff changeset
877 elif src in p2 and p2[src].filenode() == srcnode:
3cffc7bbec26 copies: extract an explicit `computechangesetcopie` method from context
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 42645
diff changeset
878 p2copies[dst] = src
3cffc7bbec26 copies: extract an explicit `computechangesetcopie` method from context
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 42645
diff changeset
879 return p1copies, p2copies