annotate mercurial/copies.py @ 35071:fc3b8483c6cb

copytrace: use the full copytracing method if only drafts are involved This patch adds the functionality to use the full copytracing even if `experimental.copytrace = heuristics` in cases when drafts are involved. This is also a part of copytrace extension in fbext. This also adds tests which are also taken from fbext. .. feature:: The `heuristics` option for `experimental.copytrace` performs full copytracing if both source and destination branches contains non-public changsets only. Differential Revision: https://phab.mercurial-scm.org/D625
author Pulkit Goyal <7895pulkit@gmail.com>
date Sun, 03 Sep 2017 20:06:45 +0530
parents 036d47d7cf39
children 1826d695ad58
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
26508
cfc24c22454e copies: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25724
diff changeset
8 from __future__ import absolute_import
cfc24c22454e copies: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25724
diff changeset
9
34962
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34861
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
34962
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34861
diff changeset
12 import os
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
13
26508
cfc24c22454e copies: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25724
diff changeset
14 from . import (
34650
252fb66ee5bb copies: use intersectmatchers() in non-merge p1 optimization
Yuya Nishihara <yuya@tcha.org>
parents: 34605
diff changeset
15 match as matchmod,
28671
d4247c306d82 copies: optimize forward copy detection logic for rebases
Durham Goode <durham@fb.com>
parents: 28531
diff changeset
16 node,
26508
cfc24c22454e copies: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25724
diff changeset
17 pathutil,
35071
fc3b8483c6cb copytrace: use the full copytracing method if only drafts are involved
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34962
diff changeset
18 phases,
28671
d4247c306d82 copies: optimize forward copy detection logic for rebases
Durham Goode <durham@fb.com>
parents: 28531
diff changeset
19 scmutil,
26508
cfc24c22454e copies: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25724
diff changeset
20 util,
cfc24c22454e copies: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25724
diff changeset
21 )
cfc24c22454e copies: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25724
diff changeset
22
6431
a42d8d3e6ea9 copies: refactor symmetricdifference as _findlimit
Matt Mackall <mpm@selenic.com>
parents: 6430
diff changeset
23 def _findlimit(repo, a, b):
23071
652ab726ba93 amend: fix amending rename commit with diverged topologies (issue4405)
Ryan McElroy <rmcelroy@fb.com>
parents: 22901
diff changeset
24 """
652ab726ba93 amend: fix amending rename commit with diverged topologies (issue4405)
Ryan McElroy <rmcelroy@fb.com>
parents: 22901
diff changeset
25 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
26 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
27 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
28 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
29 of the other, in which case we can return the minimum revnum of a and b.
10174
83cfa1baf8ad copies: don't report copies with unrelated branch
Patrick Mezard <pmezard@gmail.com>
parents: 9466
diff changeset
30 None if no such revision exists.
83cfa1baf8ad copies: don't report copies with unrelated branch
Patrick Mezard <pmezard@gmail.com>
parents: 9466
diff changeset
31 """
23071
652ab726ba93 amend: fix amending rename commit with diverged topologies (issue4405)
Ryan McElroy <rmcelroy@fb.com>
parents: 22901
diff changeset
32
6429
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
33 # basic idea:
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
34 # - mark a and b with different sides
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
35 # - 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
36 # on that side, otherwise it is on no side
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
37 # - 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
38 # - add unseen parents to side map
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
39 # - 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
40 # - 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
41 # - track the lowest interesting rev seen
a42d8d3e6ea9 copies: refactor symmetricdifference as _findlimit
Matt Mackall <mpm@selenic.com>
parents: 6430
diff changeset
42 # - quit when interesting revs is zero
6430
a6a66e812c34 copies: teach symmetric difference about working revisions
Matt Mackall <mpm@selenic.com>
parents: 6429
diff changeset
43
a6a66e812c34 copies: teach symmetric difference about working revisions
Matt Mackall <mpm@selenic.com>
parents: 6429
diff changeset
44 cl = repo.changelog
6752
fb42030d79d6 add __len__ and __iter__ methods to repo and revlog
Matt Mackall <mpm@selenic.com>
parents: 6658
diff changeset
45 working = len(cl) # pseudo rev for the working directory
6430
a6a66e812c34 copies: teach symmetric difference about working revisions
Matt Mackall <mpm@selenic.com>
parents: 6429
diff changeset
46 if a is None:
a6a66e812c34 copies: teach symmetric difference about working revisions
Matt Mackall <mpm@selenic.com>
parents: 6429
diff changeset
47 a = working
a6a66e812c34 copies: teach symmetric difference about working revisions
Matt Mackall <mpm@selenic.com>
parents: 6429
diff changeset
48 if b is None:
a6a66e812c34 copies: teach symmetric difference about working revisions
Matt Mackall <mpm@selenic.com>
parents: 6429
diff changeset
49 b = working
6429
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
50
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
51 side = {a: -1, b: 1}
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
52 visit = [-a, -b]
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
53 heapq.heapify(visit)
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
54 interesting = len(visit)
10174
83cfa1baf8ad copies: don't report copies with unrelated branch
Patrick Mezard <pmezard@gmail.com>
parents: 9466
diff changeset
55 hascommonancestor = False
6431
a42d8d3e6ea9 copies: refactor symmetricdifference as _findlimit
Matt Mackall <mpm@selenic.com>
parents: 6430
diff changeset
56 limit = working
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 while interesting:
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
59 r = -heapq.heappop(visit)
6430
a6a66e812c34 copies: teach symmetric difference about working revisions
Matt Mackall <mpm@selenic.com>
parents: 6429
diff changeset
60 if r == working:
a6a66e812c34 copies: teach symmetric difference about working revisions
Matt Mackall <mpm@selenic.com>
parents: 6429
diff changeset
61 parents = [cl.rev(p) for p in repo.dirstate.parents()]
a6a66e812c34 copies: teach symmetric difference about working revisions
Matt Mackall <mpm@selenic.com>
parents: 6429
diff changeset
62 else:
a6a66e812c34 copies: teach symmetric difference about working revisions
Matt Mackall <mpm@selenic.com>
parents: 6429
diff changeset
63 parents = cl.parentrevs(r)
a6a66e812c34 copies: teach symmetric difference about working revisions
Matt Mackall <mpm@selenic.com>
parents: 6429
diff changeset
64 for p in parents:
10174
83cfa1baf8ad copies: don't report copies with unrelated branch
Patrick Mezard <pmezard@gmail.com>
parents: 9466
diff changeset
65 if p < 0:
83cfa1baf8ad copies: don't report copies with unrelated branch
Patrick Mezard <pmezard@gmail.com>
parents: 9466
diff changeset
66 continue
6429
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
67 if p not in side:
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
68 # first time we see p; add it to visit
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
69 side[p] = side[r]
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
70 if side[p]:
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
71 interesting += 1
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
72 heapq.heappush(visit, -p)
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
73 elif side[p] and side[p] != side[r]:
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
74 # p was interesting but now we know better
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
75 side[p] = 0
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
76 interesting -= 1
10174
83cfa1baf8ad copies: don't report copies with unrelated branch
Patrick Mezard <pmezard@gmail.com>
parents: 9466
diff changeset
77 hascommonancestor = True
6430
a6a66e812c34 copies: teach symmetric difference about working revisions
Matt Mackall <mpm@selenic.com>
parents: 6429
diff changeset
78 if side[r]:
6431
a42d8d3e6ea9 copies: refactor symmetricdifference as _findlimit
Matt Mackall <mpm@selenic.com>
parents: 6430
diff changeset
79 limit = r # lowest rev visited
6430
a6a66e812c34 copies: teach symmetric difference about working revisions
Matt Mackall <mpm@selenic.com>
parents: 6429
diff changeset
80 interesting -= 1
10174
83cfa1baf8ad copies: don't report copies with unrelated branch
Patrick Mezard <pmezard@gmail.com>
parents: 9466
diff changeset
81
83cfa1baf8ad copies: don't report copies with unrelated branch
Patrick Mezard <pmezard@gmail.com>
parents: 9466
diff changeset
82 if not hascommonancestor:
83cfa1baf8ad copies: don't report copies with unrelated branch
Patrick Mezard <pmezard@gmail.com>
parents: 9466
diff changeset
83 return None
23071
652ab726ba93 amend: fix amending rename commit with diverged topologies (issue4405)
Ryan McElroy <rmcelroy@fb.com>
parents: 22901
diff changeset
84
652ab726ba93 amend: fix amending rename commit with diverged topologies (issue4405)
Ryan McElroy <rmcelroy@fb.com>
parents: 22901
diff changeset
85 # 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
86 # 1/ File 'a0' committed
652ab726ba93 amend: fix amending rename commit with diverged topologies (issue4405)
Ryan McElroy <rmcelroy@fb.com>
parents: 22901
diff changeset
87 # 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
88 # 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
89 # 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
90 # 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
91 #
652ab726ba93 amend: fix amending rename commit with diverged topologies (issue4405)
Ryan McElroy <rmcelroy@fb.com>
parents: 22901
diff changeset
92 # 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
93 #
652ab726ba93 amend: fix amending rename commit with diverged topologies (issue4405)
Ryan McElroy <rmcelroy@fb.com>
parents: 22901
diff changeset
94 # @ 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
95 # |
652ab726ba93 amend: fix amending rename commit with diverged topologies (issue4405)
Ryan McElroy <rmcelroy@fb.com>
parents: 22901
diff changeset
96 # o 2 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 1 a1
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 0 a0
652ab726ba93 amend: fix amending rename commit with diverged topologies (issue4405)
Ryan McElroy <rmcelroy@fb.com>
parents: 22901
diff changeset
101 #
23139
e53f6b72a0e4 spelling: fixes from proofreading of spell checker issues
Mads Kiilerich <madski@unity3d.com>
parents: 23071
diff changeset
102 # 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
103 # 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
104 # 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
105 # 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
106 return min(limit, a, b)
6429
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
107
15775
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
108 def _chain(src, dst, a, b):
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
109 '''chain two sets of copies a->b'''
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
110 t = a.copy()
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
111 for k, v in b.iteritems():
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
112 if v in t:
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
113 # found a chain
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
114 if t[v] != k:
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
115 # file wasn't renamed back to itself
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
116 t[k] = t[v]
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
117 if v not in dst:
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
118 # chain was a rename, not a copy
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
119 del t[v]
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
120 if v in src:
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
121 # file is a copy of an existing file
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
122 t[k] = v
15976
d1c74c6151c9 copies: eliminate criss-crosses when chaining
Matt Mackall <mpm@selenic.com>
parents: 15775
diff changeset
123
d1c74c6151c9 copies: eliminate criss-crosses when chaining
Matt Mackall <mpm@selenic.com>
parents: 15775
diff changeset
124 # remove criss-crossed copies
d1c74c6151c9 copies: eliminate criss-crosses when chaining
Matt Mackall <mpm@selenic.com>
parents: 15775
diff changeset
125 for k, v in t.items():
d1c74c6151c9 copies: eliminate criss-crosses when chaining
Matt Mackall <mpm@selenic.com>
parents: 15775
diff changeset
126 if k in src and v in dst:
d1c74c6151c9 copies: eliminate criss-crosses when chaining
Matt Mackall <mpm@selenic.com>
parents: 15775
diff changeset
127 del t[k]
d1c74c6151c9 copies: eliminate criss-crosses when chaining
Matt Mackall <mpm@selenic.com>
parents: 15775
diff changeset
128
15775
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
129 return t
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
130
20294
243ea5ffdf31 diff: search beyond ancestor when detecting renames
Mads Kiilerich <madski@unity3d.com>
parents: 19178
diff changeset
131 def _tracefile(fctx, am, limit=-1):
243ea5ffdf31 diff: search beyond ancestor when detecting renames
Mads Kiilerich <madski@unity3d.com>
parents: 19178
diff changeset
132 '''return file context that is the ancestor of fctx present in ancestor
243ea5ffdf31 diff: search beyond ancestor when detecting renames
Mads Kiilerich <madski@unity3d.com>
parents: 19178
diff changeset
133 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
134
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
135 for f in fctx.ancestors():
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
136 if am.get(f.path(), None) == f.filenode():
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
137 return f
23994
751d1138ce35 copies: use linkrev for file tracing limit
Matt Mackall <mpm@selenic.com>
parents: 23992
diff changeset
138 if limit >= 0 and f.linkrev() < limit and f.rev() < limit:
15775
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
139 return None
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
140
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
141 def _dirstatecopies(d):
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
142 ds = d._repo.dirstate
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
143 c = ds.copies().copy()
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
144 for k in c.keys():
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
145 if ds[k] not in 'anm':
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
146 del c[k]
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
147 return c
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
148
24961
4906dc0e038c copies: add matcher parameter to copy logic
Durham Goode <durham@fb.com>
parents: 24758
diff changeset
149 def _computeforwardmissing(a, b, match=None):
24023
d7d08337b3f6 copy: move _forwardcopies file logic to a function
Durham Goode <durham@fb.com>
parents: 24022
diff changeset
150 """Computes which files are in b but not a.
d7d08337b3f6 copy: move _forwardcopies file logic to a function
Durham Goode <durham@fb.com>
parents: 24022
diff changeset
151 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: 24022
diff changeset
152 files _forwardcopies is about to process.
d7d08337b3f6 copy: move _forwardcopies file logic to a function
Durham Goode <durham@fb.com>
parents: 24022
diff changeset
153 """
24961
4906dc0e038c copies: add matcher parameter to copy logic
Durham Goode <durham@fb.com>
parents: 24758
diff changeset
154 ma = a.manifest()
4906dc0e038c copies: add matcher parameter to copy logic
Durham Goode <durham@fb.com>
parents: 24758
diff changeset
155 mb = b.manifest()
32035
5a909a8098a1 copies: remove use of manifest.matches
Durham Goode <durham@fb.com>
parents: 31360
diff changeset
156 return mb.filesnotin(ma, match=match)
24023
d7d08337b3f6 copy: move _forwardcopies file logic to a function
Durham Goode <durham@fb.com>
parents: 24022
diff changeset
157
24961
4906dc0e038c copies: add matcher parameter to copy logic
Durham Goode <durham@fb.com>
parents: 24758
diff changeset
158 def _forwardcopies(a, b, match=None):
15775
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
159 '''find {dst@b: src@a} copy mapping where a is an ancestor of b'''
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
160
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
161 # check for working copy
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
162 w = None
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
163 if b.rev() is None:
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
164 w = b
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
165 b = w.p1()
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
166 if a == b:
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
167 # short-circuit to avoid issues with merge states
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
168 return _dirstatecopies(w)
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
169
20294
243ea5ffdf31 diff: search beyond ancestor when detecting renames
Mads Kiilerich <madski@unity3d.com>
parents: 19178
diff changeset
170 # 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
171 # one-side-only changeset, but not further back than that
243ea5ffdf31 diff: search beyond ancestor when detecting renames
Mads Kiilerich <madski@unity3d.com>
parents: 19178
diff changeset
172 limit = _findlimit(a._repo, a.rev(), b.rev())
243ea5ffdf31 diff: search beyond ancestor when detecting renames
Mads Kiilerich <madski@unity3d.com>
parents: 19178
diff changeset
173 if limit is None:
243ea5ffdf31 diff: search beyond ancestor when detecting renames
Mads Kiilerich <madski@unity3d.com>
parents: 19178
diff changeset
174 limit = -1
243ea5ffdf31 diff: search beyond ancestor when detecting renames
Mads Kiilerich <madski@unity3d.com>
parents: 19178
diff changeset
175 am = a.manifest()
243ea5ffdf31 diff: search beyond ancestor when detecting renames
Mads Kiilerich <madski@unity3d.com>
parents: 19178
diff changeset
176
15775
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
177 # find where new files came from
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
178 # 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
179 # 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
180 cm = {}
28671
d4247c306d82 copies: optimize forward copy detection logic for rebases
Durham Goode <durham@fb.com>
parents: 28531
diff changeset
181
d4247c306d82 copies: optimize forward copy detection logic for rebases
Durham Goode <durham@fb.com>
parents: 28531
diff changeset
182 # 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: 28531
diff changeset
183 # 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: 28531
diff changeset
184 # 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: 28531
diff changeset
185 # 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: 28531
diff changeset
186 # 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: 28531
diff changeset
187 # this comparison.
d4247c306d82 copies: optimize forward copy detection logic for rebases
Durham Goode <durham@fb.com>
parents: 28531
diff changeset
188 forwardmissingmatch = match
34650
252fb66ee5bb copies: use intersectmatchers() in non-merge p1 optimization
Yuya Nishihara <yuya@tcha.org>
parents: 34605
diff changeset
189 if b.p1() == a and b.p2().node() == node.nullid:
252fb66ee5bb copies: use intersectmatchers() in non-merge p1 optimization
Yuya Nishihara <yuya@tcha.org>
parents: 34605
diff changeset
190 filesmatcher = scmutil.matchfiles(a._repo, b.files())
252fb66ee5bb copies: use intersectmatchers() in non-merge p1 optimization
Yuya Nishihara <yuya@tcha.org>
parents: 34605
diff changeset
191 forwardmissingmatch = matchmod.intersectmatchers(match, filesmatcher)
28671
d4247c306d82 copies: optimize forward copy detection logic for rebases
Durham Goode <durham@fb.com>
parents: 28531
diff changeset
192 missing = _computeforwardmissing(a, b, match=forwardmissingmatch)
d4247c306d82 copies: optimize forward copy detection logic for rebases
Durham Goode <durham@fb.com>
parents: 28531
diff changeset
193
23992
c1ce5442453f _adjustlinkrev: reuse ancestors set during rename detection (issue4514)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23139
diff changeset
194 ancestrycontext = a._repo.changelog.ancestors([b.rev()], inclusive=True)
18874
3cfaace0441e copies._forwardcopies: use set operations to find missing files
Siddharth Agarwal <sid0@fb.com>
parents: 18362
diff changeset
195 for f in missing:
23992
c1ce5442453f _adjustlinkrev: reuse ancestors set during rename detection (issue4514)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23139
diff changeset
196 fctx = b[f]
c1ce5442453f _adjustlinkrev: reuse ancestors set during rename detection (issue4514)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23139
diff changeset
197 fctx._ancestrycontext = ancestrycontext
c1ce5442453f _adjustlinkrev: reuse ancestors set during rename detection (issue4514)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23139
diff changeset
198 ofctx = _tracefile(fctx, am, limit)
18874
3cfaace0441e copies._forwardcopies: use set operations to find missing files
Siddharth Agarwal <sid0@fb.com>
parents: 18362
diff changeset
199 if ofctx:
3cfaace0441e copies._forwardcopies: use set operations to find missing files
Siddharth Agarwal <sid0@fb.com>
parents: 18362
diff changeset
200 cm[f] = ofctx.path()
15775
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
201
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
202 # combine copies from dirstate if necessary
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
203 if w is not None:
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
204 cm = _chain(a, w, cm, _dirstatecopies(w))
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
205
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
206 return cm
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
207
18136
f23dea2b296e copies: do not track backward copies, only renames (issue3739)
Siddharth Agarwal <sid0@fb.com>
parents: 18135
diff changeset
208 def _backwardrenames(a, b):
34860
26531db4647a copytrace: replace experimental.disablecopytrace config with copytrace (BC)
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34663
diff changeset
209 if a._repo.ui.config('experimental', 'copytrace') == 'off':
26597
38f92d12357c copy: add flag for disabling copy tracing
Durham Goode <durham@fb.com>
parents: 26508
diff changeset
210 return {}
38f92d12357c copy: add flag for disabling copy tracing
Durham Goode <durham@fb.com>
parents: 26508
diff changeset
211
18136
f23dea2b296e copies: do not track backward copies, only renames (issue3739)
Siddharth Agarwal <sid0@fb.com>
parents: 18135
diff changeset
212 # 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
213 # 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
214 # arbitrarily pick one of the renames.
15775
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
215 f = _forwardcopies(b, a)
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
216 r = {}
18355
2330d97e7707 copies: make the loss in _backwardcopies more stable
Mads Kiilerich <mads@kiilerich.com>
parents: 18136
diff changeset
217 for k, v in sorted(f.iteritems()):
18136
f23dea2b296e copies: do not track backward copies, only renames (issue3739)
Siddharth Agarwal <sid0@fb.com>
parents: 18135
diff changeset
218 # remove copies
f23dea2b296e copies: do not track backward copies, only renames (issue3739)
Siddharth Agarwal <sid0@fb.com>
parents: 18135
diff changeset
219 if v in a:
f23dea2b296e copies: do not track backward copies, only renames (issue3739)
Siddharth Agarwal <sid0@fb.com>
parents: 18135
diff changeset
220 continue
15775
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
221 r[v] = k
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
222 return r
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
223
24961
4906dc0e038c copies: add matcher parameter to copy logic
Durham Goode <durham@fb.com>
parents: 24758
diff changeset
224 def pathcopies(x, y, match=None):
15775
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
225 '''find {dst@y: src@x} copy mapping for directed compare'''
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
226 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
227 return {}
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
228 a = y.ancestor(x)
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
229 if a == x:
24961
4906dc0e038c copies: add matcher parameter to copy logic
Durham Goode <durham@fb.com>
parents: 24758
diff changeset
230 return _forwardcopies(x, y, match=match)
15775
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
231 if a == y:
18136
f23dea2b296e copies: do not track backward copies, only renames (issue3739)
Siddharth Agarwal <sid0@fb.com>
parents: 18135
diff changeset
232 return _backwardrenames(x, y)
24961
4906dc0e038c copies: add matcher parameter to copy logic
Durham Goode <durham@fb.com>
parents: 24758
diff changeset
233 return _chain(x, y, _backwardrenames(x, a),
4906dc0e038c copies: add matcher parameter to copy logic
Durham Goode <durham@fb.com>
parents: 24758
diff changeset
234 _forwardcopies(a, y, match=match))
15774
0bd17a4bed88 copies: split the copies api for "normal" and merge cases (API)
Matt Mackall <mpm@selenic.com>
parents: 14494
diff changeset
235
30975
d738cda70894 copies: make it possible to distinguish betwen _computenonoverlap invocations
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30974
diff changeset
236 def _computenonoverlap(repo, c1, c2, addedinm1, addedinm2, baselabel=''):
24758
2cebf17c0fcc copies: pass changectx instead of manifest to _computenonoverlap
Durham Goode <durham@fb.com>
parents: 24540
diff changeset
237 """Computes, based on addedinm1 and addedinm2, the files exclusive to c1
2cebf17c0fcc copies: pass changectx instead of manifest to _computenonoverlap
Durham Goode <durham@fb.com>
parents: 24540
diff changeset
238 and c2. This is its own function so extensions can easily wrap this call
24258
30219bd46ed7 copies: only calculate 'addedinm[12]' sets once
Martin von Zweigbergk <martinvonz@google.com>
parents: 24257
diff changeset
239 to see what files mergecopies is about to process.
24380
ce847603040b copies: added manifests to computenonoverlap
Durham Goode <durham@fb.com>
parents: 24258
diff changeset
240
24758
2cebf17c0fcc copies: pass changectx instead of manifest to _computenonoverlap
Durham Goode <durham@fb.com>
parents: 24540
diff changeset
241 Even though c1 and c2 are not used in this function, they are useful in
24380
ce847603040b copies: added manifests to computenonoverlap
Durham Goode <durham@fb.com>
parents: 24258
diff changeset
242 other extensions for being able to read the file nodes of the changed files.
30975
d738cda70894 copies: make it possible to distinguish betwen _computenonoverlap invocations
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30974
diff changeset
243
d738cda70894 copies: make it possible to distinguish betwen _computenonoverlap invocations
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30974
diff changeset
244 "baselabel" can be passed to help distinguish the multiple computations
d738cda70894 copies: make it possible to distinguish betwen _computenonoverlap invocations
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30974
diff changeset
245 done in the graft case.
24022
a63c2b159df4 copy: move mergecopies file logic to a function
Durham Goode <durham@fb.com>
parents: 23994
diff changeset
246 """
24256
3a3806fe3ddf copies: replace _nonoverlap() by calls to manifestdict.filesnotin()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24255
diff changeset
247 u1 = sorted(addedinm1 - addedinm2)
3a3806fe3ddf copies: replace _nonoverlap() by calls to manifestdict.filesnotin()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24255
diff changeset
248 u2 = sorted(addedinm2 - addedinm1)
24022
a63c2b159df4 copy: move mergecopies file logic to a function
Durham Goode <durham@fb.com>
parents: 23994
diff changeset
249
30975
d738cda70894 copies: make it possible to distinguish betwen _computenonoverlap invocations
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30974
diff changeset
250 header = " unmatched files in %s"
d738cda70894 copies: make it possible to distinguish betwen _computenonoverlap invocations
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30974
diff changeset
251 if baselabel:
d738cda70894 copies: make it possible to distinguish betwen _computenonoverlap invocations
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30974
diff changeset
252 header += ' (from %s)' % baselabel
24022
a63c2b159df4 copy: move mergecopies file logic to a function
Durham Goode <durham@fb.com>
parents: 23994
diff changeset
253 if u1:
30975
d738cda70894 copies: make it possible to distinguish betwen _computenonoverlap invocations
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30974
diff changeset
254 repo.ui.debug("%s:\n %s\n" % (header % 'local', "\n ".join(u1)))
24022
a63c2b159df4 copy: move mergecopies file logic to a function
Durham Goode <durham@fb.com>
parents: 23994
diff changeset
255 if u2:
30975
d738cda70894 copies: make it possible to distinguish betwen _computenonoverlap invocations
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30974
diff changeset
256 repo.ui.debug("%s:\n %s\n" % (header % 'other', "\n ".join(u2)))
24022
a63c2b159df4 copy: move mergecopies file logic to a function
Durham Goode <durham@fb.com>
parents: 23994
diff changeset
257 return u1, u2
a63c2b159df4 copy: move mergecopies file logic to a function
Durham Goode <durham@fb.com>
parents: 23994
diff changeset
258
27296
3e3d783b0d59 copies: factor out setupctx into _makegetfctx
Matt Mackall <mpm@selenic.com>
parents: 27295
diff changeset
259 def _makegetfctx(ctx):
30827
91a3c58ecf93 copies: mark checkcopies as internal with the _ prefix
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30826
diff changeset
260 """return a 'getfctx' function suitable for _checkcopies usage
27296
3e3d783b0d59 copies: factor out setupctx into _makegetfctx
Matt Mackall <mpm@selenic.com>
parents: 27295
diff changeset
261
3e3d783b0d59 copies: factor out setupctx into _makegetfctx
Matt Mackall <mpm@selenic.com>
parents: 27295
diff changeset
262 We have to re-setup the function building 'filectx' for each
30827
91a3c58ecf93 copies: mark checkcopies as internal with the _ prefix
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30826
diff changeset
263 '_checkcopies' to ensure the linkrev adjustment is properly setup for
27296
3e3d783b0d59 copies: factor out setupctx into _makegetfctx
Matt Mackall <mpm@selenic.com>
parents: 27295
diff changeset
264 each. Linkrev adjustment is important to avoid bug in rename
3e3d783b0d59 copies: factor out setupctx into _makegetfctx
Matt Mackall <mpm@selenic.com>
parents: 27295
diff changeset
265 detection. Moreover, having a proper '_ancestrycontext' setup ensures
3e3d783b0d59 copies: factor out setupctx into _makegetfctx
Matt Mackall <mpm@selenic.com>
parents: 27295
diff changeset
266 the performance impact of this adjustment is kept limited. Without it,
3e3d783b0d59 copies: factor out setupctx into _makegetfctx
Matt Mackall <mpm@selenic.com>
parents: 27295
diff changeset
267 each file could do a full dag traversal making the time complexity of
3e3d783b0d59 copies: factor out setupctx into _makegetfctx
Matt Mackall <mpm@selenic.com>
parents: 27295
diff changeset
268 the operation explode (see issue4537).
3e3d783b0d59 copies: factor out setupctx into _makegetfctx
Matt Mackall <mpm@selenic.com>
parents: 27295
diff changeset
269
3e3d783b0d59 copies: factor out setupctx into _makegetfctx
Matt Mackall <mpm@selenic.com>
parents: 27295
diff changeset
270 This function exists here mostly to limit the impact on stable. Feel
3e3d783b0d59 copies: factor out setupctx into _makegetfctx
Matt Mackall <mpm@selenic.com>
parents: 27295
diff changeset
271 free to refactor on default.
3e3d783b0d59 copies: factor out setupctx into _makegetfctx
Matt Mackall <mpm@selenic.com>
parents: 27295
diff changeset
272 """
3e3d783b0d59 copies: factor out setupctx into _makegetfctx
Matt Mackall <mpm@selenic.com>
parents: 27295
diff changeset
273 rev = ctx.rev()
3e3d783b0d59 copies: factor out setupctx into _makegetfctx
Matt Mackall <mpm@selenic.com>
parents: 27295
diff changeset
274 repo = ctx._repo
3e3d783b0d59 copies: factor out setupctx into _makegetfctx
Matt Mackall <mpm@selenic.com>
parents: 27295
diff changeset
275 ac = getattr(ctx, '_ancestrycontext', None)
3e3d783b0d59 copies: factor out setupctx into _makegetfctx
Matt Mackall <mpm@selenic.com>
parents: 27295
diff changeset
276 if ac is None:
3e3d783b0d59 copies: factor out setupctx into _makegetfctx
Matt Mackall <mpm@selenic.com>
parents: 27295
diff changeset
277 revs = [rev]
3e3d783b0d59 copies: factor out setupctx into _makegetfctx
Matt Mackall <mpm@selenic.com>
parents: 27295
diff changeset
278 if rev is None:
3e3d783b0d59 copies: factor out setupctx into _makegetfctx
Matt Mackall <mpm@selenic.com>
parents: 27295
diff changeset
279 revs = [p.rev() for p in ctx.parents()]
3e3d783b0d59 copies: factor out setupctx into _makegetfctx
Matt Mackall <mpm@selenic.com>
parents: 27295
diff changeset
280 ac = repo.changelog.ancestors(revs, inclusive=True)
3e3d783b0d59 copies: factor out setupctx into _makegetfctx
Matt Mackall <mpm@selenic.com>
parents: 27295
diff changeset
281 ctx._ancestrycontext = ac
3e3d783b0d59 copies: factor out setupctx into _makegetfctx
Matt Mackall <mpm@selenic.com>
parents: 27295
diff changeset
282 def makectx(f, n):
31140
1070df141718 dirstate: change added/modified placeholder hash length to 20 bytes
Durham Goode <durham@fb.com>
parents: 31139
diff changeset
283 if n in node.wdirnodes: # in a working context?
27296
3e3d783b0d59 copies: factor out setupctx into _makegetfctx
Matt Mackall <mpm@selenic.com>
parents: 27295
diff changeset
284 if ctx.rev() is None:
3e3d783b0d59 copies: factor out setupctx into _makegetfctx
Matt Mackall <mpm@selenic.com>
parents: 27295
diff changeset
285 return ctx.filectx(f)
3e3d783b0d59 copies: factor out setupctx into _makegetfctx
Matt Mackall <mpm@selenic.com>
parents: 27295
diff changeset
286 return repo[None][f]
3e3d783b0d59 copies: factor out setupctx into _makegetfctx
Matt Mackall <mpm@selenic.com>
parents: 27295
diff changeset
287 fctx = repo.filectx(f, fileid=n)
3e3d783b0d59 copies: factor out setupctx into _makegetfctx
Matt Mackall <mpm@selenic.com>
parents: 27295
diff changeset
288 # setup only needed for filectx not create from a changectx
3e3d783b0d59 copies: factor out setupctx into _makegetfctx
Matt Mackall <mpm@selenic.com>
parents: 27295
diff changeset
289 fctx._ancestrycontext = ac
3e3d783b0d59 copies: factor out setupctx into _makegetfctx
Matt Mackall <mpm@selenic.com>
parents: 27295
diff changeset
290 fctx._descendantrev = rev
3e3d783b0d59 copies: factor out setupctx into _makegetfctx
Matt Mackall <mpm@selenic.com>
parents: 27295
diff changeset
291 return fctx
3e3d783b0d59 copies: factor out setupctx into _makegetfctx
Matt Mackall <mpm@selenic.com>
parents: 27295
diff changeset
292 return util.lrucachefunc(makectx)
3e3d783b0d59 copies: factor out setupctx into _makegetfctx
Matt Mackall <mpm@selenic.com>
parents: 27295
diff changeset
293
30981
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30980
diff changeset
294 def _combinecopies(copyfrom, copyto, finalcopy, diverge, incompletediverge):
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30980
diff changeset
295 """combine partial copy paths"""
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30980
diff changeset
296 remainder = {}
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30980
diff changeset
297 for f in copyfrom:
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30980
diff changeset
298 if f in copyto:
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30980
diff changeset
299 finalcopy[copyto[f]] = copyfrom[f]
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30980
diff changeset
300 del copyto[f]
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30980
diff changeset
301 for f in incompletediverge:
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30980
diff changeset
302 assert f not in diverge
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30980
diff changeset
303 ic = incompletediverge[f]
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30980
diff changeset
304 if ic[0] in copyto:
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30980
diff changeset
305 diverge[f] = [copyto[ic[0]], ic[1]]
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30980
diff changeset
306 else:
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30980
diff changeset
307 remainder[f] = ic
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30980
diff changeset
308 return remainder
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30980
diff changeset
309
30965
f7ed5af31242 mergecopies: rename 'ca' to 'base'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30964
diff changeset
310 def mergecopies(repo, c1, c2, base):
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
311 """
34861
b4b196092cc3 copytrace: move the default copytracing algorithm in a new function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34860
diff changeset
312 The function calling different copytracing algorithms on the basis of config
b4b196092cc3 copytrace: move the default copytracing algorithm in a new function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34860
diff changeset
313 which find moves and copies between context c1 and c2 that are relevant for
b4b196092cc3 copytrace: move the default copytracing algorithm in a new function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34860
diff changeset
314 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: 34860
diff changeset
315
b4b196092cc3 copytrace: move the default copytracing algorithm in a new function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34860
diff changeset
316 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: 34860
diff changeset
317 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: 34860
diff changeset
318 For example:
34605
42ad7cc645a4 copies: add more details to the documentation of mergecopies()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33423
diff changeset
319
42ad7cc645a4 copies: add more details to the documentation of mergecopies()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33423
diff changeset
320 o ---> 4 another commit
42ad7cc645a4 copies: add more details to the documentation of mergecopies()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33423
diff changeset
321 |
42ad7cc645a4 copies: add more details to the documentation of mergecopies()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33423
diff changeset
322 | o ---> 3 commit that modifies a.txt
42ad7cc645a4 copies: add more details to the documentation of mergecopies()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33423
diff changeset
323 | /
42ad7cc645a4 copies: add more details to the documentation of mergecopies()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33423
diff changeset
324 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: 33423
diff changeset
325 |/
42ad7cc645a4 copies: add more details to the documentation of mergecopies()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33423
diff changeset
326 o ---> 1 merge base
42ad7cc645a4 copies: add more details to the documentation of mergecopies()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33423
diff changeset
327
42ad7cc645a4 copies: add more details to the documentation of mergecopies()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33423
diff changeset
328 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: 33423
diff changeset
329 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: 33423
diff changeset
330 message:
42ad7cc645a4 copies: add more details to the documentation of mergecopies()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33423
diff changeset
331
42ad7cc645a4 copies: add more details to the documentation of mergecopies()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33423
diff changeset
332 ```other changed <file> which local deleted```
42ad7cc645a4 copies: add more details to the documentation of mergecopies()
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33423
diff changeset
333
31360
43a9e02a7b7f graft: support grafting changes to new file in renamed directory (issue5436)
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 31140
diff changeset
334 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: 31140
diff changeset
335 "dirmove".
16168
7bbabfe25321 copies: add docstring for mergecopies
Matt Mackall <mpm@selenic.com>
parents: 15994
diff changeset
336
16177
b8c1a8a57540 copies: fix mergecopies doc mapping direction
Matt Mackall <mpm@selenic.com>
parents: 16169
diff changeset
337 "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
338 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
339
18134
6c35b53cd28b copies: separate moves via directory renames from explicit copies
Siddharth Agarwal <sid0@fb.com>
parents: 17055
diff changeset
340 "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
341 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
342 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
343 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
344
16168
7bbabfe25321 copies: add docstring for mergecopies
Matt Mackall <mpm@selenic.com>
parents: 15994
diff changeset
345 "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
346 for divergent renames.
16781
98687cdddcb1 merge: warn about file deleted in one branch and renamed in other (issue3074)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 16779
diff changeset
347
98687cdddcb1 merge: warn about file deleted in one branch and renamed in other (issue3074)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 16779
diff changeset
348 "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: 16779
diff changeset
349 names for files deleted in c1 that were renamed in c2 or vice-versa.
31360
43a9e02a7b7f graft: support grafting changes to new file in renamed directory (issue5436)
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 31140
diff changeset
350
43a9e02a7b7f graft: support grafting changes to new file in renamed directory (issue5436)
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 31140
diff changeset
351 "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: 31140
diff changeset
352 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: 31140
diff changeset
353 renamed directories.
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
354 """
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
355 # 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
356 if not c1 or not c2 or c1 == c2:
31360
43a9e02a7b7f graft: support grafting changes to new file in renamed directory (issue5436)
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 31140
diff changeset
357 return {}, {}, {}, {}, {}
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
358
6658
9eb274d773d9 copies: teach copies about dirstate.copies
Matt Mackall <mpm@selenic.com>
parents: 6431
diff changeset
359 # avoid silly behavior for parent -> working dir
13878
a8d13ee0ce68 misc: replace .parents()[0] with p1()
Matt Mackall <mpm@selenic.com>
parents: 12683
diff changeset
360 if c2.node() is None and c1.node() == repo.dirstate.p1():
31360
43a9e02a7b7f graft: support grafting changes to new file in renamed directory (issue5436)
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 31140
diff changeset
361 return repo.dirstate.copies(), {}, {}, {}, {}
6658
9eb274d773d9 copies: teach copies about dirstate.copies
Matt Mackall <mpm@selenic.com>
parents: 6431
diff changeset
362
34861
b4b196092cc3 copytrace: move the default copytracing algorithm in a new function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34860
diff changeset
363 copytracing = repo.ui.config('experimental', 'copytrace')
b4b196092cc3 copytrace: move the default copytracing algorithm in a new function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34860
diff changeset
364
26597
38f92d12357c copy: add flag for disabling copy tracing
Durham Goode <durham@fb.com>
parents: 26508
diff changeset
365 # 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: 26508
diff changeset
366 # 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: 26508
diff changeset
367 # rebase.
34861
b4b196092cc3 copytrace: move the default copytracing algorithm in a new function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34860
diff changeset
368 if copytracing == 'off':
31360
43a9e02a7b7f graft: support grafting changes to new file in renamed directory (issue5436)
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 31140
diff changeset
369 return {}, {}, {}, {}, {}
34962
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34861
diff changeset
370 elif copytracing == 'heuristics':
35071
fc3b8483c6cb copytrace: use the full copytracing method if only drafts are involved
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34962
diff changeset
371 # Do full copytracing if only drafts are involved as that will be fast
fc3b8483c6cb copytrace: use the full copytracing method if only drafts are involved
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34962
diff changeset
372 # enough and will also cover the copies which can be missed by
fc3b8483c6cb copytrace: use the full copytracing method if only drafts are involved
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34962
diff changeset
373 # heuristics
fc3b8483c6cb copytrace: use the full copytracing method if only drafts are involved
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34962
diff changeset
374 if _isfullcopytraceable(c1, base):
fc3b8483c6cb copytrace: use the full copytracing method if only drafts are involved
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34962
diff changeset
375 return _fullcopytracing(repo, c1, c2, base)
34962
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34861
diff changeset
376 return _heuristicscopytracing(repo, c1, c2, base)
34861
b4b196092cc3 copytrace: move the default copytracing algorithm in a new function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34860
diff changeset
377 else:
b4b196092cc3 copytrace: move the default copytracing algorithm in a new function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34860
diff changeset
378 return _fullcopytracing(repo, c1, c2, base)
26597
38f92d12357c copy: add flag for disabling copy tracing
Durham Goode <durham@fb.com>
parents: 26508
diff changeset
379
35071
fc3b8483c6cb copytrace: use the full copytracing method if only drafts are involved
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34962
diff changeset
380 def _isfullcopytraceable(c1, base):
fc3b8483c6cb copytrace: use the full copytracing method if only drafts are involved
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34962
diff changeset
381 """ Checks that if base, source and destination are all draft branches, if
fc3b8483c6cb copytrace: use the full copytracing method if only drafts are involved
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34962
diff changeset
382 yes let's use the full copytrace algorithm for increased capabilities since
fc3b8483c6cb copytrace: use the full copytracing method if only drafts are involved
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34962
diff changeset
383 it will be fast enough.
fc3b8483c6cb copytrace: use the full copytracing method if only drafts are involved
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34962
diff changeset
384 """
fc3b8483c6cb copytrace: use the full copytracing method if only drafts are involved
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34962
diff changeset
385
fc3b8483c6cb copytrace: use the full copytracing method if only drafts are involved
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34962
diff changeset
386 nonpublicphases = set([phases.draft, phases.secret])
fc3b8483c6cb copytrace: use the full copytracing method if only drafts are involved
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34962
diff changeset
387
fc3b8483c6cb copytrace: use the full copytracing method if only drafts are involved
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34962
diff changeset
388 if (c1.phase() in nonpublicphases) and (base.phase() in nonpublicphases):
fc3b8483c6cb copytrace: use the full copytracing method if only drafts are involved
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34962
diff changeset
389 return True
fc3b8483c6cb copytrace: use the full copytracing method if only drafts are involved
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34962
diff changeset
390 return False
fc3b8483c6cb copytrace: use the full copytracing method if only drafts are involved
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34962
diff changeset
391
34861
b4b196092cc3 copytrace: move the default copytracing algorithm in a new function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34860
diff changeset
392 def _fullcopytracing(repo, c1, c2, base):
b4b196092cc3 copytrace: move the default copytracing algorithm in a new function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34860
diff changeset
393 """ 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: 34860
diff changeset
394 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: 34860
diff changeset
395 this file was copied from another file.
b4b196092cc3 copytrace: move the default copytracing algorithm in a new function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34860
diff changeset
396
b4b196092cc3 copytrace: move the default copytracing algorithm in a new function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34860
diff changeset
397 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: 34860
diff changeset
398 the copies.
b4b196092cc3 copytrace: move the default copytracing algorithm in a new function
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34860
diff changeset
399 """
30972
368e27eb1ffa copies: detect graft-like merges
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30967
diff changeset
400 # In certain scenarios (e.g. graft, update or rebase), base can be
368e27eb1ffa copies: detect graft-like merges
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30967
diff changeset
401 # overridden We still need to know a real common ancestor in this case We
368e27eb1ffa copies: detect graft-like merges
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30967
diff changeset
402 # can't just compute _c1.ancestor(_c2) and compare it to ca, because there
368e27eb1ffa copies: detect graft-like merges
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30967
diff changeset
403 # can be multiple common ancestors, e.g. in case of bidmerge. Because our
368e27eb1ffa copies: detect graft-like merges
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30967
diff changeset
404 # caller may not know if the revision passed in lieu of the CA is a genuine
368e27eb1ffa copies: detect graft-like merges
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30967
diff changeset
405 # common ancestor or not without explicitly checking it, it's better to
368e27eb1ffa copies: detect graft-like merges
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30967
diff changeset
406 # determine that here.
368e27eb1ffa copies: detect graft-like merges
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30967
diff changeset
407 #
368e27eb1ffa copies: detect graft-like merges
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30967
diff changeset
408 # base.descendant(wc) and base.descendant(base) are False, work around that
368e27eb1ffa copies: detect graft-like merges
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30967
diff changeset
409 _c1 = c1.p1() if c1.rev() is None else c1
368e27eb1ffa copies: detect graft-like merges
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30967
diff changeset
410 _c2 = c2.p1() if c2.rev() is None else c2
368e27eb1ffa copies: detect graft-like merges
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30967
diff changeset
411 # an endpoint is "dirty" if it isn't a descendant of the merge base
368e27eb1ffa copies: detect graft-like merges
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30967
diff changeset
412 # if we have a dirty endpoint, we need to trigger graft logic, and also
368e27eb1ffa copies: detect graft-like merges
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30967
diff changeset
413 # keep track of which endpoint is dirty
368e27eb1ffa copies: detect graft-like merges
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30967
diff changeset
414 dirtyc1 = not (base == _c1 or base.descendant(_c1))
34663
edf503e5dfd4 copies: fix misaligned lines
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 34662
diff changeset
415 dirtyc2 = not (base == _c2 or base.descendant(_c2))
30972
368e27eb1ffa copies: detect graft-like merges
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30967
diff changeset
416 graft = dirtyc1 or dirtyc2
30973
8c69c52ced98 copies: compute a suitable TCA if base turns out to be unsuitable
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30972
diff changeset
417 tca = base
8c69c52ced98 copies: compute a suitable TCA if base turns out to be unsuitable
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30972
diff changeset
418 if graft:
8c69c52ced98 copies: compute a suitable TCA if base turns out to be unsuitable
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30972
diff changeset
419 tca = _c1.ancestor(_c2)
8c69c52ced98 copies: compute a suitable TCA if base turns out to be unsuitable
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30972
diff changeset
420
6431
a42d8d3e6ea9 copies: refactor symmetricdifference as _findlimit
Matt Mackall <mpm@selenic.com>
parents: 6430
diff changeset
421 limit = _findlimit(repo, c1.rev(), c2.rev())
10174
83cfa1baf8ad copies: don't report copies with unrelated branch
Patrick Mezard <pmezard@gmail.com>
parents: 9466
diff changeset
422 if limit is None:
83cfa1baf8ad copies: don't report copies with unrelated branch
Patrick Mezard <pmezard@gmail.com>
parents: 9466
diff changeset
423 # no common ancestor, no copies
31360
43a9e02a7b7f graft: support grafting changes to new file in renamed directory (issue5436)
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 31140
diff changeset
424 return {}, {}, {}, {}, {}
26937
4b9bb1616195 copies: move debug statement to appropriate place
Matt Mackall <mpm@selenic.com>
parents: 26935
diff changeset
425 repo.ui.debug(" searching for copies back to rev %d\n" % limit)
4b9bb1616195 copies: move debug statement to appropriate place
Matt Mackall <mpm@selenic.com>
parents: 26935
diff changeset
426
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
427 m1 = c1.manifest()
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
428 m2 = c2.manifest()
30965
f7ed5af31242 mergecopies: rename 'ca' to 'base'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30964
diff changeset
429 mb = base.manifest()
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
430
30964
e2bfe2d52d7a copies: move variable document from checkcopies to mergecopies
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30963
diff changeset
431 # gather data from _checkcopies:
e2bfe2d52d7a copies: move variable document from checkcopies to mergecopies
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30963
diff changeset
432 # - diverge = record all diverges in this dict
e2bfe2d52d7a copies: move variable document from checkcopies to mergecopies
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30963
diff changeset
433 # - copy = record all non-divergent copies in this dict
e2bfe2d52d7a copies: move variable document from checkcopies to mergecopies
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30963
diff changeset
434 # - fullcopy = record all copies in this dict
30981
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30980
diff changeset
435 # - incomplete = record non-divergent partial copies here
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30980
diff changeset
436 # - incompletediverge = record divergent partial copies here
30963
7321c6b0c9fd checkcopies: pass data as a dictionary of dictionaries
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30962
diff changeset
437 diverge = {} # divergence data is shared
30981
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30980
diff changeset
438 incompletediverge = {}
30963
7321c6b0c9fd checkcopies: pass data as a dictionary of dictionaries
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30962
diff changeset
439 data1 = {'copy': {},
7321c6b0c9fd checkcopies: pass data as a dictionary of dictionaries
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30962
diff changeset
440 'fullcopy': {},
30981
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30980
diff changeset
441 'incomplete': {},
30963
7321c6b0c9fd checkcopies: pass data as a dictionary of dictionaries
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30962
diff changeset
442 'diverge': diverge,
30981
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30980
diff changeset
443 'incompletediverge': incompletediverge,
30963
7321c6b0c9fd checkcopies: pass data as a dictionary of dictionaries
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30962
diff changeset
444 }
7321c6b0c9fd checkcopies: pass data as a dictionary of dictionaries
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30962
diff changeset
445 data2 = {'copy': {},
7321c6b0c9fd checkcopies: pass data as a dictionary of dictionaries
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30962
diff changeset
446 'fullcopy': {},
30981
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30980
diff changeset
447 'incomplete': {},
30963
7321c6b0c9fd checkcopies: pass data as a dictionary of dictionaries
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30962
diff changeset
448 'diverge': diverge,
30981
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30980
diff changeset
449 'incompletediverge': incompletediverge,
30963
7321c6b0c9fd checkcopies: pass data as a dictionary of dictionaries
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30962
diff changeset
450 }
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
451
27299
df66736a128e copies: group bothnew with other sets
Matt Mackall <mpm@selenic.com>
parents: 27298
diff changeset
452 # find interesting file sets from manifests
30965
f7ed5af31242 mergecopies: rename 'ca' to 'base'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30964
diff changeset
453 addedinm1 = m1.filesnotin(mb)
f7ed5af31242 mergecopies: rename 'ca' to 'base'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30964
diff changeset
454 addedinm2 = m2.filesnotin(mb)
27299
df66736a128e copies: group bothnew with other sets
Matt Mackall <mpm@selenic.com>
parents: 27298
diff changeset
455 bothnew = sorted(addedinm1 & addedinm2)
30976
0accd5a5ad04 mergecopies: invoke _computenonoverlap for both base and tca during merges
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30975
diff changeset
456 if tca == base:
0accd5a5ad04 mergecopies: invoke _computenonoverlap for both base and tca during merges
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30975
diff changeset
457 # unmatched file from base
0accd5a5ad04 mergecopies: invoke _computenonoverlap for both base and tca during merges
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30975
diff changeset
458 u1r, u2r = _computenonoverlap(repo, c1, c2, addedinm1, addedinm2)
0accd5a5ad04 mergecopies: invoke _computenonoverlap for both base and tca during merges
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30975
diff changeset
459 u1u, u2u = u1r, u2r
0accd5a5ad04 mergecopies: invoke _computenonoverlap for both base and tca during merges
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30975
diff changeset
460 else:
0accd5a5ad04 mergecopies: invoke _computenonoverlap for both base and tca during merges
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30975
diff changeset
461 # unmatched file from base (DAG rotation in the graft case)
0accd5a5ad04 mergecopies: invoke _computenonoverlap for both base and tca during merges
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30975
diff changeset
462 u1r, u2r = _computenonoverlap(repo, c1, c2, addedinm1, addedinm2,
0accd5a5ad04 mergecopies: invoke _computenonoverlap for both base and tca during merges
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30975
diff changeset
463 baselabel='base')
0accd5a5ad04 mergecopies: invoke _computenonoverlap for both base and tca during merges
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30975
diff changeset
464 # unmatched file from topological common ancestors (no DAG rotation)
0accd5a5ad04 mergecopies: invoke _computenonoverlap for both base and tca during merges
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30975
diff changeset
465 # need to recompute this for directory move handling when grafting
0accd5a5ad04 mergecopies: invoke _computenonoverlap for both base and tca during merges
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30975
diff changeset
466 mta = tca.manifest()
0accd5a5ad04 mergecopies: invoke _computenonoverlap for both base and tca during merges
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30975
diff changeset
467 u1u, u2u = _computenonoverlap(repo, c1, c2, m1.filesnotin(mta),
0accd5a5ad04 mergecopies: invoke _computenonoverlap for both base and tca during merges
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30975
diff changeset
468 m2.filesnotin(mta),
0accd5a5ad04 mergecopies: invoke _computenonoverlap for both base and tca during merges
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30975
diff changeset
469 baselabel='topological common ancestor')
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
470
30826
d13a7c8bf0a5 copies: split u1/u2 to u1u/u2u and u1r/u2r
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30825
diff changeset
471 for f in u1u:
33346
e1e1cc97e05a copies: remove msrc and mdst parameters
Stanislau Hlebik <stash@fb.com>
parents: 33345
diff changeset
472 _checkcopies(c1, c2, f, base, tca, dirtyc1, limit, data1)
20989
e8533ec2d222 copies: remove _checkcopies wrapper - it does no good
Mads Kiilerich <madski@unity3d.com>
parents: 20641
diff changeset
473
30826
d13a7c8bf0a5 copies: split u1/u2 to u1u/u2u and u1r/u2r
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30825
diff changeset
474 for f in u2u:
33346
e1e1cc97e05a copies: remove msrc and mdst parameters
Stanislau Hlebik <stash@fb.com>
parents: 33345
diff changeset
475 _checkcopies(c2, c1, f, base, tca, dirtyc2, limit, data2)
26934
d5618e210191 copies: begin separating mergecopies sides
Matt Mackall <mpm@selenic.com>
parents: 26933
diff changeset
476
33423
aeac3cbcbbc1 py3: use dict.update() instead of constructing lists and adding them
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33348
diff changeset
477 copy = dict(data1['copy'])
aeac3cbcbbc1 py3: use dict.update() instead of constructing lists and adding them
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33348
diff changeset
478 copy.update(data2['copy'])
aeac3cbcbbc1 py3: use dict.update() instead of constructing lists and adding them
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33348
diff changeset
479 fullcopy = dict(data1['fullcopy'])
aeac3cbcbbc1 py3: use dict.update() instead of constructing lists and adding them
Pulkit Goyal <7895pulkit@gmail.com>
parents: 33348
diff changeset
480 fullcopy.update(data2['fullcopy'])
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
481
30981
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30980
diff changeset
482 if dirtyc1:
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30980
diff changeset
483 _combinecopies(data2['incomplete'], data1['incomplete'], copy, diverge,
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30980
diff changeset
484 incompletediverge)
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30980
diff changeset
485 else:
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30980
diff changeset
486 _combinecopies(data1['incomplete'], data2['incomplete'], copy, diverge,
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30980
diff changeset
487 incompletediverge)
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30980
diff changeset
488
16781
98687cdddcb1 merge: warn about file deleted in one branch and renamed in other (issue3074)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 16779
diff changeset
489 renamedelete = {}
27298
aabfa0fb7e3e copies: rename renamedelete to renamedeleteset for clarity
Matt Mackall <mpm@selenic.com>
parents: 27297
diff changeset
490 renamedeleteset = set()
26935
07ac78ba2e37 copies: rename diverge2 to divergeset for clarity
Matt Mackall <mpm@selenic.com>
parents: 26934
diff changeset
491 divergeset = set()
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
492 for of, fl in diverge.items():
16779
ad394c897b16 merge: do not warn about copy and rename in the same transaction (issue2113)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 16178
diff changeset
493 if len(fl) == 1 or of in c1 or of in c2:
12683
ada47c38f4e5 copies: don't detect copies as "divergent renames"
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 10873
diff changeset
494 del diverge[of] # not actually divergent, or not a rename
16781
98687cdddcb1 merge: warn about file deleted in one branch and renamed in other (issue3074)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 16779
diff changeset
495 if of not in c1 and of not in c2:
98687cdddcb1 merge: warn about file deleted in one branch and renamed in other (issue3074)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 16779
diff changeset
496 # renamed on one side, deleted on the other side, but filter
98687cdddcb1 merge: warn about file deleted in one branch and renamed in other (issue3074)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 16779
diff changeset
497 # out files that have been renamed and then deleted
98687cdddcb1 merge: warn about file deleted in one branch and renamed in other (issue3074)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 16779
diff changeset
498 renamedelete[of] = [f for f in fl if f in c1 or f in c2]
27298
aabfa0fb7e3e copies: rename renamedelete to renamedeleteset for clarity
Matt Mackall <mpm@selenic.com>
parents: 27297
diff changeset
499 renamedeleteset.update(fl) # reverse map for below
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
500 else:
26935
07ac78ba2e37 copies: rename diverge2 to divergeset for clarity
Matt Mackall <mpm@selenic.com>
parents: 26934
diff changeset
501 divergeset.update(fl) # reverse map for below
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
502
20641
3db9e798e004 copies: when both sides made the same copy, report it as a copy
Mads Kiilerich <madski@unity3d.com>
parents: 20294
diff changeset
503 if bothnew:
3db9e798e004 copies: when both sides made the same copy, report it as a copy
Mads Kiilerich <madski@unity3d.com>
parents: 20294
diff changeset
504 repo.ui.debug(" unmatched files new in both:\n %s\n"
3db9e798e004 copies: when both sides made the same copy, report it as a copy
Mads Kiilerich <madski@unity3d.com>
parents: 20294
diff changeset
505 % "\n ".join(bothnew))
30963
7321c6b0c9fd checkcopies: pass data as a dictionary of dictionaries
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30962
diff changeset
506 bothdiverge = {}
30981
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30980
diff changeset
507 bothincompletediverge = {}
30987
87a7c0d403ff copies: improve assertions during copy recombination
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30983
diff changeset
508 remainder = {}
30981
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30980
diff changeset
509 both1 = {'copy': {},
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30980
diff changeset
510 'fullcopy': {},
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30980
diff changeset
511 'incomplete': {},
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30980
diff changeset
512 'diverge': bothdiverge,
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30980
diff changeset
513 'incompletediverge': bothincompletediverge
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30980
diff changeset
514 }
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30980
diff changeset
515 both2 = {'copy': {},
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30980
diff changeset
516 'fullcopy': {},
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30980
diff changeset
517 'incomplete': {},
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30980
diff changeset
518 'diverge': bothdiverge,
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30980
diff changeset
519 'incompletediverge': bothincompletediverge
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30980
diff changeset
520 }
20641
3db9e798e004 copies: when both sides made the same copy, report it as a copy
Mads Kiilerich <madski@unity3d.com>
parents: 20294
diff changeset
521 for f in bothnew:
33346
e1e1cc97e05a copies: remove msrc and mdst parameters
Stanislau Hlebik <stash@fb.com>
parents: 33345
diff changeset
522 _checkcopies(c1, c2, f, base, tca, dirtyc1, limit, both1)
e1e1cc97e05a copies: remove msrc and mdst parameters
Stanislau Hlebik <stash@fb.com>
parents: 33345
diff changeset
523 _checkcopies(c2, c1, f, base, tca, dirtyc2, limit, both2)
30981
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30980
diff changeset
524 if dirtyc1:
30987
87a7c0d403ff copies: improve assertions during copy recombination
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30983
diff changeset
525 # incomplete copies may only be found on the "dirty" side for bothnew
87a7c0d403ff copies: improve assertions during copy recombination
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30983
diff changeset
526 assert not both2['incomplete']
30981
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30980
diff changeset
527 remainder = _combinecopies({}, both1['incomplete'], copy, bothdiverge,
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30980
diff changeset
528 bothincompletediverge)
30987
87a7c0d403ff copies: improve assertions during copy recombination
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30983
diff changeset
529 elif dirtyc2:
87a7c0d403ff copies: improve assertions during copy recombination
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30983
diff changeset
530 assert not both1['incomplete']
87a7c0d403ff copies: improve assertions during copy recombination
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30983
diff changeset
531 remainder = _combinecopies({}, both2['incomplete'], copy, bothdiverge,
87a7c0d403ff copies: improve assertions during copy recombination
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30983
diff changeset
532 bothincompletediverge)
30981
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30980
diff changeset
533 else:
30987
87a7c0d403ff copies: improve assertions during copy recombination
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30983
diff changeset
534 # incomplete copies and divergences can't happen outside grafts
87a7c0d403ff copies: improve assertions during copy recombination
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30983
diff changeset
535 assert not both1['incomplete']
87a7c0d403ff copies: improve assertions during copy recombination
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30983
diff changeset
536 assert not both2['incomplete']
87a7c0d403ff copies: improve assertions during copy recombination
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30983
diff changeset
537 assert not bothincompletediverge
30981
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30980
diff changeset
538 for f in remainder:
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30980
diff changeset
539 assert f not in bothdiverge
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30980
diff changeset
540 ic = remainder[f]
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30980
diff changeset
541 if ic[0] in (m1 if dirtyc1 else m2):
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30980
diff changeset
542 # backed-out rename on one side, but watch out for deleted files
a005c33d0bd7 mergecopies: add logic to process incomplete data
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30980
diff changeset
543 bothdiverge[f] = ic
20641
3db9e798e004 copies: when both sides made the same copy, report it as a copy
Mads Kiilerich <madski@unity3d.com>
parents: 20294
diff changeset
544 for of, fl in bothdiverge.items():
3db9e798e004 copies: when both sides made the same copy, report it as a copy
Mads Kiilerich <madski@unity3d.com>
parents: 20294
diff changeset
545 if len(fl) == 2 and fl[0] == fl[1]:
3db9e798e004 copies: when both sides made the same copy, report it as a copy
Mads Kiilerich <madski@unity3d.com>
parents: 20294
diff changeset
546 copy[fl[0]] = of # not actually divergent, just matching renames
3db9e798e004 copies: when both sides made the same copy, report it as a copy
Mads Kiilerich <madski@unity3d.com>
parents: 20294
diff changeset
547
20990
d9e211a658eb copies: guard debug section with ui.debugflag
Mads Kiilerich <madski@unity3d.com>
parents: 20989
diff changeset
548 if fullcopy and repo.ui.debugflag:
16782
e9ae770eff1c merge: show renamed on one and deleted on the other side in debug output
Thomas Arendsen Hein <thomas@intevation.de>
parents: 16781
diff changeset
549 repo.ui.debug(" all copies found (* = to merge, ! = divergent, "
e9ae770eff1c merge: show renamed on one and deleted on the other side in debug output
Thomas Arendsen Hein <thomas@intevation.de>
parents: 16781
diff changeset
550 "% = renamed and deleted):\n")
18362
5a4f220fbfca copies: report found copies sorted
Mads Kiilerich <mads@kiilerich.com>
parents: 18355
diff changeset
551 for f in sorted(fullcopy):
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
552 note = ""
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
553 if f in copy:
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
554 note += "*"
26935
07ac78ba2e37 copies: rename diverge2 to divergeset for clarity
Matt Mackall <mpm@selenic.com>
parents: 26934
diff changeset
555 if f in divergeset:
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
556 note += "!"
27298
aabfa0fb7e3e copies: rename renamedelete to renamedeleteset for clarity
Matt Mackall <mpm@selenic.com>
parents: 27297
diff changeset
557 if f in renamedeleteset:
16782
e9ae770eff1c merge: show renamed on one and deleted on the other side in debug output
Thomas Arendsen Hein <thomas@intevation.de>
parents: 16781
diff changeset
558 note += "%"
18135
a6fe1b9cc68f copies: make debug messages more sensible
Siddharth Agarwal <sid0@fb.com>
parents: 18134
diff changeset
559 repo.ui.debug(" src: '%s' -> dst: '%s' %s\n" % (fullcopy[f], f,
a6fe1b9cc68f copies: make debug messages more sensible
Siddharth Agarwal <sid0@fb.com>
parents: 18134
diff changeset
560 note))
26935
07ac78ba2e37 copies: rename diverge2 to divergeset for clarity
Matt Mackall <mpm@selenic.com>
parents: 26934
diff changeset
561 del divergeset
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
562
16169
c12d4aceba79 copies: remove checkdirs options
Matt Mackall <mpm@selenic.com>
parents: 16168
diff changeset
563 if not fullcopy:
31360
43a9e02a7b7f graft: support grafting changes to new file in renamed directory (issue5436)
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 31140
diff changeset
564 return copy, {}, diverge, renamedelete, {}
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
565
9466
4c041f1ee1b4 do not attempt to translate ui.debug output
Martin Geisler <mg@lazybytes.net>
parents: 9102
diff changeset
566 repo.ui.debug(" checking for directory renames\n")
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
567
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
568 # generate a directory move map
16178
828fe2ca7cbb copies: use ctx.dirs() for directory rename detection
Matt Mackall <mpm@selenic.com>
parents: 16177
diff changeset
569 d1, d2 = c1.dirs(), c2.dirs()
25723
947771ad5174 copies: document hack for adding '' to set of dirs
Martin von Zweigbergk <martinvonz@google.com>
parents: 25717
diff changeset
570 # Hack for adding '', which is not otherwise added, to d1 and d2
18899
d8ff607ef721 scmutil: use new dirs class in dirstate and context
Bryan O'Sullivan <bryano@fb.com>
parents: 18874
diff changeset
571 d1.addpath('/')
d8ff607ef721 scmutil: use new dirs class in dirstate and context
Bryan O'Sullivan <bryano@fb.com>
parents: 18874
diff changeset
572 d2.addpath('/')
17055
8b7cd9a998f0 copies: re-include root directory in directory rename detection (issue3511)
Matt Mackall <mpm@selenic.com>
parents: 16782
diff changeset
573 invalid = set()
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
574 dirmove = {}
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
575
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
576 # 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
577 # when all the files in a directory are moved to a new directory
7622
4dd7b28003d2 use dict.iteritems() rather than dict.items()
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6764
diff changeset
578 for dst, src in fullcopy.iteritems():
25717
0f28815ef066 copies: switch to using pathutil.dirname
Durham Goode <durham@fb.com>
parents: 24961
diff changeset
579 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
580 if dsrc in invalid:
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
581 # already seen to be uninteresting
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
582 continue
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
583 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
584 # directory wasn't entirely moved locally
28531
602add6ad9e5 copies: fix detection of divergent directory renames
Matt Mackall <mpm@selenic.com>
parents: 27421
diff changeset
585 invalid.add(dsrc + "/")
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
586 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
587 # directory wasn't entirely moved remotely
28531
602add6ad9e5 copies: fix detection of divergent directory renames
Matt Mackall <mpm@selenic.com>
parents: 27421
diff changeset
588 invalid.add(dsrc + "/")
602add6ad9e5 copies: fix detection of divergent directory renames
Matt Mackall <mpm@selenic.com>
parents: 27421
diff changeset
589 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
590 # files from the same directory moved to two different places
28531
602add6ad9e5 copies: fix detection of divergent directory renames
Matt Mackall <mpm@selenic.com>
parents: 27421
diff changeset
591 invalid.add(dsrc + "/")
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
592 else:
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
593 # looks good so far
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
594 dirmove[dsrc + "/"] = ddst + "/"
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
595
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
596 for i in invalid:
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
597 if i in dirmove:
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
598 del dirmove[i]
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
599 del d1, d2, invalid
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
600
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
601 if not dirmove:
31360
43a9e02a7b7f graft: support grafting changes to new file in renamed directory (issue5436)
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 31140
diff changeset
602 return copy, {}, diverge, renamedelete, {}
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
603
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
604 for d in dirmove:
18135
a6fe1b9cc68f copies: make debug messages more sensible
Siddharth Agarwal <sid0@fb.com>
parents: 18134
diff changeset
605 repo.ui.debug(" discovered dir src: '%s' -> dst: '%s'\n" %
a6fe1b9cc68f copies: make debug messages more sensible
Siddharth Agarwal <sid0@fb.com>
parents: 18134
diff changeset
606 (d, dirmove[d]))
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
607
30962
0106f93ca1d5 checkcopies: move 'movewithdir' initialisation right before its usage
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30917
diff changeset
608 movewithdir = {}
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
609 # check unaccounted nonoverlapping files against directory moves
30826
d13a7c8bf0a5 copies: split u1/u2 to u1u/u2u and u1r/u2r
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30825
diff changeset
610 for f in u1r + u2r:
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
611 if f not in fullcopy:
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
612 for d in dirmove:
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
613 if f.startswith(d):
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
614 # new file added in a directory that was moved, move it
6425
2d9328a2f81f copies: skip directory rename checks when not merging
Matt Mackall <mpm@selenic.com>
parents: 6424
diff changeset
615 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
616 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
617 movewithdir[f] = df
18135
a6fe1b9cc68f copies: make debug messages more sensible
Siddharth Agarwal <sid0@fb.com>
parents: 18134
diff changeset
618 repo.ui.debug((" pending file src: '%s' -> "
a6fe1b9cc68f copies: make debug messages more sensible
Siddharth Agarwal <sid0@fb.com>
parents: 18134
diff changeset
619 "dst: '%s'\n") % (f, df))
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
620 break
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
621
31360
43a9e02a7b7f graft: support grafting changes to new file in renamed directory (issue5436)
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 31140
diff changeset
622 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
623
34962
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34861
diff changeset
624 def _heuristicscopytracing(repo, c1, c2, base):
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34861
diff changeset
625 """ Fast copytracing using filename heuristics
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34861
diff changeset
626
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34861
diff changeset
627 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: 34861
diff changeset
628
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34861
diff changeset
629 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: 34861
diff changeset
630 2) Move from one directory to another
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34861
diff changeset
631 (same filenames but different directory names)
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34861
diff changeset
632
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34861
diff changeset
633 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: 34861
diff changeset
634 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: 34861
diff changeset
635
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34861
diff changeset
636 If merge is involved it fallbacks to _fullcopytracing().
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34861
diff changeset
637
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34861
diff changeset
638 Can be used by setting the following config:
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34861
diff changeset
639
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34861
diff changeset
640 [experimental]
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34861
diff changeset
641 copytrace = heuristics
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34861
diff changeset
642 """
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34861
diff changeset
643
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34861
diff changeset
644 if c1.rev() is None:
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34861
diff changeset
645 c1 = c1.p1()
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34861
diff changeset
646 if c2.rev() is None:
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34861
diff changeset
647 c2 = c2.p1()
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34861
diff changeset
648
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34861
diff changeset
649 copies = {}
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34861
diff changeset
650
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34861
diff changeset
651 changedfiles = set()
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34861
diff changeset
652 m1 = c1.manifest()
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34861
diff changeset
653 if not repo.revs('%d::%d', base.rev(), c2.rev()):
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34861
diff changeset
654 # If base is not in c2 branch, we switch to fullcopytracing
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34861
diff changeset
655 repo.ui.debug("switching to full copytracing as base is not "
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34861
diff changeset
656 "an ancestor of c2\n")
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34861
diff changeset
657 return _fullcopytracing(repo, c1, c2, base)
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34861
diff changeset
658
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34861
diff changeset
659 ctx = c2
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34861
diff changeset
660 while ctx != base:
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34861
diff changeset
661 if len(ctx.parents()) == 2:
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34861
diff changeset
662 # To keep things simple let's not handle merges
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34861
diff changeset
663 repo.ui.debug("switching to full copytracing because of merges\n")
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34861
diff changeset
664 return _fullcopytracing(repo, c1, c2, base)
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34861
diff changeset
665 changedfiles.update(ctx.files())
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34861
diff changeset
666 ctx = ctx.p1()
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34861
diff changeset
667
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34861
diff changeset
668 cp = _forwardcopies(base, c2)
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34861
diff changeset
669 for dst, src in cp.iteritems():
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34861
diff changeset
670 if src in m1:
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34861
diff changeset
671 copies[dst] = src
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34861
diff changeset
672
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34861
diff changeset
673 # 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: 34861
diff changeset
674 # the base and present in the source.
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34861
diff changeset
675 # 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: 34861
diff changeset
676 # source is important to exclude removed files.
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34861
diff changeset
677 missingfiles = filter(lambda f: f not in m1 and f in base and f in c2,
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34861
diff changeset
678 changedfiles)
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34861
diff changeset
679
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34861
diff changeset
680 if missingfiles:
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34861
diff changeset
681 basenametofilename = collections.defaultdict(list)
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34861
diff changeset
682 dirnametofilename = collections.defaultdict(list)
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34861
diff changeset
683
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34861
diff changeset
684 for f in m1.filesnotin(base.manifest()):
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34861
diff changeset
685 basename = os.path.basename(f)
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34861
diff changeset
686 dirname = os.path.dirname(f)
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34861
diff changeset
687 basenametofilename[basename].append(f)
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34861
diff changeset
688 dirnametofilename[dirname].append(f)
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34861
diff changeset
689
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34861
diff changeset
690 # in case of a rebase/graft, base may not be a common ancestor
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34861
diff changeset
691 anc = c1.ancestor(c2)
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34861
diff changeset
692
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34861
diff changeset
693 for f in missingfiles:
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34861
diff changeset
694 basename = os.path.basename(f)
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34861
diff changeset
695 dirname = os.path.dirname(f)
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34861
diff changeset
696 samebasename = basenametofilename[basename]
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34861
diff changeset
697 samedirname = dirnametofilename[dirname]
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34861
diff changeset
698 movecandidates = samebasename + samedirname
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34861
diff changeset
699 # 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: 34861
diff changeset
700 # c2.filectx(f) won't fail
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34861
diff changeset
701 f2 = c2.filectx(f)
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34861
diff changeset
702 for candidate in movecandidates:
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34861
diff changeset
703 f1 = c1.filectx(candidate)
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34861
diff changeset
704 if _related(f1, f2, anc.rev()):
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34861
diff changeset
705 # 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: 34861
diff changeset
706 # changes into all of them. This matches the behaviour
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34861
diff changeset
707 # of upstream copytracing
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34861
diff changeset
708 copies[candidate] = f
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34861
diff changeset
709
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34861
diff changeset
710 return copies, {}, {}, {}, {}
036d47d7cf39 copytrace: move fast heuristic copytracing algorithm to core
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34861
diff changeset
711
30917
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30916
diff changeset
712 def _related(f1, f2, limit):
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30916
diff changeset
713 """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: 30916
diff changeset
714
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30916
diff changeset
715 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: 30916
diff changeset
716 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: 30916
diff changeset
717 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: 30916
diff changeset
718 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: 30916
diff changeset
719 """
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30916
diff changeset
720
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30916
diff changeset
721 if f1 == f2:
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30916
diff changeset
722 return f1 # a match
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30916
diff changeset
723
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30916
diff changeset
724 g1, g2 = f1.ancestors(), f2.ancestors()
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30916
diff changeset
725 try:
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30916
diff changeset
726 f1r, f2r = f1.linkrev(), f2.linkrev()
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30916
diff changeset
727
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30916
diff changeset
728 if f1r is None:
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30916
diff changeset
729 f1 = next(g1)
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30916
diff changeset
730 if f2r is None:
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30916
diff changeset
731 f2 = next(g2)
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30916
diff changeset
732
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30916
diff changeset
733 while True:
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30916
diff changeset
734 f1r, f2r = f1.linkrev(), f2.linkrev()
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30916
diff changeset
735 if f1r > f2r:
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30916
diff changeset
736 f1 = next(g1)
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30916
diff changeset
737 elif f2r > f1r:
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30916
diff changeset
738 f2 = next(g2)
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30916
diff changeset
739 elif f1 == f2:
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30916
diff changeset
740 return f1 # a match
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30916
diff changeset
741 elif f1r == f2r or f1r < limit or f2r < limit:
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30916
diff changeset
742 return False # copy no longer relevant
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30916
diff changeset
743 except StopIteration:
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30916
diff changeset
744 return False
733fb9f7bc92 checkcopies: extract the '_related' closure
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30916
diff changeset
745
33346
e1e1cc97e05a copies: remove msrc and mdst parameters
Stanislau Hlebik <stash@fb.com>
parents: 33345
diff changeset
746 def _checkcopies(srcctx, dstctx, f, base, tca, remotebase, limit, data):
19178
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
747 """
33343
931b7707179f copies: rename m2 to mdst
Stanislau Hlebik <stash@fb.com>
parents: 33342
diff changeset
748 check possible copies of f from msrc to mdst
19178
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
749
33344
52cdbdd208d8 copies: rename ctx to srcctx
Stanislau Hlebik <stash@fb.com>
parents: 33343
diff changeset
750 srcctx = starting context for f in msrc
33345
e4d1bc14e39a copies: add dstctx parameter
Stanislau Hlebik <stash@fb.com>
parents: 33344
diff changeset
751 dstctx = destination context for f in mdst
33342
c8c9feffbd35 copies: rename m1 to msrc
Stanislau Hlebik <stash@fb.com>
parents: 33074
diff changeset
752 f = the filename to check (as in msrc)
30914
3eae81c0a09d checkcopies: rename 'ca' to 'base'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30854
diff changeset
753 base = the changectx used as a merge base
30974
88626de195f8 copies: make _checkcopies handle simple renames in a rotated DAG
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30973
diff changeset
754 tca = topological common ancestor for graft-like scenarios
33344
52cdbdd208d8 copies: rename ctx to srcctx
Stanislau Hlebik <stash@fb.com>
parents: 33343
diff changeset
755 remotebase = True if base is outside tca::srcctx, False otherwise
19178
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
756 limit = the rev number to not search beyond
30964
e2bfe2d52d7a copies: move variable document from checkcopies to mergecopies
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30963
diff changeset
757 data = dictionary of dictionary to store copy data. (see mergecopies)
30824
12cac1e4d6d9 copies: limit is an optimization, and doesn't provide guarantees
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 29966
diff changeset
758
34662
169baf3d1d3c copies: fix typo in comment
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 34650
diff changeset
759 note: limit is only an optimization, and provides no guarantee that
169baf3d1d3c copies: fix typo in comment
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 34650
diff changeset
760 irrelevant revisions will not be visited
30824
12cac1e4d6d9 copies: limit is an optimization, and doesn't provide guarantees
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 29966
diff changeset
761 there is no easy way to make this algorithm stop in a guaranteed way
12cac1e4d6d9 copies: limit is an optimization, and doesn't provide guarantees
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 29966
diff changeset
762 once it "goes behind a certain revision".
19178
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
763 """
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
764
33346
e1e1cc97e05a copies: remove msrc and mdst parameters
Stanislau Hlebik <stash@fb.com>
parents: 33345
diff changeset
765 msrc = srcctx.manifest()
e1e1cc97e05a copies: remove msrc and mdst parameters
Stanislau Hlebik <stash@fb.com>
parents: 33345
diff changeset
766 mdst = dstctx.manifest()
30914
3eae81c0a09d checkcopies: rename 'ca' to 'base'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30854
diff changeset
767 mb = base.manifest()
30983
1894c830ee74 copies: make _checkcopies handle copy sequences spanning the TCA (issue4028)
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30982
diff changeset
768 mta = tca.manifest()
30974
88626de195f8 copies: make _checkcopies handle simple renames in a rotated DAG
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30973
diff changeset
769 # Might be true if this call is about finding backward renames,
88626de195f8 copies: make _checkcopies handle simple renames in a rotated DAG
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30973
diff changeset
770 # This happens in the case of grafts because the DAG is then rotated.
88626de195f8 copies: make _checkcopies handle simple renames in a rotated DAG
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30973
diff changeset
771 # If the file exists in both the base and the source, we are not looking
88626de195f8 copies: make _checkcopies handle simple renames in a rotated DAG
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30973
diff changeset
772 # for a rename on the source side, but on the part of the DAG that is
88626de195f8 copies: make _checkcopies handle simple renames in a rotated DAG
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30973
diff changeset
773 # traversed backwards.
88626de195f8 copies: make _checkcopies handle simple renames in a rotated DAG
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30973
diff changeset
774 #
88626de195f8 copies: make _checkcopies handle simple renames in a rotated DAG
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30973
diff changeset
775 # In the case there is both backward and forward renames (before and after
30980
856ead835f56 checkcopies: handle divergences contained entirely in tca::ctx
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30976
diff changeset
776 # the base) this is more complicated as we must detect a divergence.
856ead835f56 checkcopies: handle divergences contained entirely in tca::ctx
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30976
diff changeset
777 # We use 'backwards = False' in that case.
30982
b94b92f0c683 checkcopies: add logic to handle remotebase
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30981
diff changeset
778 backwards = not remotebase and base != tca and f in mb
33347
6966e42f833a copies: rename getfctx to getsrcfctx
Stanislau Hlebik <stash@fb.com>
parents: 33346
diff changeset
779 getsrcfctx = _makegetfctx(srcctx)
33348
5313d98089f5 copies: introduce getdstfctx
Stanislau Hlebik <stash@fb.com>
parents: 33347
diff changeset
780 getdstfctx = _makegetfctx(dstctx)
19178
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
781
33342
c8c9feffbd35 copies: rename m1 to msrc
Stanislau Hlebik <stash@fb.com>
parents: 33074
diff changeset
782 if msrc[f] == mb.get(f) and not remotebase:
31008
69ffbbe73dd0 merge: avoid superfluous filemerges when grafting through renames (issue5407)
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30987
diff changeset
783 # Nothing to merge
69ffbbe73dd0 merge: avoid superfluous filemerges when grafting through renames (issue5407)
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30987
diff changeset
784 return
69ffbbe73dd0 merge: avoid superfluous filemerges when grafting through renames (issue5407)
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30987
diff changeset
785
19178
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
786 of = None
33074
bd872f64a8ba cleanup: use set literals
Martin von Zweigbergk <martinvonz@google.com>
parents: 32035
diff changeset
787 seen = {f}
33347
6966e42f833a copies: rename getfctx to getsrcfctx
Stanislau Hlebik <stash@fb.com>
parents: 33346
diff changeset
788 for oc in getsrcfctx(f, msrc[f]).ancestors():
25714
708b19c18adf mergecopies: avoid slowdown from linkrev adjustment (issue4680)
Matt Mackall <mpm@selenic.com>
parents: 24961
diff changeset
789 ocr = oc.linkrev()
19178
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
790 of = oc.path()
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
791 if of in seen:
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
792 # check limit late - grab last rename before
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
793 if ocr < limit:
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
794 break
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
795 continue
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
796 seen.add(of)
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
797
30974
88626de195f8 copies: make _checkcopies handle simple renames in a rotated DAG
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30973
diff changeset
798 # remember for dir rename detection
88626de195f8 copies: make _checkcopies handle simple renames in a rotated DAG
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30973
diff changeset
799 if backwards:
88626de195f8 copies: make _checkcopies handle simple renames in a rotated DAG
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30973
diff changeset
800 data['fullcopy'][of] = f # grafting backwards through renames
88626de195f8 copies: make _checkcopies handle simple renames in a rotated DAG
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30973
diff changeset
801 else:
88626de195f8 copies: make _checkcopies handle simple renames in a rotated DAG
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30973
diff changeset
802 data['fullcopy'][f] = of
33343
931b7707179f copies: rename m2 to mdst
Stanislau Hlebik <stash@fb.com>
parents: 33342
diff changeset
803 if of not in mdst:
19178
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
804 continue # no match, keep looking
33343
931b7707179f copies: rename m2 to mdst
Stanislau Hlebik <stash@fb.com>
parents: 33342
diff changeset
805 if mdst[of] == mb.get(of):
30854
2c8ec8c2ddfe copies: don't record divergence for files needing no merge
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30827
diff changeset
806 return # no merge needed, quit early
33348
5313d98089f5 copies: introduce getdstfctx
Stanislau Hlebik <stash@fb.com>
parents: 33347
diff changeset
807 c2 = getdstfctx(of, mdst[of])
30916
f85f9e069e09 checkcopies: add an inline comment about the '_related' call
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30915
diff changeset
808 # c2 might be a plain new file on added on destination side that is
f85f9e069e09 checkcopies: add an inline comment about the '_related' call
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30915
diff changeset
809 # unrelated to the droids we are looking for.
30974
88626de195f8 copies: make _checkcopies handle simple renames in a rotated DAG
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30973
diff changeset
810 cr = _related(oc, c2, tca.rev())
19178
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
811 if cr and (of == f or of == c2.path()): # non-divergent
30974
88626de195f8 copies: make _checkcopies handle simple renames in a rotated DAG
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30973
diff changeset
812 if backwards:
88626de195f8 copies: make _checkcopies handle simple renames in a rotated DAG
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30973
diff changeset
813 data['copy'][of] = f
88626de195f8 copies: make _checkcopies handle simple renames in a rotated DAG
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30973
diff changeset
814 elif of in mb:
30967
8a864844d5a0 checkcopies: add a sanity check against false-positive copies
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30965
diff changeset
815 data['copy'][f] = of
30982
b94b92f0c683 checkcopies: add logic to handle remotebase
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30981
diff changeset
816 elif remotebase: # special case: a <- b <- a -> b "ping-pong" rename
b94b92f0c683 checkcopies: add logic to handle remotebase
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30981
diff changeset
817 data['copy'][of] = f
b94b92f0c683 checkcopies: add logic to handle remotebase
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30981
diff changeset
818 del data['fullcopy'][f]
b94b92f0c683 checkcopies: add logic to handle remotebase
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30981
diff changeset
819 data['fullcopy'][of] = f
30980
856ead835f56 checkcopies: handle divergences contained entirely in tca::ctx
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30976
diff changeset
820 else: # divergence w.r.t. graft CA on one side of topological CA
856ead835f56 checkcopies: handle divergences contained entirely in tca::ctx
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30976
diff changeset
821 for sf in seen:
856ead835f56 checkcopies: handle divergences contained entirely in tca::ctx
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30976
diff changeset
822 if sf in mb:
856ead835f56 checkcopies: handle divergences contained entirely in tca::ctx
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30976
diff changeset
823 assert sf not in data['diverge']
856ead835f56 checkcopies: handle divergences contained entirely in tca::ctx
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30976
diff changeset
824 data['diverge'][sf] = [f, of]
856ead835f56 checkcopies: handle divergences contained entirely in tca::ctx
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30976
diff changeset
825 break
30854
2c8ec8c2ddfe copies: don't record divergence for files needing no merge
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30827
diff changeset
826 return
19178
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
827
30983
1894c830ee74 copies: make _checkcopies handle copy sequences spanning the TCA (issue4028)
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30982
diff changeset
828 if of in mta:
1894c830ee74 copies: make _checkcopies handle copy sequences spanning the TCA (issue4028)
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30982
diff changeset
829 if backwards or remotebase:
1894c830ee74 copies: make _checkcopies handle copy sequences spanning the TCA (issue4028)
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30982
diff changeset
830 data['incomplete'][of] = f
1894c830ee74 copies: make _checkcopies handle copy sequences spanning the TCA (issue4028)
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30982
diff changeset
831 else:
1894c830ee74 copies: make _checkcopies handle copy sequences spanning the TCA (issue4028)
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30982
diff changeset
832 for sf in seen:
1894c830ee74 copies: make _checkcopies handle copy sequences spanning the TCA (issue4028)
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30982
diff changeset
833 if sf in mb:
1894c830ee74 copies: make _checkcopies handle copy sequences spanning the TCA (issue4028)
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30982
diff changeset
834 if tca == base:
1894c830ee74 copies: make _checkcopies handle copy sequences spanning the TCA (issue4028)
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30982
diff changeset
835 data['diverge'].setdefault(sf, []).append(f)
1894c830ee74 copies: make _checkcopies handle copy sequences spanning the TCA (issue4028)
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30982
diff changeset
836 else:
1894c830ee74 copies: make _checkcopies handle copy sequences spanning the TCA (issue4028)
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30982
diff changeset
837 data['incompletediverge'][sf] = [of, f]
1894c830ee74 copies: make _checkcopies handle copy sequences spanning the TCA (issue4028)
Gábor Stefanik <gabor.stefanik@nng.com>
parents: 30982
diff changeset
838 return
22901
722117c8e023 duplicatecopies: move from cmdutil to copies
Matt Mackall <mpm@selenic.com>
parents: 20990
diff changeset
839
722117c8e023 duplicatecopies: move from cmdutil to copies
Matt Mackall <mpm@selenic.com>
parents: 20990
diff changeset
840 def duplicatecopies(repo, rev, fromrev, skiprev=None):
722117c8e023 duplicatecopies: move from cmdutil to copies
Matt Mackall <mpm@selenic.com>
parents: 20990
diff changeset
841 '''reproduce copies from fromrev to rev in the dirstate
722117c8e023 duplicatecopies: move from cmdutil to copies
Matt Mackall <mpm@selenic.com>
parents: 20990
diff changeset
842
722117c8e023 duplicatecopies: move from cmdutil to copies
Matt Mackall <mpm@selenic.com>
parents: 20990
diff changeset
843 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
844 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
845 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
846 copies between fromrev and rev.
722117c8e023 duplicatecopies: move from cmdutil to copies
Matt Mackall <mpm@selenic.com>
parents: 20990
diff changeset
847 '''
722117c8e023 duplicatecopies: move from cmdutil to copies
Matt Mackall <mpm@selenic.com>
parents: 20990
diff changeset
848 exclude = {}
26597
38f92d12357c copy: add flag for disabling copy tracing
Durham Goode <durham@fb.com>
parents: 26508
diff changeset
849 if (skiprev is not None and
34860
26531db4647a copytrace: replace experimental.disablecopytrace config with copytrace (BC)
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34663
diff changeset
850 repo.ui.config('experimental', 'copytrace') != 'off'):
26531db4647a copytrace: replace experimental.disablecopytrace config with copytrace (BC)
Pulkit Goyal <7895pulkit@gmail.com>
parents: 34663
diff changeset
851 # copytrace='off' skips this line, but not the entire function because
26597
38f92d12357c copy: add flag for disabling copy tracing
Durham Goode <durham@fb.com>
parents: 26508
diff changeset
852 # 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: 26508
diff changeset
853 # 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: 26508
diff changeset
854 # metadata across the rebase anyway).
22901
722117c8e023 duplicatecopies: move from cmdutil to copies
Matt Mackall <mpm@selenic.com>
parents: 20990
diff changeset
855 exclude = pathcopies(repo[fromrev], repo[skiprev])
722117c8e023 duplicatecopies: move from cmdutil to copies
Matt Mackall <mpm@selenic.com>
parents: 20990
diff changeset
856 for dst, src in pathcopies(repo[fromrev], repo[rev]).iteritems():
722117c8e023 duplicatecopies: move from cmdutil to copies
Matt Mackall <mpm@selenic.com>
parents: 20990
diff changeset
857 # copies.pathcopies returns backward renames, so dst might not
722117c8e023 duplicatecopies: move from cmdutil to copies
Matt Mackall <mpm@selenic.com>
parents: 20990
diff changeset
858 # actually be in the dirstate
722117c8e023 duplicatecopies: move from cmdutil to copies
Matt Mackall <mpm@selenic.com>
parents: 20990
diff changeset
859 if dst in exclude:
722117c8e023 duplicatecopies: move from cmdutil to copies
Matt Mackall <mpm@selenic.com>
parents: 20990
diff changeset
860 continue
722117c8e023 duplicatecopies: move from cmdutil to copies
Matt Mackall <mpm@selenic.com>
parents: 20990
diff changeset
861 if repo.dirstate[dst] in "nma":
722117c8e023 duplicatecopies: move from cmdutil to copies
Matt Mackall <mpm@selenic.com>
parents: 20990
diff changeset
862 repo.dirstate.copy(src, dst)