##// END OF EJS Templates
Add core copy detection algorithm...
Matt Mackall -
r3153:c82ea81d default
parent child Browse files
Show More
@@ -0,0 +1,23 b''
1 #!/bin/sh
2
3 mkdir t
4 cd t
5 hg init
6 echo foo > a
7 echo foo > a2
8 hg add a a2
9 hg ci -m "start" -d "0 0"
10 hg mv a b
11 hg mv a2 b2
12 hg ci -m "rename" -d "0 0"
13 echo "checkout"
14 hg co 0
15 echo blahblah > a
16 echo blahblah > a2
17 hg mv a2 c2
18 hg ci -m "modify" -d "0 0"
19 echo "merge"
20 hg merge -y --debug
21 cat a
22 cat b
23 hg ci -m "merge" -d "0 0"
@@ -0,0 +1,14 b''
1 checkout
2 2 files updated, 0 files merged, 2 files removed, 0 files unresolved
3 merge
4 resolving manifests
5 overwrite None branchmerge True partial False
6 ancestor f26ec4fc3fa3 local 8e765a822af2 remote af1939970a1c
7 b: remote created -> g
8 b2: remote created -> g
9 getting b
10 getting b2
11 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
12 (branch merge, don't forget to commit)
13 blahblah
14 foo
@@ -94,6 +94,77 b' def forgetremoved(m2, status):'
94
94
95 return action
95 return action
96
96
97 def nonoverlap(d1, d2):
98 """
99 Return list of elements in d1 not in d2
100 """
101
102 l = []
103 for d in d1:
104 if d not in d2:
105 l.append(d)
106
107 l.sort()
108 return l
109
110 def findold(fctx, limit):
111 """
112 find files that path was copied from, back to linkrev limit
113 """
114
115 old = {}
116 orig = fctx.path()
117 visit = [fctx]
118 while visit:
119 fc = visit.pop()
120 if fc.rev() < limit:
121 continue
122 if fc.path() != orig and fc.path() not in old:
123 old[fc.path()] = 1
124 visit += fc.parents()
125
126 old = old.keys()
127 old.sort()
128 return old
129
130 def findcopies(repo, m1, m2, limit):
131 """
132 Find moves and copies between m1 and m2 back to limit linkrev
133 """
134
135 copy = {}
136 match = {}
137 u1 = nonoverlap(m1, m2)
138 u2 = nonoverlap(m2, m1)
139 ctx = util.cachefunc(lambda f,n: repo.filectx(f, fileid=n[:20]))
140
141 def checkpair(c, f2, man):
142 ''' check if an apparent pair actually matches '''
143 c2 = ctx(f2, man[f2])
144 ca = c.ancestor(c2)
145 if ca:
146 copy[c.path()] = f2
147 copy[f2] = c.path()
148
149 for f in u1:
150 c = ctx(f, m1[f])
151 for of in findold(c, limit):
152 if of in m2:
153 checkpair(c, of, m2)
154 else:
155 match.setdefault(of, []).append(f)
156
157 for f in u2:
158 c = ctx(f, m2[f])
159 for of in findold(c, limit):
160 if of in m1:
161 checkpair(c, of, m1)
162 elif of in match:
163 for mf in match[of]:
164 checkpair(c, mf, m1)
165
166 return copy
167
97 def manifestmerge(ui, m1, m2, ma, overwrite, backwards, partial):
168 def manifestmerge(ui, m1, m2, ma, overwrite, backwards, partial):
98 """
169 """
99 Merge manifest m1 with m2 using ancestor ma and generate merge action list
170 Merge manifest m1 with m2 using ancestor ma and generate merge action list
@@ -289,6 +360,11 b' def update(repo, node, branchmerge=False'
289 checkunknown(repo, m2, status)
360 checkunknown(repo, m2, status)
290 if not branchmerge:
361 if not branchmerge:
291 action += forgetremoved(m2, status)
362 action += forgetremoved(m2, status)
363
364 copy = {}
365 if not (backwards or overwrite):
366 copy = findcopies(repo, m1, m2, repo.changelog.rev(pa))
367
292 action += manifestmerge(repo.ui, m1, m2, ma, overwrite, backwards, partial)
368 action += manifestmerge(repo.ui, m1, m2, ma, overwrite, backwards, partial)
293 del m1, m2, ma
369 del m1, m2, ma
294
370
General Comments 0
You need to be logged in to leave comments. Login now