annotate mercurial/filemerge.py @ 8564:6b9ec23b09fc

named branches: improve pre-push logic (issue736) Each named branch is considered separately, and the push is allowed if no new branch heads are created for any named branch to be pushed. Due to some tests's use of --debug, their output will change after this addition. This has been fixed as well. Co-contributor: Henrik Stuart <henrik.stuart@edlund.dk>
author Sune Foldager <cryo@cyanite.org>
date Sat, 23 May 2009 17:04:31 +0200
parents b87a50b7125c
children 744d6322b05b
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 #
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 _
8312
b87a50b7125c separate import lines from mercurial and general python modules
Simon Heimberg <simohe@besonet.ch>
parents: 8269
diff changeset
10 import util, simplemerge
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
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
19 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
20 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
21 return tool
6006
3c9dbb743d20 merge: add registry look up bits to tool search
Matt Mackall <mpm@selenic.com>
parents: 6005
diff changeset
22 k = _toolstr(ui, tool, "regkey")
3c9dbb743d20 merge: add registry look up bits to tool search
Matt Mackall <mpm@selenic.com>
parents: 6005
diff changeset
23 if k:
3c9dbb743d20 merge: add registry look up bits to tool search
Matt Mackall <mpm@selenic.com>
parents: 6005
diff changeset
24 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
25 if p:
3c9dbb743d20 merge: add registry look up bits to tool search
Matt Mackall <mpm@selenic.com>
parents: 6005
diff changeset
26 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
27 if p:
3c9dbb743d20 merge: add registry look up bits to tool search
Matt Mackall <mpm@selenic.com>
parents: 6005
diff changeset
28 return p
6004
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
29 return util.find_exe(_toolstr(ui, tool, "executable", tool))
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
30
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
31 def _picktool(repo, ui, path, binary, symlink):
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
32 def check(tool, pat, symlink, binary):
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
33 tmsg = tool
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
34 if pat:
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
35 tmsg += " specified for " + pat
7397
4c92d8971809 More verbose logging when filemerge searches for merge-tool
Mads Kiilerich <mads@kiilerich.com>
parents: 6762
diff changeset
36 if not _findtool(ui, tool):
4c92d8971809 More verbose logging when filemerge searches for merge-tool
Mads Kiilerich <mads@kiilerich.com>
parents: 6762
diff changeset
37 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
38 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
39 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
40 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
41 elif symlink and not _toolbool(ui, tool, "symlink"):
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
42 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
43 elif binary and not _toolbool(ui, tool, "binary"):
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
44 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
45 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
46 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
47 else:
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
48 return True
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
49 return False
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
50
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
51 # HGMERGE takes precedence
6025
f2335246e5c7 filemerge: wrap quotes around tool path
Steve Borho <steve@borho.org>
parents: 6016
diff changeset
52 hgmerge = os.environ.get("HGMERGE")
f2335246e5c7 filemerge: wrap quotes around tool path
Steve Borho <steve@borho.org>
parents: 6016
diff changeset
53 if hgmerge:
f2335246e5c7 filemerge: wrap quotes around tool path
Steve Borho <steve@borho.org>
parents: 6016
diff changeset
54 return (hgmerge, hgmerge)
6004
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
55
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
56 # then patterns
6016
288ec2f6faa2 filemerge: fix pattern matching
dhruva <dhruvakm@gmail.com>
parents: 6015
diff changeset
57 for pat, tool in ui.configitems("merge-patterns"):
6004
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
58 mf = util.matcher(repo.root, "", [pat], [], [])[1]
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
59 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
60 toolpath = _findtool(ui, tool)
f2335246e5c7 filemerge: wrap quotes around tool path
Steve Borho <steve@borho.org>
parents: 6016
diff changeset
61 return (tool, '"' + toolpath + '"')
6004
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
62
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
63 # then merge tools
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
64 tools = {}
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
65 for k,v in ui.configitems("merge-tools"):
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
66 t = k.split('.')[0]
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
67 if t not in tools:
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
68 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
69 names = tools.keys()
8209
a1a5a57efe90 replace util.sort with sorted built-in
Matt Mackall <mpm@selenic.com>
parents: 7873
diff changeset
70 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
71 uimerge = ui.config("ui", "merge")
0ee885fea464 filemerge: more backwards compatible behavior for ui.merge
Steve Borho <steve@borho.org>
parents: 6075
diff changeset
72 if uimerge:
0ee885fea464 filemerge: more backwards compatible behavior for ui.merge
Steve Borho <steve@borho.org>
parents: 6075
diff changeset
73 if uimerge not in names:
0ee885fea464 filemerge: more backwards compatible behavior for ui.merge
Steve Borho <steve@borho.org>
parents: 6075
diff changeset
74 return (uimerge, uimerge)
0ee885fea464 filemerge: more backwards compatible behavior for ui.merge
Steve Borho <steve@borho.org>
parents: 6075
diff changeset
75 tools.insert(0, (None, uimerge)) # highest priority
6004
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
76 tools.append((None, "hgmerge")) # the old default, if found
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
77 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
78 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
79 toolpath = _findtool(ui, t)
6025
f2335246e5c7 filemerge: wrap quotes around tool path
Steve Borho <steve@borho.org>
parents: 6016
diff changeset
80 return (t, '"' + toolpath + '"')
f2335246e5c7 filemerge: wrap quotes around tool path
Steve Borho <steve@borho.org>
parents: 6016
diff changeset
81 # internal merge as last resort
f2335246e5c7 filemerge: wrap quotes around tool path
Steve Borho <steve@borho.org>
parents: 6016
diff changeset
82 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
83
6005
3c33032d8906 merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents: 6004
diff changeset
84 def _eoltype(data):
3c33032d8906 merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents: 6004
diff changeset
85 "Guess the EOL type of a file"
3c33032d8906 merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents: 6004
diff changeset
86 if '\0' in data: # binary
3c33032d8906 merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents: 6004
diff changeset
87 return None
3c33032d8906 merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents: 6004
diff changeset
88 if '\r\n' in data: # Windows
3c33032d8906 merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents: 6004
diff changeset
89 return '\r\n'
3c33032d8906 merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents: 6004
diff changeset
90 if '\r' in data: # Old Mac
3c33032d8906 merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents: 6004
diff changeset
91 return '\r'
3c33032d8906 merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents: 6004
diff changeset
92 if '\n' in data: # UNIX
3c33032d8906 merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents: 6004
diff changeset
93 return '\n'
3c33032d8906 merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents: 6004
diff changeset
94 return None # unknown
3c33032d8906 merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents: 6004
diff changeset
95
3c33032d8906 merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents: 6004
diff changeset
96 def _matcheol(file, origfile):
3c33032d8906 merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents: 6004
diff changeset
97 "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
98 tostyle = _eoltype(open(origfile, "rb").read())
3c33032d8906 merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents: 6004
diff changeset
99 if tostyle:
3c33032d8906 merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents: 6004
diff changeset
100 data = open(file, "rb").read()
3c33032d8906 merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents: 6004
diff changeset
101 style = _eoltype(data)
3c33032d8906 merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents: 6004
diff changeset
102 if style:
3c33032d8906 merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents: 6004
diff changeset
103 newdata = data.replace(style, tostyle)
3c33032d8906 merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents: 6004
diff changeset
104 if newdata != data:
3c33032d8906 merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents: 6004
diff changeset
105 open(file, "wb").write(newdata)
3c33032d8906 merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents: 6004
diff changeset
106
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6212
diff changeset
107 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
108 """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
109
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6212
diff changeset
110 mynode = parent node before merge
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6212
diff changeset
111 orig = original local filename before merge
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6212
diff changeset
112 fco = other file context
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6212
diff changeset
113 fca = ancestor file context
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6212
diff changeset
114 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
115 """
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
116
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
117 def temp(prefix, ctx):
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
118 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
119 (fd, name) = tempfile.mkstemp(prefix=pre)
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
120 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
121 f = os.fdopen(fd, "wb")
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
122 f.write(data)
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
123 f.close()
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
124 return name
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
125
6004
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
126 def isbin(ctx):
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
127 try:
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
128 return util.binary(ctx.data())
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
129 except IOError:
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
130 return False
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
131
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6212
diff changeset
132 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
133 return None
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
134
6004
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
135 ui = repo.ui
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6212
diff changeset
136 fd = fcd.path()
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6212
diff changeset
137 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
138 symlink = 'l' in fcd.flags() + fco.flags()
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6212
diff changeset
139 tool, toolpath = _picktool(repo, ui, fd, binary, symlink)
6004
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
140 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
141 (tool, fd, binary, symlink))
6004
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
142
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
143 if not tool:
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
144 tool = "internal:local"
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
145 if ui.prompt(_(" no tool found to merge %s\n"
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6212
diff changeset
146 "keep (l)ocal or take (o)ther?") % fd,
8259
98acfd1d2b08 ui: replace regexp pattern with sequence of choices
Steve Borho <steve@borho.org>
parents: 8225
diff changeset
147 (_("&Local"), _("&Other")), _("l")) != _("l"):
6004
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
148 tool = "internal:other"
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
149 if tool == "internal:local":
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:other":
6743
86e8187b721a simplify flag handling
Matt Mackall <mpm@selenic.com>
parents: 6533
diff changeset
152 repo.wwrite(fd, fco.data(), fco.flags())
6004
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:fail":
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
155 return 1
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
156
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
157 # do the actual merge
6003
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
158 a = repo.wjoin(fd)
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
159 b = temp("base", fca)
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
160 c = temp("other", fco)
6004
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
161 out = ""
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
162 back = a + ".orig"
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
163 util.copyfile(a, back)
6003
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
164
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6212
diff changeset
165 if orig != fco.path():
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6212
diff changeset
166 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
167 else:
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6212
diff changeset
168 repo.ui.status(_("merging %s\n") % fd)
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6212
diff changeset
169
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6212
diff changeset
170 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
171
6004
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
172 # do we attempt to simplemerge first?
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
173 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
174 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
175 if not r:
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
176 ui.debug(_(" premerge successful\n"))
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
177 os.unlink(back)
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
178 os.unlink(b)
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
179 os.unlink(c)
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
180 return 0
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
181 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
182
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
183 env = dict(HG_FILE=fd,
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6212
diff changeset
184 HG_MY_NODE=short(mynode),
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6212
diff changeset
185 HG_OTHER_NODE=str(fco.changectx()),
6744
d3691d31fc9c context: remove islink and isexec methods
Matt Mackall <mpm@selenic.com>
parents: 6743
diff changeset
186 HG_MY_ISLINK='l' in fcd.flags(),
d3691d31fc9c context: remove islink and isexec methods
Matt Mackall <mpm@selenic.com>
parents: 6743
diff changeset
187 HG_OTHER_ISLINK='l' in fco.flags(),
d3691d31fc9c context: remove islink and isexec methods
Matt Mackall <mpm@selenic.com>
parents: 6743
diff changeset
188 HG_BASE_ISLINK='l' in fca.flags())
6004
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
189
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
190 if tool == "internal:merge":
8269
bb9f13974d8e simplemerge: use ui.warn() for warnings
Steve Borho <steve@borho.org>
parents: 8259
diff changeset
191 r = simplemerge.simplemerge(ui, a, b, c, label=['local', 'other'])
6004
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
192 else:
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
193 args = _toolstr(ui, tool, "args", '$local $base $other')
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
194 if "$output" in args:
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
195 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
196 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
197 args = re.sub("\$(local|base|other|output)",
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
198 lambda x: '"%s"' % replace[x.group()[1:]], args)
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
199 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
200
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
201 if not r and _toolbool(ui, tool, "checkconflicts"):
6512
368a4ec603cc merge: introduce mergestate
Matt Mackall <mpm@selenic.com>
parents: 6212
diff changeset
202 if re.match("^(<<<<<<< .*|=======|>>>>>>> .*)$", fcd.data()):
6004
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
203 r = 1
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
204
6075
63e0e57ab157 filemerge: add 'checkchanged' merge tool property
Steve Borho <steve@borho.org>
parents: 6025
diff changeset
205 if not r and _toolbool(ui, tool, "checkchanged"):
63e0e57ab157 filemerge: add 'checkchanged' merge tool property
Steve Borho <steve@borho.org>
parents: 6025
diff changeset
206 if filecmp.cmp(repo.wjoin(fd), back):
63e0e57ab157 filemerge: add 'checkchanged' merge tool property
Steve Borho <steve@borho.org>
parents: 6025
diff changeset
207 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
208 "was merge successful (yn)?") % fd,
8259
98acfd1d2b08 ui: replace regexp pattern with sequence of choices
Steve Borho <steve@borho.org>
parents: 8225
diff changeset
209 (_("&Yes"), _("&No")), _("n")) != _("y"):
6075
63e0e57ab157 filemerge: add 'checkchanged' merge tool property
Steve Borho <steve@borho.org>
parents: 6025
diff changeset
210 r = 1
63e0e57ab157 filemerge: add 'checkchanged' merge tool property
Steve Borho <steve@borho.org>
parents: 6025
diff changeset
211
6005
3c33032d8906 merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents: 6004
diff changeset
212 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
213 _matcheol(repo.wjoin(fd), back)
6005
3c33032d8906 merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents: 6004
diff changeset
214
6003
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
215 if r:
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
216 repo.ui.warn(_("merging %s failed!\n") % fd)
6004
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
217 else:
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
218 os.unlink(back)
6003
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
219
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
220 os.unlink(b)
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
221 os.unlink(c)
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
222 return r