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 | 8 | from node import * |
|
9 | 9 | from i18n import _ |
|
10 | import errno, util, os, tempfile, context | |
|
10 | import errno, util, os, tempfile, context, heapq | |
|
11 | 11 | |
|
12 | 12 | def filemerge(repo, fw, fd, fo, wctx, mctx): |
|
13 | 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 | 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 | 307 | def manifestmerge(repo, p1, p2, pa, overwrite, partial): |
|
256 | 308 | """ |
|
257 | 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 | 342 | action.append((f, m) + args) |
|
291 | 343 | |
|
292 | 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 | 352 | for of, fl in diverge.items(): |
|
296 | 353 | act("divergent renames", "dr", of, fl) |
General Comments 0
You need to be logged in to leave comments.
Login now