Show More
@@ -0,0 +1,65 b'' | |||
|
1 | # filemerge.py - file-level merge handling for Mercurial | |
|
2 | # | |
|
3 | # Copyright 2006, 2007, 2008 Matt Mackall <mpm@selenic.com> | |
|
4 | # | |
|
5 | # This software may be used and distributed according to the terms | |
|
6 | # of the GNU General Public License, incorporated herein by reference. | |
|
7 | ||
|
8 | from node import * | |
|
9 | from i18n import _ | |
|
10 | import util, os, tempfile, context | |
|
11 | ||
|
12 | def filemerge(repo, fw, fd, fo, wctx, mctx): | |
|
13 | """perform a 3-way merge in the working directory | |
|
14 | ||
|
15 | fw = original filename in the working directory | |
|
16 | fd = destination filename in the working directory | |
|
17 | fo = filename in other parent | |
|
18 | wctx, mctx = working and merge changecontexts | |
|
19 | """ | |
|
20 | ||
|
21 | def temp(prefix, ctx): | |
|
22 | pre = "%s~%s." % (os.path.basename(ctx.path()), prefix) | |
|
23 | (fd, name) = tempfile.mkstemp(prefix=pre) | |
|
24 | data = repo.wwritedata(ctx.path(), ctx.data()) | |
|
25 | f = os.fdopen(fd, "wb") | |
|
26 | f.write(data) | |
|
27 | f.close() | |
|
28 | return name | |
|
29 | ||
|
30 | fcm = wctx.filectx(fw) | |
|
31 | fcmdata = wctx.filectx(fd).data() | |
|
32 | fco = mctx.filectx(fo) | |
|
33 | ||
|
34 | if not fco.cmp(fcmdata): # files identical? | |
|
35 | return None | |
|
36 | ||
|
37 | fca = fcm.ancestor(fco) | |
|
38 | if not fca: | |
|
39 | fca = repo.filectx(fw, fileid=nullrev) | |
|
40 | a = repo.wjoin(fd) | |
|
41 | b = temp("base", fca) | |
|
42 | c = temp("other", fco) | |
|
43 | ||
|
44 | if fw != fo: | |
|
45 | repo.ui.status(_("merging %s and %s\n") % (fw, fo)) | |
|
46 | else: | |
|
47 | repo.ui.status(_("merging %s\n") % fw) | |
|
48 | ||
|
49 | repo.ui.debug(_("my %s other %s ancestor %s\n") % (fcm, fco, fca)) | |
|
50 | ||
|
51 | cmd = (os.environ.get("HGMERGE") or repo.ui.config("ui", "merge") | |
|
52 | or "hgmerge") | |
|
53 | r = util.system('%s "%s" "%s" "%s"' % (cmd, a, b, c), cwd=repo.root, | |
|
54 | environ={'HG_FILE': fd, | |
|
55 | 'HG_MY_NODE': str(wctx.parents()[0]), | |
|
56 | 'HG_OTHER_NODE': str(mctx), | |
|
57 | 'HG_MY_ISLINK': fcm.islink(), | |
|
58 | 'HG_OTHER_ISLINK': fco.islink(), | |
|
59 | 'HG_BASE_ISLINK': fca.islink(),}) | |
|
60 | if r: | |
|
61 | repo.ui.warn(_("merging %s failed!\n") % fd) | |
|
62 | ||
|
63 | os.unlink(b) | |
|
64 | os.unlink(c) | |
|
65 | return r |
@@ -7,7 +7,8 b' imerge - interactive merge' | |||
|
7 | 7 | |
|
8 | 8 | from mercurial.i18n import _ |
|
9 | 9 | from mercurial.node import * |
|
10 |
from mercurial import commands, cmdutil, dispatch, fancyopts |
|
|
10 | from mercurial import commands, cmdutil, dispatch, fancyopts | |
|
11 | from mercurial import hg, filemerge, util | |
|
11 | 12 | import os, tarfile |
|
12 | 13 | |
|
13 | 14 | class InvalidStateFileException(Exception): pass |
@@ -126,7 +127,7 b' class Imerge(object):' | |||
|
126 | 127 | self.wctx._parents.pop() |
|
127 | 128 | try: |
|
128 | 129 | # TODO: we should probably revert the file if merge fails |
|
129 | return merge.filemerge(self.repo, fn, fd, fo, self.wctx, p2) | |
|
130 | return filemerge.filemerge(self.repo, fn, fd, fo, self.wctx, p2) | |
|
130 | 131 | finally: |
|
131 | 132 | self.wctx._parents.append(p2) |
|
132 | 133 | if realmerge: |
@@ -135,13 +136,13 b' class Imerge(object):' | |||
|
135 | 136 | del os.environ['HGMERGE'] |
|
136 | 137 | |
|
137 | 138 | def start(self, rev=None): |
|
138 | _filemerge = merge.filemerge | |
|
139 | def filemerge(repo, fw, fd, fo, wctx, mctx): | |
|
139 | _filemerge = filemerge.filemerge | |
|
140 | def filemerge_(repo, fw, fd, fo, wctx, mctx): | |
|
140 | 141 | self.conflicts[fw] = (fd, fo) |
|
141 | 142 | |
|
142 | merge.filemerge = filemerge | |
|
143 | filemerge.filemerge = filemerge_ | |
|
143 | 144 | commands.merge(self.ui, self.repo, rev=rev) |
|
144 | merge.filemerge = _filemerge | |
|
145 | filemerge.filemerge = _filemerge | |
|
145 | 146 | |
|
146 | 147 | self.wctx = self.repo.workingctx() |
|
147 | 148 | self.save() |
@@ -7,62 +7,7 b'' | |||
|
7 | 7 | |
|
8 | 8 | from node import * |
|
9 | 9 | from i18n import _ |
|
10 |
import errno, util, os, |
|
|
11 | ||
|
12 | def filemerge(repo, fw, fd, fo, wctx, mctx): | |
|
13 | """perform a 3-way merge in the working directory | |
|
14 | ||
|
15 | fw = original filename in the working directory | |
|
16 | fd = destination filename in the working directory | |
|
17 | fo = filename in other parent | |
|
18 | wctx, mctx = working and merge changecontexts | |
|
19 | """ | |
|
20 | ||
|
21 | def temp(prefix, ctx): | |
|
22 | pre = "%s~%s." % (os.path.basename(ctx.path()), prefix) | |
|
23 | (fd, name) = tempfile.mkstemp(prefix=pre) | |
|
24 | data = repo.wwritedata(ctx.path(), ctx.data()) | |
|
25 | f = os.fdopen(fd, "wb") | |
|
26 | f.write(data) | |
|
27 | f.close() | |
|
28 | return name | |
|
29 | ||
|
30 | fcm = wctx.filectx(fw) | |
|
31 | fcmdata = wctx.filectx(fd).data() | |
|
32 | fco = mctx.filectx(fo) | |
|
33 | ||
|
34 | if not fco.cmp(fcmdata): # files identical? | |
|
35 | return None | |
|
36 | ||
|
37 | fca = fcm.ancestor(fco) | |
|
38 | if not fca: | |
|
39 | fca = repo.filectx(fw, fileid=nullrev) | |
|
40 | a = repo.wjoin(fd) | |
|
41 | b = temp("base", fca) | |
|
42 | c = temp("other", fco) | |
|
43 | ||
|
44 | if fw != fo: | |
|
45 | repo.ui.status(_("merging %s and %s\n") % (fw, fo)) | |
|
46 | else: | |
|
47 | repo.ui.status(_("merging %s\n") % fw) | |
|
48 | ||
|
49 | repo.ui.debug(_("my %s other %s ancestor %s\n") % (fcm, fco, fca)) | |
|
50 | ||
|
51 | cmd = (os.environ.get("HGMERGE") or repo.ui.config("ui", "merge") | |
|
52 | or "hgmerge") | |
|
53 | r = util.system('%s "%s" "%s" "%s"' % (cmd, a, b, c), cwd=repo.root, | |
|
54 | environ={'HG_FILE': fd, | |
|
55 | 'HG_MY_NODE': str(wctx.parents()[0]), | |
|
56 | 'HG_OTHER_NODE': str(mctx), | |
|
57 | 'HG_MY_ISLINK': fcm.islink(), | |
|
58 | 'HG_OTHER_ISLINK': fco.islink(), | |
|
59 | 'HG_BASE_ISLINK': fca.islink(),}) | |
|
60 | if r: | |
|
61 | repo.ui.warn(_("merging %s failed!\n") % fd) | |
|
62 | ||
|
63 | os.unlink(b) | |
|
64 | os.unlink(c) | |
|
65 | return r | |
|
10 | import errno, util, os, heapq, filemerge | |
|
66 | 11 | |
|
67 | 12 | def checkunknown(wctx, mctx): |
|
68 | 13 | "check for collisions between unknown files and files in mctx" |
@@ -514,7 +459,7 b' def applyupdates(repo, action, wctx, mct' | |||
|
514 | 459 | removed += 1 |
|
515 | 460 | elif m == "m": # merge |
|
516 | 461 | f2, fd, flags, move = a[2:] |
|
517 | r = filemerge(repo, f, fd, f2, wctx, mctx) | |
|
462 | r = filemerge.filemerge(repo, f, fd, f2, wctx, mctx) | |
|
518 | 463 | if r > 0: |
|
519 | 464 | unresolved += 1 |
|
520 | 465 | else: |
General Comments 0
You need to be logged in to leave comments.
Login now