Mercurial > public > mercurial-scm > hg-stable
annotate mercurial/filemerge.py @ 9709:5858117a0077
merge: supply base node to merge tools in the environment
Merge tools will be able to exploit this to correctly merge backouts.
This won't work fully, though, until issue 1327 is solved, since the
node information is not necessarily correct.
author | Sune Foldager <cryo@cyanite.org> |
---|---|
date | Wed, 04 Nov 2009 15:18:19 +0100 |
parents | 4c041f1ee1b4 |
children | 25e572394f5c |
rev | line source |
---|---|
6003
7855b88ba838
filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
1 # filemerge.py - file-level merge handling for Mercurial |
7855b88ba838
filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
2 # |
7855b88ba838
filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
3 # Copyright 2006, 2007, 2008 Matt Mackall <mpm@selenic.com> |
7855b88ba838
filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
4 # |
8225
46293a0c7e9f
updated license to be explicit about GPL version 2
Martin Geisler <mg@lazybytes.net>
parents:
8209
diff
changeset
|
5 # This software may be used and distributed according to the terms of the |
46293a0c7e9f
updated license to be explicit about GPL version 2
Martin Geisler <mg@lazybytes.net>
parents:
8209
diff
changeset
|
6 # GNU General Public License version 2, incorporated herein by reference. |
6003
7855b88ba838
filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
7 |
7873
4a4c7f6a5912
cleanup: drop unused imports
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents:
7397
diff
changeset
|
8 from node import short |
6003
7855b88ba838
filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
9 from i18n import _ |
8566
744d6322b05b
match: change all users of util.matcher to match.match
Matt Mackall <mpm@selenic.com>
parents:
8312
diff
changeset
|
10 import util, simplemerge, match |
8312
b87a50b7125c
separate import lines from mercurial and general python modules
Simon Heimberg <simohe@besonet.ch>
parents:
8269
diff
changeset
|
11 import os, tempfile, re, filecmp |
6004
5af5f0f9d724
merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents:
6003
diff
changeset
|
12 |
6013
bb441d77df99
filemerge: handle missing regappend
Matt Mackall <mpm@selenic.com>
parents:
6007
diff
changeset
|
13 def _toolstr(ui, tool, part, default=""): |
6004
5af5f0f9d724
merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents:
6003
diff
changeset
|
14 return ui.config("merge-tools", tool + "." + part, default) |
5af5f0f9d724
merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents:
6003
diff
changeset
|
15 |
5af5f0f9d724
merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents:
6003
diff
changeset
|
16 def _toolbool(ui, tool, part, default=False): |
5af5f0f9d724
merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents:
6003
diff
changeset
|
17 return ui.configbool("merge-tools", tool + "." + part, default) |
5af5f0f9d724
merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents:
6003
diff
changeset
|
18 |
8831
91e26fb24fb1
filemerge: add internal:dump
Matt Mackall <mpm@selenic.com>
parents:
8830
diff
changeset
|
19 _internal = ['internal:' + s |
91e26fb24fb1
filemerge: add internal:dump
Matt Mackall <mpm@selenic.com>
parents:
8830
diff
changeset
|
20 for s in 'fail local other merge prompt dump'.split()] |
8830
a9850eda2973
filemerge: add internal:prompt target
Matt Mackall <mpm@selenic.com>
parents:
8615
diff
changeset
|
21 |
6004
5af5f0f9d724
merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents:
6003
diff
changeset
|
22 def _findtool(ui, tool): |
8830
a9850eda2973
filemerge: add internal:prompt target
Matt Mackall <mpm@selenic.com>
parents:
8615
diff
changeset
|
23 if tool in _internal: |
6522
2b181fb3a70a
use internal merge tool when specified for a merge-pattern in hgrc
Dov Feldstern <dfeldstern@fastimap.com>
parents:
6212
diff
changeset
|
24 return tool |
6006
3c9dbb743d20
merge: add registry look up bits to tool search
Matt Mackall <mpm@selenic.com>
parents:
6005
diff
changeset
|
25 k = _toolstr(ui, tool, "regkey") |
3c9dbb743d20
merge: add registry look up bits to tool search
Matt Mackall <mpm@selenic.com>
parents:
6005
diff
changeset
|
26 if k: |
3c9dbb743d20
merge: add registry look up bits to tool search
Matt Mackall <mpm@selenic.com>
parents:
6005
diff
changeset
|
27 p = util.lookup_reg(k, _toolstr(ui, tool, "regname")) |
3c9dbb743d20
merge: add registry look up bits to tool search
Matt Mackall <mpm@selenic.com>
parents:
6005
diff
changeset
|
28 if p: |
3c9dbb743d20
merge: add registry look up bits to tool search
Matt Mackall <mpm@selenic.com>
parents:
6005
diff
changeset
|
29 p = util.find_exe(p + _toolstr(ui, tool, "regappend")) |
3c9dbb743d20
merge: add registry look up bits to tool search
Matt Mackall <mpm@selenic.com>
parents:
6005
diff
changeset
|
30 if p: |
3c9dbb743d20
merge: add registry look up bits to tool search
Matt Mackall <mpm@selenic.com>
parents:
6005
diff
changeset
|
31 return p |
6004
5af5f0f9d724
merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents:
6003
diff
changeset
|
32 return util.find_exe(_toolstr(ui, tool, "executable", tool)) |
5af5f0f9d724
merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents:
6003
diff
changeset
|
33 |
5af5f0f9d724
merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents:
6003
diff
changeset
|
34 def _picktool(repo, ui, path, binary, symlink): |
5af5f0f9d724
merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents:
6003
diff
changeset
|
35 def check(tool, pat, symlink, binary): |
5af5f0f9d724
merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents:
6003
diff
changeset
|
36 tmsg = tool |
5af5f0f9d724
merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents:
6003
diff
changeset
|
37 if pat: |
5af5f0f9d724
merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents:
6003
diff
changeset
|
38 tmsg += " specified for " + pat |
7397
4c92d8971809
More verbose logging when filemerge searches for merge-tool
Mads Kiilerich <mads@kiilerich.com>
parents:
6762
diff
changeset
|
39 if not _findtool(ui, tool): |
4c92d8971809
More verbose logging when filemerge searches for merge-tool
Mads Kiilerich <mads@kiilerich.com>
parents:
6762
diff
changeset
|
40 if pat: # explicitly requested tool deserves a warning |
4c92d8971809
More verbose logging when filemerge searches for merge-tool
Mads Kiilerich <mads@kiilerich.com>
parents:
6762
diff
changeset
|
41 ui.warn(_("couldn't find merge tool %s\n") % tmsg) |
4c92d8971809
More verbose logging when filemerge searches for merge-tool
Mads Kiilerich <mads@kiilerich.com>
parents:
6762
diff
changeset
|
42 else: # configured but non-existing tools are more silent |
4c92d8971809
More verbose logging when filemerge searches for merge-tool
Mads Kiilerich <mads@kiilerich.com>
parents:
6762
diff
changeset
|
43 ui.note(_("couldn't find merge tool %s\n") % tmsg) |
6004
5af5f0f9d724
merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents:
6003
diff
changeset
|
44 elif symlink and not _toolbool(ui, tool, "symlink"): |
5af5f0f9d724
merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents:
6003
diff
changeset
|
45 ui.warn(_("tool %s can't handle symlinks\n") % tmsg) |
5af5f0f9d724
merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents:
6003
diff
changeset
|
46 elif binary and not _toolbool(ui, tool, "binary"): |
5af5f0f9d724
merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents:
6003
diff
changeset
|
47 ui.warn(_("tool %s can't handle binary\n") % tmsg) |
6007
090b1a665901
filemerge: add config item for GUI tools
Matt Mackall <mpm@selenic.com>
parents:
6006
diff
changeset
|
48 elif not util.gui() and _toolbool(ui, tool, "gui"): |
090b1a665901
filemerge: add config item for GUI tools
Matt Mackall <mpm@selenic.com>
parents:
6006
diff
changeset
|
49 ui.warn(_("tool %s requires a GUI\n") % tmsg) |
6004
5af5f0f9d724
merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents:
6003
diff
changeset
|
50 else: |
5af5f0f9d724
merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents:
6003
diff
changeset
|
51 return True |
5af5f0f9d724
merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents:
6003
diff
changeset
|
52 return False |
5af5f0f9d724
merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents:
6003
diff
changeset
|
53 |
5af5f0f9d724
merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents:
6003
diff
changeset
|
54 # HGMERGE takes precedence |
6025
f2335246e5c7
filemerge: wrap quotes around tool path
Steve Borho <steve@borho.org>
parents:
6016
diff
changeset
|
55 hgmerge = os.environ.get("HGMERGE") |
f2335246e5c7
filemerge: wrap quotes around tool path
Steve Borho <steve@borho.org>
parents:
6016
diff
changeset
|
56 if hgmerge: |
f2335246e5c7
filemerge: wrap quotes around tool path
Steve Borho <steve@borho.org>
parents:
6016
diff
changeset
|
57 return (hgmerge, hgmerge) |
6004
5af5f0f9d724
merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents:
6003
diff
changeset
|
58 |
5af5f0f9d724
merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents:
6003
diff
changeset
|
59 # then patterns |
6016
288ec2f6faa2
filemerge: fix pattern matching
dhruva <dhruvakm@gmail.com>
parents:
6015
diff
changeset
|
60 for pat, tool in ui.configitems("merge-patterns"): |
8567
fea40a677d43
match: add some default args
Matt Mackall <mpm@selenic.com>
parents:
8566
diff
changeset
|
61 mf = match.match(repo.root, '', [pat]) |
6004
5af5f0f9d724
merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents:
6003
diff
changeset
|
62 if mf(path) and check(tool, pat, symlink, False): |
6025
f2335246e5c7
filemerge: wrap quotes around tool path
Steve Borho <steve@borho.org>
parents:
6016
diff
changeset
|
63 toolpath = _findtool(ui, tool) |
f2335246e5c7
filemerge: wrap quotes around tool path
Steve Borho <steve@borho.org>
parents:
6016
diff
changeset
|
64 return (tool, '"' + toolpath + '"') |
6004
5af5f0f9d724
merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents:
6003
diff
changeset
|
65 |
5af5f0f9d724
merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents:
6003
diff
changeset
|
66 # then merge tools |
5af5f0f9d724
merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents:
6003
diff
changeset
|
67 tools = {} |
5af5f0f9d724
merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents:
6003
diff
changeset
|
68 for k,v in ui.configitems("merge-tools"): |
5af5f0f9d724
merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents:
6003
diff
changeset
|
69 t = k.split('.')[0] |
5af5f0f9d724
merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents:
6003
diff
changeset
|
70 if t not in tools: |
5af5f0f9d724
merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents:
6003
diff
changeset
|
71 tools[t] = int(_toolstr(ui, t, "priority", "0")) |
6076
0ee885fea464
filemerge: more backwards compatible behavior for ui.merge
Steve Borho <steve@borho.org>
parents:
6075
diff
changeset
|
72 names = tools.keys() |
8209
a1a5a57efe90
replace util.sort with sorted built-in
Matt Mackall <mpm@selenic.com>
parents:
7873
diff
changeset
|
73 tools = sorted([(-p,t) for t,p in tools.items()]) |
6076
0ee885fea464
filemerge: more backwards compatible behavior for ui.merge
Steve Borho <steve@borho.org>
parents:
6075
diff
changeset
|
74 uimerge = ui.config("ui", "merge") |
0ee885fea464
filemerge: more backwards compatible behavior for ui.merge
Steve Borho <steve@borho.org>
parents:
6075
diff
changeset
|
75 if uimerge: |
0ee885fea464
filemerge: more backwards compatible behavior for ui.merge
Steve Borho <steve@borho.org>
parents:
6075
diff
changeset
|
76 if uimerge not in names: |
0ee885fea464
filemerge: more backwards compatible behavior for ui.merge
Steve Borho <steve@borho.org>
parents:
6075
diff
changeset
|
77 return (uimerge, uimerge) |
0ee885fea464
filemerge: more backwards compatible behavior for ui.merge
Steve Borho <steve@borho.org>
parents:
6075
diff
changeset
|
78 tools.insert(0, (None, uimerge)) # highest priority |
6004
5af5f0f9d724
merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents:
6003
diff
changeset
|
79 tools.append((None, "hgmerge")) # the old default, if found |
5af5f0f9d724
merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents:
6003
diff
changeset
|
80 for p,t in tools: |
7397
4c92d8971809
More verbose logging when filemerge searches for merge-tool
Mads Kiilerich <mads@kiilerich.com>
parents:
6762
diff
changeset
|
81 if check(t, None, symlink, binary): |
4c92d8971809
More verbose logging when filemerge searches for merge-tool
Mads Kiilerich <mads@kiilerich.com>
parents:
6762
diff
changeset
|
82 toolpath = _findtool(ui, t) |
6025
f2335246e5c7
filemerge: wrap quotes around tool path
Steve Borho <steve@borho.org>
parents:
6016
diff
changeset
|
83 return (t, '"' + toolpath + '"') |
f2335246e5c7
filemerge: wrap quotes around tool path
Steve Borho <steve@borho.org>
parents:
6016
diff
changeset
|
84 # internal merge as last resort |
f2335246e5c7
filemerge: wrap quotes around tool path
Steve Borho <steve@borho.org>
parents:
6016
diff
changeset
|
85 return (not (symlink or binary) and "internal:merge" or None, None) |
6003
7855b88ba838
filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
86 |
6005
3c33032d8906
merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents:
6004
diff
changeset
|
87 def _eoltype(data): |
3c33032d8906
merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents:
6004
diff
changeset
|
88 "Guess the EOL type of a file" |
3c33032d8906
merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents:
6004
diff
changeset
|
89 if '\0' in data: # binary |
3c33032d8906
merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents:
6004
diff
changeset
|
90 return None |
3c33032d8906
merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents:
6004
diff
changeset
|
91 if '\r\n' in data: # Windows |
3c33032d8906
merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents:
6004
diff
changeset
|
92 return '\r\n' |
3c33032d8906
merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents:
6004
diff
changeset
|
93 if '\r' in data: # Old Mac |
3c33032d8906
merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents:
6004
diff
changeset
|
94 return '\r' |
3c33032d8906
merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents:
6004
diff
changeset
|
95 if '\n' in data: # UNIX |
3c33032d8906
merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents:
6004
diff
changeset
|
96 return '\n' |
3c33032d8906
merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents:
6004
diff
changeset
|
97 return None # unknown |
3c33032d8906
merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents:
6004
diff
changeset
|
98 |
3c33032d8906
merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents:
6004
diff
changeset
|
99 def _matcheol(file, origfile): |
3c33032d8906
merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents:
6004
diff
changeset
|
100 "Convert EOL markers in a file to match origfile" |
3c33032d8906
merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents:
6004
diff
changeset
|
101 tostyle = _eoltype(open(origfile, "rb").read()) |
3c33032d8906
merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents:
6004
diff
changeset
|
102 if tostyle: |
3c33032d8906
merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents:
6004
diff
changeset
|
103 data = open(file, "rb").read() |
3c33032d8906
merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents:
6004
diff
changeset
|
104 style = _eoltype(data) |
3c33032d8906
merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents:
6004
diff
changeset
|
105 if style: |
3c33032d8906
merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents:
6004
diff
changeset
|
106 newdata = data.replace(style, tostyle) |
3c33032d8906
merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents:
6004
diff
changeset
|
107 if newdata != data: |
3c33032d8906
merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents:
6004
diff
changeset
|
108 open(file, "wb").write(newdata) |
3c33032d8906
merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents:
6004
diff
changeset
|
109 |
6512
368a4ec603cc
merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents:
6212
diff
changeset
|
110 def filemerge(repo, mynode, orig, fcd, fco, fca): |
6003
7855b88ba838
filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
111 """perform a 3-way merge in the working directory |
7855b88ba838
filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
112 |
6512
368a4ec603cc
merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents:
6212
diff
changeset
|
113 mynode = parent node before merge |
368a4ec603cc
merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents:
6212
diff
changeset
|
114 orig = original local filename before merge |
368a4ec603cc
merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents:
6212
diff
changeset
|
115 fco = other file context |
368a4ec603cc
merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents:
6212
diff
changeset
|
116 fca = ancestor file context |
368a4ec603cc
merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents:
6212
diff
changeset
|
117 fcd = local file context for current/destination file |
6003
7855b88ba838
filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
118 """ |
7855b88ba838
filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
119 |
7855b88ba838
filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
120 def temp(prefix, ctx): |
7855b88ba838
filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
121 pre = "%s~%s." % (os.path.basename(ctx.path()), prefix) |
7855b88ba838
filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
122 (fd, name) = tempfile.mkstemp(prefix=pre) |
7855b88ba838
filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
123 data = repo.wwritedata(ctx.path(), ctx.data()) |
7855b88ba838
filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
124 f = os.fdopen(fd, "wb") |
7855b88ba838
filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
125 f.write(data) |
7855b88ba838
filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
126 f.close() |
7855b88ba838
filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
127 return name |
7855b88ba838
filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
128 |
6004
5af5f0f9d724
merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents:
6003
diff
changeset
|
129 def isbin(ctx): |
5af5f0f9d724
merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents:
6003
diff
changeset
|
130 try: |
5af5f0f9d724
merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents:
6003
diff
changeset
|
131 return util.binary(ctx.data()) |
5af5f0f9d724
merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents:
6003
diff
changeset
|
132 except IOError: |
5af5f0f9d724
merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents:
6003
diff
changeset
|
133 return False |
5af5f0f9d724
merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents:
6003
diff
changeset
|
134 |
6512
368a4ec603cc
merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents:
6212
diff
changeset
|
135 if not fco.cmp(fcd.data()): # files identical? |
6003
7855b88ba838
filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
136 return None |
7855b88ba838
filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
137 |
6004
5af5f0f9d724
merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents:
6003
diff
changeset
|
138 ui = repo.ui |
6512
368a4ec603cc
merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents:
6212
diff
changeset
|
139 fd = fcd.path() |
368a4ec603cc
merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents:
6212
diff
changeset
|
140 binary = isbin(fcd) or isbin(fco) or isbin(fca) |
6744
d3691d31fc9c
context: remove islink and isexec methods
Matt Mackall <mpm@selenic.com>
parents:
6743
diff
changeset
|
141 symlink = 'l' in fcd.flags() + fco.flags() |
6512
368a4ec603cc
merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents:
6212
diff
changeset
|
142 tool, toolpath = _picktool(repo, ui, fd, binary, symlink) |
9467
4c041f1ee1b4
do not attempt to translate ui.debug output
Martin Geisler <mg@lazybytes.net>
parents:
9049
diff
changeset
|
143 ui.debug("picked tool '%s' for %s (binary %s symlink %s)\n" % |
6512
368a4ec603cc
merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents:
6212
diff
changeset
|
144 (tool, fd, binary, symlink)) |
6004
5af5f0f9d724
merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents:
6003
diff
changeset
|
145 |
8830
a9850eda2973
filemerge: add internal:prompt target
Matt Mackall <mpm@selenic.com>
parents:
8615
diff
changeset
|
146 if not tool or tool == 'internal:prompt': |
6004
5af5f0f9d724
merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents:
6003
diff
changeset
|
147 tool = "internal:local" |
9048
86b4a9b0ddda
ui: extract choice from prompt
Simon Heimberg <simohe@besonet.ch>
parents:
8861
diff
changeset
|
148 if ui.promptchoice(_(" no tool found to merge %s\n" |
9049
38b5d5e0efab
filemerge, subrepo: correct indention
Martin Geisler <mg@lazybytes.net>
parents:
9048
diff
changeset
|
149 "keep (l)ocal or take (o)ther?") % fd, |
38b5d5e0efab
filemerge, subrepo: correct indention
Martin Geisler <mg@lazybytes.net>
parents:
9048
diff
changeset
|
150 (_("&Local"), _("&Other")), 0): |
6004
5af5f0f9d724
merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents:
6003
diff
changeset
|
151 tool = "internal:other" |
5af5f0f9d724
merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents:
6003
diff
changeset
|
152 if tool == "internal:local": |
5af5f0f9d724
merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents:
6003
diff
changeset
|
153 return 0 |
5af5f0f9d724
merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents:
6003
diff
changeset
|
154 if tool == "internal:other": |
6743 | 155 repo.wwrite(fd, fco.data(), fco.flags()) |
6004
5af5f0f9d724
merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents:
6003
diff
changeset
|
156 return 0 |
5af5f0f9d724
merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents:
6003
diff
changeset
|
157 if tool == "internal:fail": |
5af5f0f9d724
merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents:
6003
diff
changeset
|
158 return 1 |
5af5f0f9d724
merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents:
6003
diff
changeset
|
159 |
5af5f0f9d724
merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents:
6003
diff
changeset
|
160 # do the actual merge |
6003
7855b88ba838
filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
161 a = repo.wjoin(fd) |
7855b88ba838
filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
162 b = temp("base", fca) |
7855b88ba838
filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
163 c = temp("other", fco) |
6004
5af5f0f9d724
merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents:
6003
diff
changeset
|
164 out = "" |
5af5f0f9d724
merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents:
6003
diff
changeset
|
165 back = a + ".orig" |
5af5f0f9d724
merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents:
6003
diff
changeset
|
166 util.copyfile(a, back) |
6003
7855b88ba838
filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
167 |
6512
368a4ec603cc
merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents:
6212
diff
changeset
|
168 if orig != fco.path(): |
8615
94ca38e63576
use ui instead of repo.ui when the former is in scope
Martin Geisler <mg@lazybytes.net>
parents:
8567
diff
changeset
|
169 ui.status(_("merging %s and %s to %s\n") % (orig, fco.path(), fd)) |
6003
7855b88ba838
filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
170 else: |
8615
94ca38e63576
use ui instead of repo.ui when the former is in scope
Martin Geisler <mg@lazybytes.net>
parents:
8567
diff
changeset
|
171 ui.status(_("merging %s\n") % fd) |
6512
368a4ec603cc
merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents:
6212
diff
changeset
|
172 |
9467
4c041f1ee1b4
do not attempt to translate ui.debug output
Martin Geisler <mg@lazybytes.net>
parents:
9049
diff
changeset
|
173 ui.debug("my %s other %s ancestor %s\n" % (fcd, fco, fca)) |
6003
7855b88ba838
filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
174 |
6004
5af5f0f9d724
merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents:
6003
diff
changeset
|
175 # do we attempt to simplemerge first? |
5af5f0f9d724
merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents:
6003
diff
changeset
|
176 if _toolbool(ui, tool, "premerge", not (binary or symlink)): |
8269
bb9f13974d8e
simplemerge: use ui.warn() for warnings
Steve Borho <steve@borho.org>
parents:
8259
diff
changeset
|
177 r = simplemerge.simplemerge(ui, a, b, c, quiet=True) |
6004
5af5f0f9d724
merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents:
6003
diff
changeset
|
178 if not r: |
9467
4c041f1ee1b4
do not attempt to translate ui.debug output
Martin Geisler <mg@lazybytes.net>
parents:
9049
diff
changeset
|
179 ui.debug(" premerge successful\n") |
6004
5af5f0f9d724
merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents:
6003
diff
changeset
|
180 os.unlink(back) |
5af5f0f9d724
merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents:
6003
diff
changeset
|
181 os.unlink(b) |
5af5f0f9d724
merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents:
6003
diff
changeset
|
182 os.unlink(c) |
5af5f0f9d724
merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents:
6003
diff
changeset
|
183 return 0 |
5af5f0f9d724
merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents:
6003
diff
changeset
|
184 util.copyfile(back, a) # restore from backup and try again |
5af5f0f9d724
merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents:
6003
diff
changeset
|
185 |
5af5f0f9d724
merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents:
6003
diff
changeset
|
186 env = dict(HG_FILE=fd, |
6512
368a4ec603cc
merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents:
6212
diff
changeset
|
187 HG_MY_NODE=short(mynode), |
368a4ec603cc
merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents:
6212
diff
changeset
|
188 HG_OTHER_NODE=str(fco.changectx()), |
9709
5858117a0077
merge: supply base node to merge tools in the environment
Sune Foldager <cryo@cyanite.org>
parents:
9467
diff
changeset
|
189 HG_BASE_NODE=str(fca.changectx()), |
6744
d3691d31fc9c
context: remove islink and isexec methods
Matt Mackall <mpm@selenic.com>
parents:
6743
diff
changeset
|
190 HG_MY_ISLINK='l' in fcd.flags(), |
d3691d31fc9c
context: remove islink and isexec methods
Matt Mackall <mpm@selenic.com>
parents:
6743
diff
changeset
|
191 HG_OTHER_ISLINK='l' in fco.flags(), |
d3691d31fc9c
context: remove islink and isexec methods
Matt Mackall <mpm@selenic.com>
parents:
6743
diff
changeset
|
192 HG_BASE_ISLINK='l' in fca.flags()) |
6004
5af5f0f9d724
merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents:
6003
diff
changeset
|
193 |
5af5f0f9d724
merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents:
6003
diff
changeset
|
194 if tool == "internal:merge": |
8269
bb9f13974d8e
simplemerge: use ui.warn() for warnings
Steve Borho <steve@borho.org>
parents:
8259
diff
changeset
|
195 r = simplemerge.simplemerge(ui, a, b, c, label=['local', 'other']) |
8831
91e26fb24fb1
filemerge: add internal:dump
Matt Mackall <mpm@selenic.com>
parents:
8830
diff
changeset
|
196 elif tool == 'internal:dump': |
91e26fb24fb1
filemerge: add internal:dump
Matt Mackall <mpm@selenic.com>
parents:
8830
diff
changeset
|
197 a = repo.wjoin(fd) |
91e26fb24fb1
filemerge: add internal:dump
Matt Mackall <mpm@selenic.com>
parents:
8830
diff
changeset
|
198 util.copyfile(a, a + ".local") |
8861
90f74b31ed4f
filemerge: fix internal:dump
Matt Mackall <mpm@selenic.com>
parents:
8831
diff
changeset
|
199 repo.wwrite(fd + ".other", fco.data(), fco.flags()) |
90f74b31ed4f
filemerge: fix internal:dump
Matt Mackall <mpm@selenic.com>
parents:
8831
diff
changeset
|
200 repo.wwrite(fd + ".base", fca.data(), fca.flags()) |
8831
91e26fb24fb1
filemerge: add internal:dump
Matt Mackall <mpm@selenic.com>
parents:
8830
diff
changeset
|
201 return 1 # unresolved |
6004
5af5f0f9d724
merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents:
6003
diff
changeset
|
202 else: |
5af5f0f9d724
merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents:
6003
diff
changeset
|
203 args = _toolstr(ui, tool, "args", '$local $base $other') |
5af5f0f9d724
merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents:
6003
diff
changeset
|
204 if "$output" in args: |
5af5f0f9d724
merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents:
6003
diff
changeset
|
205 out, a = a, back # read input from backup, write to original |
5af5f0f9d724
merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents:
6003
diff
changeset
|
206 replace = dict(local=a, base=b, other=c, output=out) |
5af5f0f9d724
merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents:
6003
diff
changeset
|
207 args = re.sub("\$(local|base|other|output)", |
5af5f0f9d724
merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents:
6003
diff
changeset
|
208 lambda x: '"%s"' % replace[x.group()[1:]], args) |
5af5f0f9d724
merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents:
6003
diff
changeset
|
209 r = util.system(toolpath + ' ' + args, cwd=repo.root, environ=env) |
5af5f0f9d724
merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents:
6003
diff
changeset
|
210 |
5af5f0f9d724
merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents:
6003
diff
changeset
|
211 if not r and _toolbool(ui, tool, "checkconflicts"): |
6512
368a4ec603cc
merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents:
6212
diff
changeset
|
212 if re.match("^(<<<<<<< .*|=======|>>>>>>> .*)$", fcd.data()): |
6004
5af5f0f9d724
merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents:
6003
diff
changeset
|
213 r = 1 |
5af5f0f9d724
merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents:
6003
diff
changeset
|
214 |
6075
63e0e57ab157
filemerge: add 'checkchanged' merge tool property
Steve Borho <steve@borho.org>
parents:
6025
diff
changeset
|
215 if not r and _toolbool(ui, tool, "checkchanged"): |
63e0e57ab157
filemerge: add 'checkchanged' merge tool property
Steve Borho <steve@borho.org>
parents:
6025
diff
changeset
|
216 if filecmp.cmp(repo.wjoin(fd), back): |
9048
86b4a9b0ddda
ui: extract choice from prompt
Simon Heimberg <simohe@besonet.ch>
parents:
8861
diff
changeset
|
217 if ui.promptchoice(_(" output file %s appears unchanged\n" |
9049
38b5d5e0efab
filemerge, subrepo: correct indention
Martin Geisler <mg@lazybytes.net>
parents:
9048
diff
changeset
|
218 "was merge successful (yn)?") % fd, |
38b5d5e0efab
filemerge, subrepo: correct indention
Martin Geisler <mg@lazybytes.net>
parents:
9048
diff
changeset
|
219 (_("&Yes"), _("&No")), 1): |
6075
63e0e57ab157
filemerge: add 'checkchanged' merge tool property
Steve Borho <steve@borho.org>
parents:
6025
diff
changeset
|
220 r = 1 |
63e0e57ab157
filemerge: add 'checkchanged' merge tool property
Steve Borho <steve@borho.org>
parents:
6025
diff
changeset
|
221 |
6005
3c33032d8906
merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents:
6004
diff
changeset
|
222 if _toolbool(ui, tool, "fixeol"): |
6015
26ef792f834e
filemerge: fix path to working file when fixeol is enabled
Lee Cantey <lcantey@gmail.com>
parents:
6013
diff
changeset
|
223 _matcheol(repo.wjoin(fd), back) |
6005
3c33032d8906
merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents:
6004
diff
changeset
|
224 |
6003
7855b88ba838
filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
225 if r: |
8615
94ca38e63576
use ui instead of repo.ui when the former is in scope
Martin Geisler <mg@lazybytes.net>
parents:
8567
diff
changeset
|
226 ui.warn(_("merging %s failed!\n") % fd) |
6004
5af5f0f9d724
merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents:
6003
diff
changeset
|
227 else: |
5af5f0f9d724
merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents:
6003
diff
changeset
|
228 os.unlink(back) |
6003
7855b88ba838
filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
229 |
7855b88ba838
filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
230 os.unlink(b) |
7855b88ba838
filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
231 os.unlink(c) |
7855b88ba838
filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
232 return r |