annotate mercurial/filemerge.py @ 6615:0697e7818d07

status: fix "added" attributes renamed in bf2bf986ff87
author Patrick Mezard <pmezard@gmail.com>
date Sun, 18 May 2008 23:09:59 +0200
parents 65f1b97484be
children 86e8187b721a
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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 #
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
5 # This software may be used and distributed according to the terms
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
6 # of the GNU General Public License, incorporated herein by reference.
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
7
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6212
diff changeset
8 from node import nullrev, short
6003
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
9 from i18n import _
6212
e75aab656f46 Remove unused imports
Joel Rosdahl <joel@rosdahl.net>
parents: 6211
diff changeset
10 import util, os, tempfile, simplemerge, re, filecmp
6004
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
11
6013
bb441d77df99 filemerge: handle missing regappend
Matt Mackall <mpm@selenic.com>
parents: 6007
diff changeset
12 def _toolstr(ui, tool, part, default=""):
6004
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
13 return ui.config("merge-tools", tool + "." + part, default)
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
14
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
15 def _toolbool(ui, tool, part, default=False):
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
16 return ui.configbool("merge-tools", tool + "." + part, default)
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
17
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
18 def _findtool(ui, tool):
6522
2b181fb3a70a use internal merge tool when specified for a merge-pattern in hgrc
Dov Feldstern <dfeldstern@fastimap.com>
parents: 6212
diff changeset
19 if tool in ("internal:fail", "internal:local", "internal:other"):
2b181fb3a70a use internal merge tool when specified for a merge-pattern in hgrc
Dov Feldstern <dfeldstern@fastimap.com>
parents: 6212
diff changeset
20 return tool
6006
3c9dbb743d20 merge: add registry look up bits to tool search
Matt Mackall <mpm@selenic.com>
parents: 6005
diff changeset
21 k = _toolstr(ui, tool, "regkey")
3c9dbb743d20 merge: add registry look up bits to tool search
Matt Mackall <mpm@selenic.com>
parents: 6005
diff changeset
22 if k:
3c9dbb743d20 merge: add registry look up bits to tool search
Matt Mackall <mpm@selenic.com>
parents: 6005
diff changeset
23 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
24 if p:
3c9dbb743d20 merge: add registry look up bits to tool search
Matt Mackall <mpm@selenic.com>
parents: 6005
diff changeset
25 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
26 if p:
3c9dbb743d20 merge: add registry look up bits to tool search
Matt Mackall <mpm@selenic.com>
parents: 6005
diff changeset
27 return p
6004
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
28 return util.find_exe(_toolstr(ui, tool, "executable", tool))
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
29
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
30 def _picktool(repo, ui, path, binary, symlink):
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
31 def check(tool, pat, symlink, binary):
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
32 tmsg = tool
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
33 if pat:
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
34 tmsg += " specified for " + pat
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
35 if pat and not _findtool(ui, tool): # skip search if not matching
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
36 ui.warn(_("couldn't find merge tool %s\n") % tmsg)
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
37 elif symlink and not _toolbool(ui, tool, "symlink"):
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
38 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
39 elif binary and not _toolbool(ui, tool, "binary"):
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
40 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
41 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
42 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
43 else:
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
44 return True
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
45 return False
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
46
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
47 # HGMERGE takes precedence
6025
f2335246e5c7 filemerge: wrap quotes around tool path
Steve Borho <steve@borho.org>
parents: 6016
diff changeset
48 hgmerge = os.environ.get("HGMERGE")
f2335246e5c7 filemerge: wrap quotes around tool path
Steve Borho <steve@borho.org>
parents: 6016
diff changeset
49 if hgmerge:
f2335246e5c7 filemerge: wrap quotes around tool path
Steve Borho <steve@borho.org>
parents: 6016
diff changeset
50 return (hgmerge, hgmerge)
6004
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
51
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
52 # then patterns
6016
288ec2f6faa2 filemerge: fix pattern matching
dhruva <dhruvakm@gmail.com>
parents: 6015
diff changeset
53 for pat, tool in ui.configitems("merge-patterns"):
6004
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
54 mf = util.matcher(repo.root, "", [pat], [], [])[1]
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
55 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
56 toolpath = _findtool(ui, tool)
f2335246e5c7 filemerge: wrap quotes around tool path
Steve Borho <steve@borho.org>
parents: 6016
diff changeset
57 return (tool, '"' + toolpath + '"')
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 merge tools
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
60 tools = {}
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
61 for k,v in ui.configitems("merge-tools"):
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
62 t = k.split('.')[0]
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
63 if t not in tools:
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
64 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
65 names = tools.keys()
6004
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
66 tools = [(-p,t) for t,p in tools.items()]
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
67 tools.sort()
6076
0ee885fea464 filemerge: more backwards compatible behavior for ui.merge
Steve Borho <steve@borho.org>
parents: 6075
diff changeset
68 uimerge = ui.config("ui", "merge")
0ee885fea464 filemerge: more backwards compatible behavior for ui.merge
Steve Borho <steve@borho.org>
parents: 6075
diff changeset
69 if uimerge:
0ee885fea464 filemerge: more backwards compatible behavior for ui.merge
Steve Borho <steve@borho.org>
parents: 6075
diff changeset
70 if uimerge not in names:
0ee885fea464 filemerge: more backwards compatible behavior for ui.merge
Steve Borho <steve@borho.org>
parents: 6075
diff changeset
71 return (uimerge, uimerge)
0ee885fea464 filemerge: more backwards compatible behavior for ui.merge
Steve Borho <steve@borho.org>
parents: 6075
diff changeset
72 tools.insert(0, (None, uimerge)) # highest priority
6004
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
73 tools.append((None, "hgmerge")) # the old default, if found
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
74 for p,t in tools:
6025
f2335246e5c7 filemerge: wrap quotes around tool path
Steve Borho <steve@borho.org>
parents: 6016
diff changeset
75 toolpath = _findtool(ui, t)
f2335246e5c7 filemerge: wrap quotes around tool path
Steve Borho <steve@borho.org>
parents: 6016
diff changeset
76 if toolpath and check(t, None, symlink, binary):
f2335246e5c7 filemerge: wrap quotes around tool path
Steve Borho <steve@borho.org>
parents: 6016
diff changeset
77 return (t, '"' + toolpath + '"')
f2335246e5c7 filemerge: wrap quotes around tool path
Steve Borho <steve@borho.org>
parents: 6016
diff changeset
78 # internal merge as last resort
f2335246e5c7 filemerge: wrap quotes around tool path
Steve Borho <steve@borho.org>
parents: 6016
diff changeset
79 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
80
6005
3c33032d8906 merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents: 6004
diff changeset
81 def _eoltype(data):
3c33032d8906 merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents: 6004
diff changeset
82 "Guess the EOL type of a file"
3c33032d8906 merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents: 6004
diff changeset
83 if '\0' in data: # binary
3c33032d8906 merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents: 6004
diff changeset
84 return None
3c33032d8906 merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents: 6004
diff changeset
85 if '\r\n' in data: # Windows
3c33032d8906 merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents: 6004
diff changeset
86 return '\r\n'
3c33032d8906 merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents: 6004
diff changeset
87 if '\r' in data: # Old Mac
3c33032d8906 merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents: 6004
diff changeset
88 return '\r'
3c33032d8906 merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents: 6004
diff changeset
89 if '\n' in data: # UNIX
3c33032d8906 merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents: 6004
diff changeset
90 return '\n'
3c33032d8906 merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents: 6004
diff changeset
91 return None # unknown
3c33032d8906 merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents: 6004
diff changeset
92
3c33032d8906 merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents: 6004
diff changeset
93 def _matcheol(file, origfile):
3c33032d8906 merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents: 6004
diff changeset
94 "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
95 tostyle = _eoltype(open(origfile, "rb").read())
3c33032d8906 merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents: 6004
diff changeset
96 if tostyle:
3c33032d8906 merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents: 6004
diff changeset
97 data = open(file, "rb").read()
3c33032d8906 merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents: 6004
diff changeset
98 style = _eoltype(data)
3c33032d8906 merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents: 6004
diff changeset
99 if style:
3c33032d8906 merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents: 6004
diff changeset
100 newdata = data.replace(style, tostyle)
3c33032d8906 merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents: 6004
diff changeset
101 if newdata != data:
3c33032d8906 merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents: 6004
diff changeset
102 open(file, "wb").write(newdata)
3c33032d8906 merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents: 6004
diff changeset
103
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6212
diff changeset
104 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
105 """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
106
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6212
diff changeset
107 mynode = parent node before merge
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6212
diff changeset
108 orig = original local filename before merge
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6212
diff changeset
109 fco = other file context
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6212
diff changeset
110 fca = ancestor file context
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6212
diff changeset
111 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
112 """
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
113
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
114 def temp(prefix, ctx):
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
115 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
116 (fd, name) = tempfile.mkstemp(prefix=pre)
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
117 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
118 f = os.fdopen(fd, "wb")
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
119 f.write(data)
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
120 f.close()
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
121 return name
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
122
6004
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
123 def isbin(ctx):
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
124 try:
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
125 return util.binary(ctx.data())
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
126 except IOError:
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
127 return False
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
128
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6212
diff changeset
129 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
130 return None
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
131
6004
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
132 ui = repo.ui
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6212
diff changeset
133 fd = fcd.path()
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6212
diff changeset
134 binary = isbin(fcd) or isbin(fco) or isbin(fca)
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6212
diff changeset
135 symlink = fcd.islink() or fco.islink()
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6212
diff changeset
136 tool, toolpath = _picktool(repo, ui, fd, binary, symlink)
6004
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
137 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
138 (tool, fd, binary, symlink))
6004
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
139
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
140 if not tool:
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
141 tool = "internal:local"
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
142 if ui.prompt(_(" no tool found to merge %s\n"
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6212
diff changeset
143 "keep (l)ocal or take (o)ther?") % fd,
6004
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
144 _("[lo]"), _("l")) != _("l"):
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
145 tool = "internal:other"
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
146 if tool == "internal:local":
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
147 return 0
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
148 if tool == "internal:other":
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
149 repo.wwrite(fd, fco.data(), fco.fileflags())
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
150 return 0
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
151 if tool == "internal:fail":
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
152 return 1
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
153
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
154 # do the actual merge
6003
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
155 a = repo.wjoin(fd)
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
156 b = temp("base", fca)
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
157 c = temp("other", fco)
6004
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
158 out = ""
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
159 back = a + ".orig"
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
160 util.copyfile(a, back)
6003
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
161
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6212
diff changeset
162 if orig != fco.path():
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6212
diff changeset
163 repo.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
164 else:
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6212
diff changeset
165 repo.ui.status(_("merging %s\n") % fd)
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6212
diff changeset
166
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6212
diff changeset
167 repo.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
168
6004
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
169 # do we attempt to simplemerge first?
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
170 if _toolbool(ui, tool, "premerge", not (binary or symlink)):
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
171 r = simplemerge.simplemerge(a, b, c, quiet=True)
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
172 if not r:
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
173 ui.debug(_(" premerge successful\n"))
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
174 os.unlink(back)
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
175 os.unlink(b)
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
176 os.unlink(c)
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
177 return 0
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
178 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
179
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
180 env = dict(HG_FILE=fd,
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6212
diff changeset
181 HG_MY_NODE=short(mynode),
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6212
diff changeset
182 HG_OTHER_NODE=str(fco.changectx()),
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6212
diff changeset
183 HG_MY_ISLINK=fcd.islink(),
6004
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
184 HG_OTHER_ISLINK=fco.islink(),
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
185 HG_BASE_ISLINK=fca.islink())
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
186
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
187 if tool == "internal:merge":
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
188 r = simplemerge.simplemerge(a, b, c, label=['local', 'other'])
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
189 else:
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
190 args = _toolstr(ui, tool, "args", '$local $base $other')
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
191 if "$output" in args:
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
192 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
193 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
194 args = re.sub("\$(local|base|other|output)",
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
195 lambda x: '"%s"' % replace[x.group()[1:]], args)
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
196 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
197
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
198 if not r and _toolbool(ui, tool, "checkconflicts"):
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6212
diff changeset
199 if re.match("^(<<<<<<< .*|=======|>>>>>>> .*)$", fcd.data()):
6004
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
200 r = 1
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
201
6075
63e0e57ab157 filemerge: add 'checkchanged' merge tool property
Steve Borho <steve@borho.org>
parents: 6025
diff changeset
202 if not r and _toolbool(ui, tool, "checkchanged"):
63e0e57ab157 filemerge: add 'checkchanged' merge tool property
Steve Borho <steve@borho.org>
parents: 6025
diff changeset
203 if filecmp.cmp(repo.wjoin(fd), back):
63e0e57ab157 filemerge: add 'checkchanged' merge tool property
Steve Borho <steve@borho.org>
parents: 6025
diff changeset
204 if ui.prompt(_(" output file %s appears unchanged\n"
63e0e57ab157 filemerge: add 'checkchanged' merge tool property
Steve Borho <steve@borho.org>
parents: 6025
diff changeset
205 "was merge successful (yn)?") % fd,
63e0e57ab157 filemerge: add 'checkchanged' merge tool property
Steve Borho <steve@borho.org>
parents: 6025
diff changeset
206 _("[yn]"), _("n")) != _("y"):
63e0e57ab157 filemerge: add 'checkchanged' merge tool property
Steve Borho <steve@borho.org>
parents: 6025
diff changeset
207 r = 1
63e0e57ab157 filemerge: add 'checkchanged' merge tool property
Steve Borho <steve@borho.org>
parents: 6025
diff changeset
208
6005
3c33032d8906 merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents: 6004
diff changeset
209 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
210 _matcheol(repo.wjoin(fd), back)
6005
3c33032d8906 merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents: 6004
diff changeset
211
6003
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
212 if r:
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
213 repo.ui.warn(_("merging %s failed!\n") % fd)
6004
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
214 else:
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
215 os.unlink(back)
6003
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
216
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
217 os.unlink(b)
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
218 os.unlink(c)
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
219 return r