annotate mercurial/copies.py @ 26610:f9f82c444ff7

filemerge: only copy to backup during premerge step The premerge might leave the original file in an unclean state. Therefore it's important to only copy the file in the beginning.
author Siddharth Agarwal <sid0@fb.com>
date Sun, 11 Oct 2015 20:04:40 -0700
parents 4b9bb1616195
children f3c6540f2cd1
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
1 # copies.py - copy detection for Mercurial
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
2 #
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
3 # Copyright 2008 Matt Mackall <mpm@selenic.com>
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
4 #
8225
46293a0c7e9f updated license to be explicit about GPL version 2
Martin Geisler <mg@lazybytes.net>
parents: 8209
diff changeset
5 # This software may be used and distributed according to the terms of the
10263
25e572394f5c Update license to GPLv2+
Matt Mackall <mpm@selenic.com>
parents: 10262
diff changeset
6 # GNU General Public License version 2 or any later version.
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
7
25924
cfc24c22454e copies: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25289
diff changeset
8 from __future__ import absolute_import
cfc24c22454e copies: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25289
diff changeset
9
8312
b87a50b7125c separate import lines from mercurial and general python modules
Simon Heimberg <simohe@besonet.ch>
parents: 8225
diff changeset
10 import heapq
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
11
25924
cfc24c22454e copies: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25289
diff changeset
12 from . import (
cfc24c22454e copies: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25289
diff changeset
13 pathutil,
cfc24c22454e copies: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25289
diff changeset
14 util,
cfc24c22454e copies: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25289
diff changeset
15 )
cfc24c22454e copies: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25289
diff changeset
16
6431
a42d8d3e6ea9 copies: refactor symmetricdifference as _findlimit
Matt Mackall <mpm@selenic.com>
parents: 6430
diff changeset
17 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
18 """
652ab726ba93 amend: fix amending rename commit with diverged topologies (issue4405)
Ryan McElroy <rmcelroy@fb.com>
parents: 22901
diff changeset
19 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
20 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
21 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
22 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
23 of the other, in which case we can return the minimum revnum of a and b.
10179
83cfa1baf8ad copies: don't report copies with unrelated branch
Patrick Mezard <pmezard@gmail.com>
parents: 9467
diff changeset
24 None if no such revision exists.
83cfa1baf8ad copies: don't report copies with unrelated branch
Patrick Mezard <pmezard@gmail.com>
parents: 9467
diff changeset
25 """
23071
652ab726ba93 amend: fix amending rename commit with diverged topologies (issue4405)
Ryan McElroy <rmcelroy@fb.com>
parents: 22901
diff changeset
26
6429
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
27 # basic idea:
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
28 # - mark a and b with different sides
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
29 # - 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
30 # on that side, otherwise it is on no side
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
31 # - 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
32 # - add unseen parents to side map
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
33 # - 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
34 # - 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
35 # - track the lowest interesting rev seen
a42d8d3e6ea9 copies: refactor symmetricdifference as _findlimit
Matt Mackall <mpm@selenic.com>
parents: 6430
diff changeset
36 # - quit when interesting revs is zero
6430
a6a66e812c34 copies: teach symmetric difference about working revisions
Matt Mackall <mpm@selenic.com>
parents: 6429
diff changeset
37
a6a66e812c34 copies: teach symmetric difference about working revisions
Matt Mackall <mpm@selenic.com>
parents: 6429
diff changeset
38 cl = repo.changelog
6750
fb42030d79d6 add __len__ and __iter__ methods to repo and revlog
Matt Mackall <mpm@selenic.com>
parents: 6646
diff changeset
39 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
40 if a is None:
a6a66e812c34 copies: teach symmetric difference about working revisions
Matt Mackall <mpm@selenic.com>
parents: 6429
diff changeset
41 a = working
a6a66e812c34 copies: teach symmetric difference about working revisions
Matt Mackall <mpm@selenic.com>
parents: 6429
diff changeset
42 if b is None:
a6a66e812c34 copies: teach symmetric difference about working revisions
Matt Mackall <mpm@selenic.com>
parents: 6429
diff changeset
43 b = working
6429
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
44
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
45 side = {a: -1, b: 1}
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
46 visit = [-a, -b]
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
47 heapq.heapify(visit)
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
48 interesting = len(visit)
10179
83cfa1baf8ad copies: don't report copies with unrelated branch
Patrick Mezard <pmezard@gmail.com>
parents: 9467
diff changeset
49 hascommonancestor = False
6431
a42d8d3e6ea9 copies: refactor symmetricdifference as _findlimit
Matt Mackall <mpm@selenic.com>
parents: 6430
diff changeset
50 limit = working
6429
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
51
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
52 while interesting:
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
53 r = -heapq.heappop(visit)
6430
a6a66e812c34 copies: teach symmetric difference about working revisions
Matt Mackall <mpm@selenic.com>
parents: 6429
diff changeset
54 if r == working:
a6a66e812c34 copies: teach symmetric difference about working revisions
Matt Mackall <mpm@selenic.com>
parents: 6429
diff changeset
55 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
56 else:
a6a66e812c34 copies: teach symmetric difference about working revisions
Matt Mackall <mpm@selenic.com>
parents: 6429
diff changeset
57 parents = cl.parentrevs(r)
a6a66e812c34 copies: teach symmetric difference about working revisions
Matt Mackall <mpm@selenic.com>
parents: 6429
diff changeset
58 for p in parents:
10179
83cfa1baf8ad copies: don't report copies with unrelated branch
Patrick Mezard <pmezard@gmail.com>
parents: 9467
diff changeset
59 if p < 0:
83cfa1baf8ad copies: don't report copies with unrelated branch
Patrick Mezard <pmezard@gmail.com>
parents: 9467
diff changeset
60 continue
6429
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
61 if p not in side:
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
62 # first time we see p; add it to visit
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
63 side[p] = side[r]
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
64 if side[p]:
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
65 interesting += 1
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
66 heapq.heappush(visit, -p)
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
67 elif side[p] and side[p] != side[r]:
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
68 # p was interesting but now we know better
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
69 side[p] = 0
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
70 interesting -= 1
10179
83cfa1baf8ad copies: don't report copies with unrelated branch
Patrick Mezard <pmezard@gmail.com>
parents: 9467
diff changeset
71 hascommonancestor = True
6430
a6a66e812c34 copies: teach symmetric difference about working revisions
Matt Mackall <mpm@selenic.com>
parents: 6429
diff changeset
72 if side[r]:
6431
a42d8d3e6ea9 copies: refactor symmetricdifference as _findlimit
Matt Mackall <mpm@selenic.com>
parents: 6430
diff changeset
73 limit = r # lowest rev visited
6430
a6a66e812c34 copies: teach symmetric difference about working revisions
Matt Mackall <mpm@selenic.com>
parents: 6429
diff changeset
74 interesting -= 1
10179
83cfa1baf8ad copies: don't report copies with unrelated branch
Patrick Mezard <pmezard@gmail.com>
parents: 9467
diff changeset
75
83cfa1baf8ad copies: don't report copies with unrelated branch
Patrick Mezard <pmezard@gmail.com>
parents: 9467
diff changeset
76 if not hascommonancestor:
83cfa1baf8ad copies: don't report copies with unrelated branch
Patrick Mezard <pmezard@gmail.com>
parents: 9467
diff changeset
77 return None
23071
652ab726ba93 amend: fix amending rename commit with diverged topologies (issue4405)
Ryan McElroy <rmcelroy@fb.com>
parents: 22901
diff changeset
78
652ab726ba93 amend: fix amending rename commit with diverged topologies (issue4405)
Ryan McElroy <rmcelroy@fb.com>
parents: 22901
diff changeset
79 # 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
80 # 1/ File 'a0' committed
652ab726ba93 amend: fix amending rename commit with diverged topologies (issue4405)
Ryan McElroy <rmcelroy@fb.com>
parents: 22901
diff changeset
81 # 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
82 # 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
83 # 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
84 # 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
85 #
652ab726ba93 amend: fix amending rename commit with diverged topologies (issue4405)
Ryan McElroy <rmcelroy@fb.com>
parents: 22901
diff changeset
86 # 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
87 #
652ab726ba93 amend: fix amending rename commit with diverged topologies (issue4405)
Ryan McElroy <rmcelroy@fb.com>
parents: 22901
diff changeset
88 # @ 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
89 # |
652ab726ba93 amend: fix amending rename commit with diverged topologies (issue4405)
Ryan McElroy <rmcelroy@fb.com>
parents: 22901
diff changeset
90 # o 2 a1-amend
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 # | o 1 a1
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 # o 0 a0
652ab726ba93 amend: fix amending rename commit with diverged topologies (issue4405)
Ryan McElroy <rmcelroy@fb.com>
parents: 22901
diff changeset
95 #
23139
e53f6b72a0e4 spelling: fixes from proofreading of spell checker issues
Mads Kiilerich <madski@unity3d.com>
parents: 23071
diff changeset
96 # 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
97 # 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
98 # 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
99 # 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
100 return min(limit, a, b)
6429
532ca442b903 symmetricdifference: move back to copies
Matt Mackall <mpm@selenic.com>
parents: 6426
diff changeset
101
15775
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
102 def _chain(src, dst, a, b):
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
103 '''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
104 t = a.copy()
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
105 for k, v in b.iteritems():
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
106 if v in t:
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
107 # found a chain
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
108 if t[v] != k:
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
109 # 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
110 t[k] = t[v]
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
111 if v not in dst:
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
112 # 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
113 del t[v]
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
114 if v in src:
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
115 # 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
116 t[k] = v
15976
d1c74c6151c9 copies: eliminate criss-crosses when chaining
Matt Mackall <mpm@selenic.com>
parents: 15775
diff changeset
117
d1c74c6151c9 copies: eliminate criss-crosses when chaining
Matt Mackall <mpm@selenic.com>
parents: 15775
diff changeset
118 # remove criss-crossed copies
d1c74c6151c9 copies: eliminate criss-crosses when chaining
Matt Mackall <mpm@selenic.com>
parents: 15775
diff changeset
119 for k, v in t.items():
d1c74c6151c9 copies: eliminate criss-crosses when chaining
Matt Mackall <mpm@selenic.com>
parents: 15775
diff changeset
120 if k in src and v in dst:
d1c74c6151c9 copies: eliminate criss-crosses when chaining
Matt Mackall <mpm@selenic.com>
parents: 15775
diff changeset
121 del t[k]
d1c74c6151c9 copies: eliminate criss-crosses when chaining
Matt Mackall <mpm@selenic.com>
parents: 15775
diff changeset
122
15775
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
123 return t
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
124
20294
243ea5ffdf31 diff: search beyond ancestor when detecting renames
Mads Kiilerich <madski@unity3d.com>
parents: 19178
diff changeset
125 def _tracefile(fctx, am, limit=-1):
243ea5ffdf31 diff: search beyond ancestor when detecting renames
Mads Kiilerich <madski@unity3d.com>
parents: 19178
diff changeset
126 '''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
127 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
128
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
129 for f in fctx.ancestors():
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
130 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
131 return f
23982
751d1138ce35 copies: use linkrev for file tracing limit
Matt Mackall <mpm@selenic.com>
parents: 23980
diff changeset
132 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
133 return None
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 def _dirstatecopies(d):
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
136 ds = d._repo.dirstate
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
137 c = ds.copies().copy()
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
138 for k in c.keys():
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
139 if ds[k] not in 'anm':
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
140 del c[k]
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
141 return c
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
142
24782
4906dc0e038c copies: add matcher parameter to copy logic
Durham Goode <durham@fb.com>
parents: 24625
diff changeset
143 def _computeforwardmissing(a, b, match=None):
24011
d7d08337b3f6 copy: move _forwardcopies file logic to a function
Durham Goode <durham@fb.com>
parents: 24010
diff changeset
144 """Computes which files are in b but not a.
d7d08337b3f6 copy: move _forwardcopies file logic to a function
Durham Goode <durham@fb.com>
parents: 24010
diff changeset
145 This is its own function so extensions can easily wrap this call to see what
d7d08337b3f6 copy: move _forwardcopies file logic to a function
Durham Goode <durham@fb.com>
parents: 24010
diff changeset
146 files _forwardcopies is about to process.
d7d08337b3f6 copy: move _forwardcopies file logic to a function
Durham Goode <durham@fb.com>
parents: 24010
diff changeset
147 """
24782
4906dc0e038c copies: add matcher parameter to copy logic
Durham Goode <durham@fb.com>
parents: 24625
diff changeset
148 ma = a.manifest()
4906dc0e038c copies: add matcher parameter to copy logic
Durham Goode <durham@fb.com>
parents: 24625
diff changeset
149 mb = b.manifest()
4906dc0e038c copies: add matcher parameter to copy logic
Durham Goode <durham@fb.com>
parents: 24625
diff changeset
150 if match:
4906dc0e038c copies: add matcher parameter to copy logic
Durham Goode <durham@fb.com>
parents: 24625
diff changeset
151 ma = ma.matches(match)
4906dc0e038c copies: add matcher parameter to copy logic
Durham Goode <durham@fb.com>
parents: 24625
diff changeset
152 mb = mb.matches(match)
4906dc0e038c copies: add matcher parameter to copy logic
Durham Goode <durham@fb.com>
parents: 24625
diff changeset
153 return mb.filesnotin(ma)
24011
d7d08337b3f6 copy: move _forwardcopies file logic to a function
Durham Goode <durham@fb.com>
parents: 24010
diff changeset
154
24782
4906dc0e038c copies: add matcher parameter to copy logic
Durham Goode <durham@fb.com>
parents: 24625
diff changeset
155 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
156 '''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
157
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
158 # check for working copy
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
159 w = None
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
160 if b.rev() is None:
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
161 w = b
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
162 b = w.p1()
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
163 if a == b:
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
164 # 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
165 return _dirstatecopies(w)
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
166
20294
243ea5ffdf31 diff: search beyond ancestor when detecting renames
Mads Kiilerich <madski@unity3d.com>
parents: 19178
diff changeset
167 # 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
168 # 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
169 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
170 if limit is None:
243ea5ffdf31 diff: search beyond ancestor when detecting renames
Mads Kiilerich <madski@unity3d.com>
parents: 19178
diff changeset
171 limit = -1
243ea5ffdf31 diff: search beyond ancestor when detecting renames
Mads Kiilerich <madski@unity3d.com>
parents: 19178
diff changeset
172 am = a.manifest()
243ea5ffdf31 diff: search beyond ancestor when detecting renames
Mads Kiilerich <madski@unity3d.com>
parents: 19178
diff changeset
173
15775
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
174 # find where new files came from
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
175 # 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
176 # 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
177 cm = {}
24782
4906dc0e038c copies: add matcher parameter to copy logic
Durham Goode <durham@fb.com>
parents: 24625
diff changeset
178 missing = _computeforwardmissing(a, b, match=match)
23980
c1ce5442453f _adjustlinkrev: reuse ancestors set during rename detection (issue4514)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23139
diff changeset
179 ancestrycontext = a._repo.changelog.ancestors([b.rev()], inclusive=True)
18878
3cfaace0441e copies._forwardcopies: use set operations to find missing files
Siddharth Agarwal <sid0@fb.com>
parents: 18362
diff changeset
180 for f in missing:
23980
c1ce5442453f _adjustlinkrev: reuse ancestors set during rename detection (issue4514)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23139
diff changeset
181 fctx = b[f]
c1ce5442453f _adjustlinkrev: reuse ancestors set during rename detection (issue4514)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23139
diff changeset
182 fctx._ancestrycontext = ancestrycontext
c1ce5442453f _adjustlinkrev: reuse ancestors set during rename detection (issue4514)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23139
diff changeset
183 ofctx = _tracefile(fctx, am, limit)
18878
3cfaace0441e copies._forwardcopies: use set operations to find missing files
Siddharth Agarwal <sid0@fb.com>
parents: 18362
diff changeset
184 if ofctx:
3cfaace0441e copies._forwardcopies: use set operations to find missing files
Siddharth Agarwal <sid0@fb.com>
parents: 18362
diff changeset
185 cm[f] = ofctx.path()
15775
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
186
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
187 # combine copies from dirstate if necessary
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
188 if w is not None:
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
189 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
190
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
191 return cm
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
192
18136
f23dea2b296e copies: do not track backward copies, only renames (issue3739)
Siddharth Agarwal <sid0@fb.com>
parents: 18135
diff changeset
193 def _backwardrenames(a, b):
26013
38f92d12357c copy: add flag for disabling copy tracing
Durham Goode <durham@fb.com>
parents: 25924
diff changeset
194 if a._repo.ui.configbool('experimental', 'disablecopytrace'):
38f92d12357c copy: add flag for disabling copy tracing
Durham Goode <durham@fb.com>
parents: 25924
diff changeset
195 return {}
38f92d12357c copy: add flag for disabling copy tracing
Durham Goode <durham@fb.com>
parents: 25924
diff changeset
196
18136
f23dea2b296e copies: do not track backward copies, only renames (issue3739)
Siddharth Agarwal <sid0@fb.com>
parents: 18135
diff changeset
197 # 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
198 # 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
199 # 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
200 f = _forwardcopies(b, a)
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
201 r = {}
18355
2330d97e7707 copies: make the loss in _backwardcopies more stable
Mads Kiilerich <mads@kiilerich.com>
parents: 18136
diff changeset
202 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
203 # remove copies
f23dea2b296e copies: do not track backward copies, only renames (issue3739)
Siddharth Agarwal <sid0@fb.com>
parents: 18135
diff changeset
204 if v in a:
f23dea2b296e copies: do not track backward copies, only renames (issue3739)
Siddharth Agarwal <sid0@fb.com>
parents: 18135
diff changeset
205 continue
15775
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
206 r[v] = k
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
207 return r
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
208
24782
4906dc0e038c copies: add matcher parameter to copy logic
Durham Goode <durham@fb.com>
parents: 24625
diff changeset
209 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
210 '''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
211 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
212 return {}
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
213 a = y.ancestor(x)
91eb4512edd0 copies: rewrite copy detection for non-merge users
Matt Mackall <mpm@selenic.com>
parents: 15774
diff changeset
214 if a == x:
24782
4906dc0e038c copies: add matcher parameter to copy logic
Durham Goode <durham@fb.com>
parents: 24625
diff changeset
215 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
216 if a == y:
18136
f23dea2b296e copies: do not track backward copies, only renames (issue3739)
Siddharth Agarwal <sid0@fb.com>
parents: 18135
diff changeset
217 return _backwardrenames(x, y)
24782
4906dc0e038c copies: add matcher parameter to copy logic
Durham Goode <durham@fb.com>
parents: 24625
diff changeset
218 return _chain(x, y, _backwardrenames(x, a),
4906dc0e038c copies: add matcher parameter to copy logic
Durham Goode <durham@fb.com>
parents: 24625
diff changeset
219 _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
220
24625
2cebf17c0fcc copies: pass changectx instead of manifest to _computenonoverlap
Durham Goode <durham@fb.com>
parents: 24415
diff changeset
221 def _computenonoverlap(repo, c1, c2, addedinm1, addedinm2):
2cebf17c0fcc copies: pass changectx instead of manifest to _computenonoverlap
Durham Goode <durham@fb.com>
parents: 24415
diff changeset
222 """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: 24415
diff changeset
223 and c2. This is its own function so extensions can easily wrap this call
24187
30219bd46ed7 copies: only calculate 'addedinm[12]' sets once
Martin von Zweigbergk <martinvonz@google.com>
parents: 24186
diff changeset
224 to see what files mergecopies is about to process.
24273
ce847603040b copies: added manifests to computenonoverlap
Durham Goode <durham@fb.com>
parents: 24187
diff changeset
225
24625
2cebf17c0fcc copies: pass changectx instead of manifest to _computenonoverlap
Durham Goode <durham@fb.com>
parents: 24415
diff changeset
226 Even though c1 and c2 are not used in this function, they are useful in
24273
ce847603040b copies: added manifests to computenonoverlap
Durham Goode <durham@fb.com>
parents: 24187
diff changeset
227 other extensions for being able to read the file nodes of the changed files.
24010
a63c2b159df4 copy: move mergecopies file logic to a function
Durham Goode <durham@fb.com>
parents: 23982
diff changeset
228 """
24185
3a3806fe3ddf copies: replace _nonoverlap() by calls to manifestdict.filesnotin()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24184
diff changeset
229 u1 = sorted(addedinm1 - addedinm2)
3a3806fe3ddf copies: replace _nonoverlap() by calls to manifestdict.filesnotin()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24184
diff changeset
230 u2 = sorted(addedinm2 - addedinm1)
24010
a63c2b159df4 copy: move mergecopies file logic to a function
Durham Goode <durham@fb.com>
parents: 23982
diff changeset
231
a63c2b159df4 copy: move mergecopies file logic to a function
Durham Goode <durham@fb.com>
parents: 23982
diff changeset
232 if u1:
a63c2b159df4 copy: move mergecopies file logic to a function
Durham Goode <durham@fb.com>
parents: 23982
diff changeset
233 repo.ui.debug(" unmatched files in local:\n %s\n"
a63c2b159df4 copy: move mergecopies file logic to a function
Durham Goode <durham@fb.com>
parents: 23982
diff changeset
234 % "\n ".join(u1))
a63c2b159df4 copy: move mergecopies file logic to a function
Durham Goode <durham@fb.com>
parents: 23982
diff changeset
235 if u2:
a63c2b159df4 copy: move mergecopies file logic to a function
Durham Goode <durham@fb.com>
parents: 23982
diff changeset
236 repo.ui.debug(" unmatched files in other:\n %s\n"
a63c2b159df4 copy: move mergecopies file logic to a function
Durham Goode <durham@fb.com>
parents: 23982
diff changeset
237 % "\n ".join(u2))
a63c2b159df4 copy: move mergecopies file logic to a function
Durham Goode <durham@fb.com>
parents: 23982
diff changeset
238 return u1, u2
a63c2b159df4 copy: move mergecopies file logic to a function
Durham Goode <durham@fb.com>
parents: 23982
diff changeset
239
16169
c12d4aceba79 copies: remove checkdirs options
Matt Mackall <mpm@selenic.com>
parents: 16168
diff changeset
240 def mergecopies(repo, c1, c2, ca):
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
241 """
16168
7bbabfe25321 copies: add docstring for mergecopies
Matt Mackall <mpm@selenic.com>
parents: 15994
diff changeset
242 Find moves and copies between context c1 and c2 that are relevant
7bbabfe25321 copies: add docstring for mergecopies
Matt Mackall <mpm@selenic.com>
parents: 15994
diff changeset
243 for merging.
7bbabfe25321 copies: add docstring for mergecopies
Matt Mackall <mpm@selenic.com>
parents: 15994
diff changeset
244
18134
6c35b53cd28b copies: separate moves via directory renames from explicit copies
Siddharth Agarwal <sid0@fb.com>
parents: 17055
diff changeset
245 Returns four dicts: "copy", "movewithdir", "diverge", and
6c35b53cd28b copies: separate moves via directory renames from explicit copies
Siddharth Agarwal <sid0@fb.com>
parents: 17055
diff changeset
246 "renamedelete".
16168
7bbabfe25321 copies: add docstring for mergecopies
Matt Mackall <mpm@selenic.com>
parents: 15994
diff changeset
247
16177
b8c1a8a57540 copies: fix mergecopies doc mapping direction
Matt Mackall <mpm@selenic.com>
parents: 16169
diff changeset
248 "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
249 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
250
18134
6c35b53cd28b copies: separate moves via directory renames from explicit copies
Siddharth Agarwal <sid0@fb.com>
parents: 17055
diff changeset
251 "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
252 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
253 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
254 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
255
16168
7bbabfe25321 copies: add docstring for mergecopies
Matt Mackall <mpm@selenic.com>
parents: 15994
diff changeset
256 "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
257 for divergent renames.
16794
98687cdddcb1 merge: warn about file deleted in one branch and renamed in other (issue3074)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 16792
diff changeset
258
98687cdddcb1 merge: warn about file deleted in one branch and renamed in other (issue3074)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 16792
diff changeset
259 "renamedelete" is a mapping of source name -> list of destination
98687cdddcb1 merge: warn about file deleted in one branch and renamed in other (issue3074)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 16792
diff changeset
260 names for files deleted in c1 that were renamed in c2 or vice-versa.
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
261 """
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
262 # 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
263 if not c1 or not c2 or c1 == c2:
18134
6c35b53cd28b copies: separate moves via directory renames from explicit copies
Siddharth Agarwal <sid0@fb.com>
parents: 17055
diff changeset
264 return {}, {}, {}, {}
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
265
6646
9eb274d773d9 copies: teach copies about dirstate.copies
Matt Mackall <mpm@selenic.com>
parents: 6431
diff changeset
266 # avoid silly behavior for parent -> working dir
13878
a8d13ee0ce68 misc: replace .parents()[0] with p1()
Matt Mackall <mpm@selenic.com>
parents: 12683
diff changeset
267 if c2.node() is None and c1.node() == repo.dirstate.p1():
18134
6c35b53cd28b copies: separate moves via directory renames from explicit copies
Siddharth Agarwal <sid0@fb.com>
parents: 17055
diff changeset
268 return repo.dirstate.copies(), {}, {}, {}
6646
9eb274d773d9 copies: teach copies about dirstate.copies
Matt Mackall <mpm@selenic.com>
parents: 6431
diff changeset
269
26013
38f92d12357c copy: add flag for disabling copy tracing
Durham Goode <durham@fb.com>
parents: 25924
diff changeset
270 # Copy trace disabling is explicitly below the node == p1 logic above
38f92d12357c copy: add flag for disabling copy tracing
Durham Goode <durham@fb.com>
parents: 25924
diff changeset
271 # because the logic above is required for a simple copy to be kept across a
38f92d12357c copy: add flag for disabling copy tracing
Durham Goode <durham@fb.com>
parents: 25924
diff changeset
272 # rebase.
38f92d12357c copy: add flag for disabling copy tracing
Durham Goode <durham@fb.com>
parents: 25924
diff changeset
273 if repo.ui.configbool('experimental', 'disablecopytrace'):
38f92d12357c copy: add flag for disabling copy tracing
Durham Goode <durham@fb.com>
parents: 25924
diff changeset
274 return {}, {}, {}, {}
38f92d12357c copy: add flag for disabling copy tracing
Durham Goode <durham@fb.com>
parents: 25924
diff changeset
275
6431
a42d8d3e6ea9 copies: refactor symmetricdifference as _findlimit
Matt Mackall <mpm@selenic.com>
parents: 6430
diff changeset
276 limit = _findlimit(repo, c1.rev(), c2.rev())
10179
83cfa1baf8ad copies: don't report copies with unrelated branch
Patrick Mezard <pmezard@gmail.com>
parents: 9467
diff changeset
277 if limit is None:
83cfa1baf8ad copies: don't report copies with unrelated branch
Patrick Mezard <pmezard@gmail.com>
parents: 9467
diff changeset
278 # no common ancestor, no copies
18134
6c35b53cd28b copies: separate moves via directory renames from explicit copies
Siddharth Agarwal <sid0@fb.com>
parents: 17055
diff changeset
279 return {}, {}, {}, {}
26319
4b9bb1616195 copies: move debug statement to appropriate place
Matt Mackall <mpm@selenic.com>
parents: 26317
diff changeset
280 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: 26317
diff changeset
281
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
282 m1 = c1.manifest()
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
283 m2 = c2.manifest()
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
284 ma = ca.manifest()
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
285
24412
9372180b8c9b mergecopies: reuse ancestry context when traversing file history (issue4537)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23982
diff changeset
286
9372180b8c9b mergecopies: reuse ancestry context when traversing file history (issue4537)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23982
diff changeset
287 def setupctx(ctx):
26315
3c6902ed9f07 copies: rename ctx() to getfctx() for clarity
Matt Mackall <mpm@selenic.com>
parents: 26013
diff changeset
288 """return a 'getfctx' function suitable for checkcopies usage
24412
9372180b8c9b mergecopies: reuse ancestry context when traversing file history (issue4537)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23982
diff changeset
289
9372180b8c9b mergecopies: reuse ancestry context when traversing file history (issue4537)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23982
diff changeset
290 We have to re-setup the function building 'filectx' for each
9372180b8c9b mergecopies: reuse ancestry context when traversing file history (issue4537)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23982
diff changeset
291 'checkcopies' to ensure the linkrev adjustement is properly setup for
9372180b8c9b mergecopies: reuse ancestry context when traversing file history (issue4537)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23982
diff changeset
292 each. Linkrev adjustment is important to avoid bug in rename
9372180b8c9b mergecopies: reuse ancestry context when traversing file history (issue4537)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23982
diff changeset
293 detection. Moreover, having a proper '_ancestrycontext' setup ensures
9372180b8c9b mergecopies: reuse ancestry context when traversing file history (issue4537)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23982
diff changeset
294 the performance impact of this adjustment is kept limited. Without it,
9372180b8c9b mergecopies: reuse ancestry context when traversing file history (issue4537)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23982
diff changeset
295 each file could do a full dag traversal making the time complexity of
9372180b8c9b mergecopies: reuse ancestry context when traversing file history (issue4537)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23982
diff changeset
296 the operation explode (see issue4537).
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
297
24412
9372180b8c9b mergecopies: reuse ancestry context when traversing file history (issue4537)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23982
diff changeset
298 This function exists here mostly to limit the impact on stable. Feel
9372180b8c9b mergecopies: reuse ancestry context when traversing file history (issue4537)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23982
diff changeset
299 free to refactor on default.
9372180b8c9b mergecopies: reuse ancestry context when traversing file history (issue4537)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23982
diff changeset
300 """
9372180b8c9b mergecopies: reuse ancestry context when traversing file history (issue4537)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23982
diff changeset
301 rev = ctx.rev()
9372180b8c9b mergecopies: reuse ancestry context when traversing file history (issue4537)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23982
diff changeset
302 ac = getattr(ctx, '_ancestrycontext', None)
9372180b8c9b mergecopies: reuse ancestry context when traversing file history (issue4537)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23982
diff changeset
303 if ac is None:
9372180b8c9b mergecopies: reuse ancestry context when traversing file history (issue4537)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23982
diff changeset
304 revs = [rev]
9372180b8c9b mergecopies: reuse ancestry context when traversing file history (issue4537)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23982
diff changeset
305 if rev is None:
9372180b8c9b mergecopies: reuse ancestry context when traversing file history (issue4537)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23982
diff changeset
306 revs = [p.rev() for p in ctx.parents()]
9372180b8c9b mergecopies: reuse ancestry context when traversing file history (issue4537)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23982
diff changeset
307 ac = ctx._repo.changelog.ancestors(revs, inclusive=True)
9372180b8c9b mergecopies: reuse ancestry context when traversing file history (issue4537)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23982
diff changeset
308 ctx._ancestrycontext = ac
9372180b8c9b mergecopies: reuse ancestry context when traversing file history (issue4537)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23982
diff changeset
309 def makectx(f, n):
9372180b8c9b mergecopies: reuse ancestry context when traversing file history (issue4537)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23982
diff changeset
310 if len(n) != 20: # in a working context?
9372180b8c9b mergecopies: reuse ancestry context when traversing file history (issue4537)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23982
diff changeset
311 if c1.rev() is None:
9372180b8c9b mergecopies: reuse ancestry context when traversing file history (issue4537)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23982
diff changeset
312 return c1.filectx(f)
9372180b8c9b mergecopies: reuse ancestry context when traversing file history (issue4537)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23982
diff changeset
313 return c2.filectx(f)
9372180b8c9b mergecopies: reuse ancestry context when traversing file history (issue4537)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23982
diff changeset
314 fctx = repo.filectx(f, fileid=n)
9372180b8c9b mergecopies: reuse ancestry context when traversing file history (issue4537)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23982
diff changeset
315 # setup only needed for filectx not create from a changectx
9372180b8c9b mergecopies: reuse ancestry context when traversing file history (issue4537)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23982
diff changeset
316 fctx._ancestrycontext = ac
9372180b8c9b mergecopies: reuse ancestry context when traversing file history (issue4537)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23982
diff changeset
317 fctx._descendantrev = rev
9372180b8c9b mergecopies: reuse ancestry context when traversing file history (issue4537)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23982
diff changeset
318 return fctx
9372180b8c9b mergecopies: reuse ancestry context when traversing file history (issue4537)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23982
diff changeset
319 return util.lrucachefunc(makectx)
9372180b8c9b mergecopies: reuse ancestry context when traversing file history (issue4537)
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23982
diff changeset
320
26316
d5618e210191 copies: begin separating mergecopies sides
Matt Mackall <mpm@selenic.com>
parents: 26315
diff changeset
321 copy1, copy2, = {}, {}
d5618e210191 copies: begin separating mergecopies sides
Matt Mackall <mpm@selenic.com>
parents: 26315
diff changeset
322 movewithdir1, movewithdir2 = {}, {}
d5618e210191 copies: begin separating mergecopies sides
Matt Mackall <mpm@selenic.com>
parents: 26315
diff changeset
323 fullcopy1, fullcopy2 = {}, {}
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
324 diverge = {}
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
325
24187
30219bd46ed7 copies: only calculate 'addedinm[12]' sets once
Martin von Zweigbergk <martinvonz@google.com>
parents: 24186
diff changeset
326 addedinm1 = m1.filesnotin(ma)
30219bd46ed7 copies: only calculate 'addedinm[12]' sets once
Martin von Zweigbergk <martinvonz@google.com>
parents: 24186
diff changeset
327 addedinm2 = m2.filesnotin(ma)
24625
2cebf17c0fcc copies: pass changectx instead of manifest to _computenonoverlap
Durham Goode <durham@fb.com>
parents: 24415
diff changeset
328 u1, u2 = _computenonoverlap(repo, c1, c2, addedinm1, addedinm2)
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
329
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
330 for f in u1:
26315
3c6902ed9f07 copies: rename ctx() to getfctx() for clarity
Matt Mackall <mpm@selenic.com>
parents: 26013
diff changeset
331 getfctx = setupctx(c1)
26316
d5618e210191 copies: begin separating mergecopies sides
Matt Mackall <mpm@selenic.com>
parents: 26315
diff changeset
332 checkcopies(getfctx, f, m1, m2, ca, limit, diverge, copy1, fullcopy1)
20989
e8533ec2d222 copies: remove _checkcopies wrapper - it does no good
Mads Kiilerich <madski@unity3d.com>
parents: 20641
diff changeset
333
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
334 for f in u2:
26315
3c6902ed9f07 copies: rename ctx() to getfctx() for clarity
Matt Mackall <mpm@selenic.com>
parents: 26013
diff changeset
335 getfctx = setupctx(c2)
26316
d5618e210191 copies: begin separating mergecopies sides
Matt Mackall <mpm@selenic.com>
parents: 26315
diff changeset
336 checkcopies(getfctx, f, m2, m1, ca, limit, diverge, copy2, fullcopy2)
d5618e210191 copies: begin separating mergecopies sides
Matt Mackall <mpm@selenic.com>
parents: 26315
diff changeset
337
d5618e210191 copies: begin separating mergecopies sides
Matt Mackall <mpm@selenic.com>
parents: 26315
diff changeset
338 copy = dict(copy1.items() + copy2.items())
d5618e210191 copies: begin separating mergecopies sides
Matt Mackall <mpm@selenic.com>
parents: 26315
diff changeset
339 movewithdir = dict(movewithdir1.items() + movewithdir2.items())
d5618e210191 copies: begin separating mergecopies sides
Matt Mackall <mpm@selenic.com>
parents: 26315
diff changeset
340 fullcopy = dict(fullcopy1.items() + fullcopy2.items())
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
341
16794
98687cdddcb1 merge: warn about file deleted in one branch and renamed in other (issue3074)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 16792
diff changeset
342 renamedelete = {}
16795
e9ae770eff1c merge: show renamed on one and deleted on the other side in debug output
Thomas Arendsen Hein <thomas@intevation.de>
parents: 16794
diff changeset
343 renamedelete2 = set()
26317
07ac78ba2e37 copies: rename diverge2 to divergeset for clarity
Matt Mackall <mpm@selenic.com>
parents: 26316
diff changeset
344 divergeset = set()
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
345 for of, fl in diverge.items():
16792
ad394c897b16 merge: do not warn about copy and rename in the same transaction (issue2113)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 16178
diff changeset
346 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: 10874
diff changeset
347 del diverge[of] # not actually divergent, or not a rename
16794
98687cdddcb1 merge: warn about file deleted in one branch and renamed in other (issue3074)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 16792
diff changeset
348 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: 16792
diff changeset
349 # 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: 16792
diff changeset
350 # 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: 16792
diff changeset
351 renamedelete[of] = [f for f in fl if f in c1 or f in c2]
16795
e9ae770eff1c merge: show renamed on one and deleted on the other side in debug output
Thomas Arendsen Hein <thomas@intevation.de>
parents: 16794
diff changeset
352 renamedelete2.update(fl) # reverse map for below
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
353 else:
26317
07ac78ba2e37 copies: rename diverge2 to divergeset for clarity
Matt Mackall <mpm@selenic.com>
parents: 26316
diff changeset
354 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
355
24186
61aadba2396e copies: calculate 'bothnew' from manifestdict.filesnotin()
Martin von Zweigbergk <martinvonz@google.com>
parents: 24185
diff changeset
356 bothnew = sorted(addedinm1 & addedinm2)
20641
3db9e798e004 copies: when both sides made the same copy, report it as a copy
Mads Kiilerich <madski@unity3d.com>
parents: 20294
diff changeset
357 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
358 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
359 % "\n ".join(bothnew))
3db9e798e004 copies: when both sides made the same copy, report it as a copy
Mads Kiilerich <madski@unity3d.com>
parents: 20294
diff changeset
360 bothdiverge, _copy, _fullcopy = {}, {}, {}
3db9e798e004 copies: when both sides made the same copy, report it as a copy
Mads Kiilerich <madski@unity3d.com>
parents: 20294
diff changeset
361 for f in bothnew:
26315
3c6902ed9f07 copies: rename ctx() to getfctx() for clarity
Matt Mackall <mpm@selenic.com>
parents: 26013
diff changeset
362 getfctx = setupctx(c1)
3c6902ed9f07 copies: rename ctx() to getfctx() for clarity
Matt Mackall <mpm@selenic.com>
parents: 26013
diff changeset
363 checkcopies(getfctx, f, m1, m2, ca, limit, bothdiverge,
3c6902ed9f07 copies: rename ctx() to getfctx() for clarity
Matt Mackall <mpm@selenic.com>
parents: 26013
diff changeset
364 _copy, _fullcopy)
3c6902ed9f07 copies: rename ctx() to getfctx() for clarity
Matt Mackall <mpm@selenic.com>
parents: 26013
diff changeset
365 getfctx = setupctx(c2)
3c6902ed9f07 copies: rename ctx() to getfctx() for clarity
Matt Mackall <mpm@selenic.com>
parents: 26013
diff changeset
366 checkcopies(getfctx, f, m2, m1, ca, limit, bothdiverge,
3c6902ed9f07 copies: rename ctx() to getfctx() for clarity
Matt Mackall <mpm@selenic.com>
parents: 26013
diff changeset
367 _copy, _fullcopy)
20641
3db9e798e004 copies: when both sides made the same copy, report it as a copy
Mads Kiilerich <madski@unity3d.com>
parents: 20294
diff changeset
368 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
369 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
370 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
371
20990
d9e211a658eb copies: guard debug section with ui.debugflag
Mads Kiilerich <madski@unity3d.com>
parents: 20989
diff changeset
372 if fullcopy and repo.ui.debugflag:
16795
e9ae770eff1c merge: show renamed on one and deleted on the other side in debug output
Thomas Arendsen Hein <thomas@intevation.de>
parents: 16794
diff changeset
373 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: 16794
diff changeset
374 "% = renamed and deleted):\n")
18362
5a4f220fbfca copies: report found copies sorted
Mads Kiilerich <mads@kiilerich.com>
parents: 18355
diff changeset
375 for f in sorted(fullcopy):
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
376 note = ""
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
377 if f in copy:
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
378 note += "*"
26317
07ac78ba2e37 copies: rename diverge2 to divergeset for clarity
Matt Mackall <mpm@selenic.com>
parents: 26316
diff changeset
379 if f in divergeset:
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
380 note += "!"
16795
e9ae770eff1c merge: show renamed on one and deleted on the other side in debug output
Thomas Arendsen Hein <thomas@intevation.de>
parents: 16794
diff changeset
381 if f in renamedelete2:
e9ae770eff1c merge: show renamed on one and deleted on the other side in debug output
Thomas Arendsen Hein <thomas@intevation.de>
parents: 16794
diff changeset
382 note += "%"
18135
a6fe1b9cc68f copies: make debug messages more sensible
Siddharth Agarwal <sid0@fb.com>
parents: 18134
diff changeset
383 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
384 note))
26317
07ac78ba2e37 copies: rename diverge2 to divergeset for clarity
Matt Mackall <mpm@selenic.com>
parents: 26316
diff changeset
385 del divergeset
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
386
16169
c12d4aceba79 copies: remove checkdirs options
Matt Mackall <mpm@selenic.com>
parents: 16168
diff changeset
387 if not fullcopy:
18134
6c35b53cd28b copies: separate moves via directory renames from explicit copies
Siddharth Agarwal <sid0@fb.com>
parents: 17055
diff changeset
388 return copy, movewithdir, diverge, renamedelete
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
389
9467
4c041f1ee1b4 do not attempt to translate ui.debug output
Martin Geisler <mg@lazybytes.net>
parents: 9102
diff changeset
390 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
391
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
392 # generate a directory move map
16178
828fe2ca7cbb copies: use ctx.dirs() for directory rename detection
Matt Mackall <mpm@selenic.com>
parents: 16177
diff changeset
393 d1, d2 = c1.dirs(), c2.dirs()
25288
947771ad5174 copies: document hack for adding '' to set of dirs
Martin von Zweigbergk <martinvonz@google.com>
parents: 25282
diff changeset
394 # 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: 18878
diff changeset
395 d1.addpath('/')
d8ff607ef721 scmutil: use new dirs class in dirstate and context
Bryan O'Sullivan <bryano@fb.com>
parents: 18878
diff changeset
396 d2.addpath('/')
17055
8b7cd9a998f0 copies: re-include root directory in directory rename detection (issue3511)
Matt Mackall <mpm@selenic.com>
parents: 16795
diff changeset
397 invalid = set()
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
398 dirmove = {}
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
399
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
400 # 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
401 # 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: 6762
diff changeset
402 for dst, src in fullcopy.iteritems():
25282
0f28815ef066 copies: switch to using pathutil.dirname
Durham Goode <durham@fb.com>
parents: 24782
diff changeset
403 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
404 if dsrc in invalid:
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
405 # already seen to be uninteresting
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
406 continue
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
407 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
408 # directory wasn't entirely moved locally
8468
b35d11d10646 copies: use set instead of dict
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8337
diff changeset
409 invalid.add(dsrc)
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
410 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
411 # directory wasn't entirely moved remotely
8468
b35d11d10646 copies: use set instead of dict
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8337
diff changeset
412 invalid.add(dsrc)
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
413 elif dsrc in dirmove and dirmove[dsrc] != ddst:
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
414 # files from the same directory moved to two different places
8468
b35d11d10646 copies: use set instead of dict
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8337
diff changeset
415 invalid.add(dsrc)
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
416 else:
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
417 # looks good so far
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
418 dirmove[dsrc + "/"] = ddst + "/"
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
419
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
420 for i in invalid:
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
421 if i in dirmove:
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
422 del dirmove[i]
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
423 del d1, d2, invalid
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
424
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
425 if not dirmove:
18134
6c35b53cd28b copies: separate moves via directory renames from explicit copies
Siddharth Agarwal <sid0@fb.com>
parents: 17055
diff changeset
426 return copy, movewithdir, diverge, renamedelete
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
427
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
428 for d in dirmove:
18135
a6fe1b9cc68f copies: make debug messages more sensible
Siddharth Agarwal <sid0@fb.com>
parents: 18134
diff changeset
429 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
430 (d, dirmove[d]))
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
431
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
432 # check unaccounted nonoverlapping files against directory moves
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
433 for f in u1 + u2:
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
434 if f not in fullcopy:
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
435 for d in dirmove:
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
436 if f.startswith(d):
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
437 # 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
438 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
439 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
440 movewithdir[f] = df
18135
a6fe1b9cc68f copies: make debug messages more sensible
Siddharth Agarwal <sid0@fb.com>
parents: 18134
diff changeset
441 repo.ui.debug((" pending file src: '%s' -> "
a6fe1b9cc68f copies: make debug messages more sensible
Siddharth Agarwal <sid0@fb.com>
parents: 18134
diff changeset
442 "dst: '%s'\n") % (f, df))
6274
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
443 break
f3f383efbeae copies: move findcopies code to its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
444
18134
6c35b53cd28b copies: separate moves via directory renames from explicit copies
Siddharth Agarwal <sid0@fb.com>
parents: 17055
diff changeset
445 return copy, movewithdir, diverge, renamedelete
19178
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
446
26315
3c6902ed9f07 copies: rename ctx() to getfctx() for clarity
Matt Mackall <mpm@selenic.com>
parents: 26013
diff changeset
447 def checkcopies(getfctx, f, m1, m2, ca, limit, diverge, copy, fullcopy):
19178
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
448 """
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
449 check possible copies of f from m1 to m2
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
450
26315
3c6902ed9f07 copies: rename ctx() to getfctx() for clarity
Matt Mackall <mpm@selenic.com>
parents: 26013
diff changeset
451 getfctx = function accepting (filename, node) that returns a filectx.
19178
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
452 f = the filename to check
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
453 m1 = the source manifest
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
454 m2 = the destination manifest
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
455 ca = the changectx of the common ancestor
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
456 limit = the rev number to not search beyond
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
457 diverge = record all diverges in this dict
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
458 copy = record all non-divergent copies in this dict
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
459 fullcopy = record all copies in this dict
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
460 """
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
461
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
462 ma = ca.manifest()
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
463
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
464 def _related(f1, f2, limit):
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
465 # Walk back to common ancestor to see if the two files originate
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
466 # from the same file. Since workingfilectx's rev() is None it messes
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
467 # up the integer comparison logic, hence the pre-step check for
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
468 # None (f1 and f2 can only be workingfilectx's initially).
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
469
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
470 if f1 == f2:
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
471 return f1 # a match
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
472
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
473 g1, g2 = f1.ancestors(), f2.ancestors()
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
474 try:
25279
708b19c18adf mergecopies: avoid slowdown from linkrev adjustment (issue4680)
Matt Mackall <mpm@selenic.com>
parents: 24782
diff changeset
475 f1r, f2r = f1.linkrev(), f2.linkrev()
19178
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
476
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
477 if f1r is None:
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
478 f1 = g1.next()
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
479 if f2r is None:
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
480 f2 = g2.next()
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
481
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
482 while True:
25279
708b19c18adf mergecopies: avoid slowdown from linkrev adjustment (issue4680)
Matt Mackall <mpm@selenic.com>
parents: 24782
diff changeset
483 f1r, f2r = f1.linkrev(), f2.linkrev()
19178
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
484 if f1r > f2r:
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
485 f1 = g1.next()
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
486 elif f2r > f1r:
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
487 f2 = g2.next()
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
488 elif f1 == f2:
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
489 return f1 # a match
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
490 elif f1r == f2r or f1r < limit or f2r < limit:
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
491 return False # copy no longer relevant
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
492 except StopIteration:
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
493 return False
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
494
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
495 of = None
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
496 seen = set([f])
26315
3c6902ed9f07 copies: rename ctx() to getfctx() for clarity
Matt Mackall <mpm@selenic.com>
parents: 26013
diff changeset
497 for oc in getfctx(f, m1[f]).ancestors():
25279
708b19c18adf mergecopies: avoid slowdown from linkrev adjustment (issue4680)
Matt Mackall <mpm@selenic.com>
parents: 24782
diff changeset
498 ocr = oc.linkrev()
19178
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
499 of = oc.path()
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
500 if of in seen:
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
501 # 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
502 if ocr < limit:
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
503 break
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
504 continue
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
505 seen.add(of)
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
506
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
507 fullcopy[f] = of # remember for dir rename detection
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
508 if of not in m2:
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
509 continue # no match, keep looking
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
510 if m2[of] == ma.get(of):
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
511 break # no merge needed, quit early
26315
3c6902ed9f07 copies: rename ctx() to getfctx() for clarity
Matt Mackall <mpm@selenic.com>
parents: 26013
diff changeset
512 c2 = getfctx(of, m2[of])
19178
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
513 cr = _related(oc, c2, ca.rev())
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
514 if cr and (of == f or of == c2.path()): # non-divergent
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
515 copy[f] = of
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
516 of = None
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
517 break
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
518
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
519 if of in ma:
4327687ca757 copies: refactor checkcopies() into a top level method
Durham Goode <durham@fb.com>
parents: 18899
diff changeset
520 diverge.setdefault(of, []).append(f)
22901
722117c8e023 duplicatecopies: move from cmdutil to copies
Matt Mackall <mpm@selenic.com>
parents: 20990
diff changeset
521
722117c8e023 duplicatecopies: move from cmdutil to copies
Matt Mackall <mpm@selenic.com>
parents: 20990
diff changeset
522 def duplicatecopies(repo, rev, fromrev, skiprev=None):
722117c8e023 duplicatecopies: move from cmdutil to copies
Matt Mackall <mpm@selenic.com>
parents: 20990
diff changeset
523 '''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
524
722117c8e023 duplicatecopies: move from cmdutil to copies
Matt Mackall <mpm@selenic.com>
parents: 20990
diff changeset
525 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
526 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
527 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
528 copies between fromrev and rev.
722117c8e023 duplicatecopies: move from cmdutil to copies
Matt Mackall <mpm@selenic.com>
parents: 20990
diff changeset
529 '''
722117c8e023 duplicatecopies: move from cmdutil to copies
Matt Mackall <mpm@selenic.com>
parents: 20990
diff changeset
530 exclude = {}
26013
38f92d12357c copy: add flag for disabling copy tracing
Durham Goode <durham@fb.com>
parents: 25924
diff changeset
531 if (skiprev is not None and
38f92d12357c copy: add flag for disabling copy tracing
Durham Goode <durham@fb.com>
parents: 25924
diff changeset
532 not repo.ui.configbool('experimental', 'disablecopytrace')):
38f92d12357c copy: add flag for disabling copy tracing
Durham Goode <durham@fb.com>
parents: 25924
diff changeset
533 # disablecopytrace skips this line, but not the entire function because
38f92d12357c copy: add flag for disabling copy tracing
Durham Goode <durham@fb.com>
parents: 25924
diff changeset
534 # the line below is O(size of the repo) during a rebase, while the rest
38f92d12357c copy: add flag for disabling copy tracing
Durham Goode <durham@fb.com>
parents: 25924
diff changeset
535 # of the function is much faster (and is required for carrying copy
38f92d12357c copy: add flag for disabling copy tracing
Durham Goode <durham@fb.com>
parents: 25924
diff changeset
536 # metadata across the rebase anyway).
22901
722117c8e023 duplicatecopies: move from cmdutil to copies
Matt Mackall <mpm@selenic.com>
parents: 20990
diff changeset
537 exclude = pathcopies(repo[fromrev], repo[skiprev])
722117c8e023 duplicatecopies: move from cmdutil to copies
Matt Mackall <mpm@selenic.com>
parents: 20990
diff changeset
538 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
539 # 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
540 # actually be in the dirstate
722117c8e023 duplicatecopies: move from cmdutil to copies
Matt Mackall <mpm@selenic.com>
parents: 20990
diff changeset
541 if dst in exclude:
722117c8e023 duplicatecopies: move from cmdutil to copies
Matt Mackall <mpm@selenic.com>
parents: 20990
diff changeset
542 continue
722117c8e023 duplicatecopies: move from cmdutil to copies
Matt Mackall <mpm@selenic.com>
parents: 20990
diff changeset
543 if repo.dirstate[dst] in "nma":
722117c8e023 duplicatecopies: move from cmdutil to copies
Matt Mackall <mpm@selenic.com>
parents: 20990
diff changeset
544 repo.dirstate.copy(src, dst)