##// END OF EJS Templates
merge: fix a copy detection bug (issue672)...
Alexis S. L. Carvalho -
r5096:ad6b9713 default
parent child Browse files
Show More
@@ -0,0 +1,35 b''
1 #!/bin/sh
2
3 # 0-2-4
4 # \ \ \
5 # 1-3-5
6 #
7 # rename in #1, content change in #4.
8
9 hg init t
10 cd t
11
12 touch 1
13 touch 2
14 hg commit -Am init -d "0 0" # 0
15
16 hg rename 1 1a
17 hg commit -m rename -d "0 0" # 1
18
19 hg co -C 0
20 echo unrelated >> 2
21 hg ci -m unrelated1 -d "0 0" # 2
22
23 hg merge --debug 1
24 hg ci -m merge1 -d "0 0" # 3
25
26 hg co -C 2
27 echo hello >> 1
28 hg ci -m unrelated2 -d "0 0" # 4
29
30 hg co -C 3
31 hg merge -y --debug 4
32
33 hg co -C 4
34 hg merge -y --debug 3
35
@@ -0,0 +1,33 b''
1 adding 1
2 adding 2
3 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
4 resolving manifests
5 overwrite None partial False
6 ancestor 81f4b099af3d local c64f439569a9+ remote 2f8037f47a5c
7 1: other deleted -> r
8 1a: remote created -> g
9 removing 1
10 getting 1a
11 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
12 (branch merge, don't forget to commit)
13 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
14 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
15 resolving manifests
16 overwrite None partial False
17 ancestor c64f439569a9 local ac7575e3c052+ remote 746e9549ea96
18 1a: local moved to 1 -> m
19 merging 1a and 1
20 my 1a@ac7575e3c052+ other 1@746e9549ea96 ancestor 1@81f4b099af3d
21 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
22 (branch merge, don't forget to commit)
23 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
24 resolving manifests
25 overwrite None partial False
26 ancestor c64f439569a9 local 746e9549ea96+ remote ac7575e3c052
27 1: remote moved to 1a -> m
28 copying 1 to 1a
29 merging 1 and 1a
30 my 1@746e9549ea96+ other 1a@2f8037f47a5c ancestor 1@81f4b099af3d
31 removing 1
32 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
33 (branch merge, don't forget to commit)
@@ -7,7 +7,7 b''
7
7
8 from node import *
8 from node import *
9 from i18n import _
9 from i18n import _
10 import errno, util, os, tempfile, context
10 import errno, util, os, tempfile, context, heapq
11
11
12 def filemerge(repo, fw, fd, fo, wctx, mctx):
12 def filemerge(repo, fw, fd, fo, wctx, mctx):
13 """perform a 3-way merge in the working directory
13 """perform a 3-way merge in the working directory
@@ -252,6 +252,58 b' def findcopies(repo, m1, m2, ma, limit):'
252
252
253 return copy, diverge
253 return copy, diverge
254
254
255 def symmetricdifference(repo, rev1, rev2):
256 """symmetric difference of the sets of ancestors of rev1 and rev2
257
258 I.e. revisions that are ancestors of rev1 or rev2, but not both.
259 """
260 # basic idea:
261 # - mark rev1 and rev2 with different colors
262 # - walk the graph in topological order with the help of a heap;
263 # for each revision r:
264 # - if r has only one color, we want to return it
265 # - add colors[r] to its parents
266 #
267 # We keep track of the number of revisions in the heap that
268 # we may be interested in. We stop walking the graph as soon
269 # as this number reaches 0.
270 WHITE = 1
271 BLACK = 2
272 ALLCOLORS = WHITE | BLACK
273 colors = {rev1: WHITE, rev2: BLACK}
274
275 cl = repo.changelog
276
277 visit = [-rev1, -rev2]
278 heapq.heapify(visit)
279 n_wanted = len(visit)
280 ret = []
281
282 while n_wanted:
283 r = -heapq.heappop(visit)
284 wanted = colors[r] != ALLCOLORS
285 n_wanted -= wanted
286 if wanted:
287 ret.append(r)
288
289 for p in cl.parentrevs(r):
290 if p == nullrev:
291 continue
292 if p not in colors:
293 # first time we see p; add it to visit
294 n_wanted += wanted
295 colors[p] = colors[r]
296 heapq.heappush(visit, -p)
297 elif colors[p] != ALLCOLORS and colors[p] != colors[r]:
298 # at first we thought we wanted p, but now
299 # we know we don't really want it
300 n_wanted -= 1
301 colors[p] |= colors[r]
302
303 del colors[r]
304
305 return ret
306
255 def manifestmerge(repo, p1, p2, pa, overwrite, partial):
307 def manifestmerge(repo, p1, p2, pa, overwrite, partial):
256 """
308 """
257 Merge p1 and p2 with ancestor ma and generate merge action list
309 Merge p1 and p2 with ancestor ma and generate merge action list
@@ -290,7 +342,12 b' def manifestmerge(repo, p1, p2, pa, over'
290 action.append((f, m) + args)
342 action.append((f, m) + args)
291
343
292 if not (backwards or overwrite):
344 if not (backwards or overwrite):
293 copy, diverge = findcopies(repo, m1, m2, ma, pa.rev())
345 rev1 = p1.rev()
346 if rev1 is None:
347 # p1 is a workingctx
348 rev1 = p1.parents()[0].rev()
349 limit = min(symmetricdifference(repo, rev1, p2.rev()))
350 copy, diverge = findcopies(repo, m1, m2, ma, limit)
294
351
295 for of, fl in diverge.items():
352 for of, fl in diverge.items():
296 act("divergent renames", "dr", of, fl)
353 act("divergent renames", "dr", of, fl)
General Comments 0
You need to be logged in to leave comments. Login now