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 |
11 |
11 |
12 def filemerge(repo, fw, 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 |
14 |
14 |
15 fw = filename in the working directory |
15 fw = original filename in the working directory |
|
16 fd = destination filename in the working directory |
16 fo = filename in other parent |
17 fo = filename in other parent |
17 wctx, mctx = working and merge changecontexts |
18 wctx, mctx = working and merge changecontexts |
18 """ |
19 """ |
19 |
20 |
20 def temp(prefix, ctx): |
21 def temp(prefix, ctx): |
25 f.write(data) |
26 f.write(data) |
26 f.close() |
27 f.close() |
27 return name |
28 return name |
28 |
29 |
29 fcm = wctx.filectx(fw) |
30 fcm = wctx.filectx(fw) |
|
31 fcmdata = wctx.filectx(fd).data() |
30 fco = mctx.filectx(fo) |
32 fco = mctx.filectx(fo) |
31 |
33 |
32 if not fco.cmp(fcm.data()): # files identical? |
34 if not fco.cmp(fcmdata): # files identical? |
33 return None |
35 return None |
34 |
36 |
35 fca = fcm.ancestor(fco) |
37 fca = fcm.ancestor(fco) |
36 if not fca: |
38 if not fca: |
37 fca = repo.filectx(fw, fileid=nullrev) |
39 fca = repo.filectx(fw, fileid=nullrev) |
38 a = repo.wjoin(fw) |
40 a = repo.wjoin(fd) |
39 b = temp("base", fca) |
41 b = temp("base", fca) |
40 c = temp("other", fco) |
42 c = temp("other", fco) |
41 |
43 |
42 if fw != fo: |
44 if fw != fo: |
43 repo.ui.status(_("merging %s and %s\n") % (fw, fo)) |
45 repo.ui.status(_("merging %s and %s\n") % (fw, fo)) |
47 repo.ui.debug(_("my %s other %s ancestor %s\n") % (fcm, fco, fca)) |
49 repo.ui.debug(_("my %s other %s ancestor %s\n") % (fcm, fco, fca)) |
48 |
50 |
49 cmd = (os.environ.get("HGMERGE") or repo.ui.config("ui", "merge") |
51 cmd = (os.environ.get("HGMERGE") or repo.ui.config("ui", "merge") |
50 or "hgmerge") |
52 or "hgmerge") |
51 r = util.system('%s "%s" "%s" "%s"' % (cmd, a, b, c), cwd=repo.root, |
53 r = util.system('%s "%s" "%s" "%s"' % (cmd, a, b, c), cwd=repo.root, |
52 environ={'HG_FILE': fw, |
54 environ={'HG_FILE': fd, |
53 'HG_MY_NODE': str(wctx.parents()[0]), |
55 'HG_MY_NODE': str(wctx.parents()[0]), |
54 'HG_OTHER_NODE': str(mctx)}) |
56 'HG_OTHER_NODE': str(mctx)}) |
55 if r: |
57 if r: |
56 repo.ui.warn(_("merging %s failed!\n") % fw) |
58 repo.ui.warn(_("merging %s failed!\n") % fd) |
57 |
59 |
58 os.unlink(b) |
60 os.unlink(b) |
59 os.unlink(c) |
61 os.unlink(c) |
60 return r |
62 return r |
61 |
63 |
378 def applyupdates(repo, action, wctx, mctx): |
380 def applyupdates(repo, action, wctx, mctx): |
379 "apply the merge action list to the working directory" |
381 "apply the merge action list to the working directory" |
380 |
382 |
381 updated, merged, removed, unresolved = 0, 0, 0, 0 |
383 updated, merged, removed, unresolved = 0, 0, 0, 0 |
382 action.sort() |
384 action.sort() |
|
385 # prescan for copy/renames |
|
386 for a in action: |
|
387 f, m = a[:2] |
|
388 if m == 'm': # merge |
|
389 f2, fd, flags, move = a[2:] |
|
390 if f != fd: |
|
391 repo.ui.debug(_("copying %s to %s\n") % (f, fd)) |
|
392 repo.wwrite(fd, repo.wread(f), flags) |
|
393 |
383 for a in action: |
394 for a in action: |
384 f, m = a[:2] |
395 f, m = a[:2] |
385 if f and f[0] == "/": |
396 if f and f[0] == "/": |
386 continue |
397 continue |
387 if m == "r": # remove |
398 if m == "r": # remove |
394 repo.ui.warn(_("update failed to remove %s: %s!\n") % |
405 repo.ui.warn(_("update failed to remove %s: %s!\n") % |
395 (f, inst.strerror)) |
406 (f, inst.strerror)) |
396 removed += 1 |
407 removed += 1 |
397 elif m == "m": # merge |
408 elif m == "m": # merge |
398 f2, fd, flags, move = a[2:] |
409 f2, fd, flags, move = a[2:] |
399 r = filemerge(repo, f, f2, wctx, mctx) |
410 r = filemerge(repo, f, fd, f2, wctx, mctx) |
400 if r > 0: |
411 if r > 0: |
401 unresolved += 1 |
412 unresolved += 1 |
402 else: |
413 else: |
403 if r is None: |
414 if r is None: |
404 updated += 1 |
415 updated += 1 |
405 else: |
416 else: |
406 merged += 1 |
417 merged += 1 |
407 if f != fd: |
418 if f != fd and move: |
408 repo.ui.debug(_("copying %s to %s\n") % (f, fd)) |
419 repo.ui.debug(_("removing %s\n") % f) |
409 repo.wwrite(fd, repo.wread(f), flags) |
420 os.unlink(repo.wjoin(f)) |
410 if move: |
|
411 repo.ui.debug(_("removing %s\n") % f) |
|
412 os.unlink(repo.wjoin(f)) |
|
413 util.set_exec(repo.wjoin(fd), "x" in flags) |
421 util.set_exec(repo.wjoin(fd), "x" in flags) |
414 elif m == "g": # get |
422 elif m == "g": # get |
415 flags = a[2] |
423 flags = a[2] |
416 repo.ui.note(_("getting %s\n") % f) |
424 repo.ui.note(_("getting %s\n") % f) |
417 t = mctx.filectx(f).data() |
425 t = mctx.filectx(f).data() |