annotate mercurial/filemerge.py @ 6139:989467e8e3a9

Fix bad behaviour when specifying an invalid date (issue700) commit (aborts _after_ typing in a commit message) backout (aborted after the initial revert) tag (edited .hgtags and couldn't commit) import (patch applied, then commit fails) qnew (aborts on bad dates, but writes any valid date into the # Date header) qrefresh (like qnew) sign (like tag) fetch (merge, merge, merge, merge, abort)
author Thomas Arendsen Hein <thomas@intevation.de>
date Sun, 17 Feb 2008 21:34:28 +0100
parents 0ee885fea464
children f89fd07fc51d
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
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
8 from node import *
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
9 from i18n import _
6075
63e0e57ab157 filemerge: add 'checkchanged' merge tool property
Steve Borho <steve@borho.org>
parents: 6025
diff changeset
10 import util, os, tempfile, context, 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):
6006
3c9dbb743d20 merge: add registry look up bits to tool search
Matt Mackall <mpm@selenic.com>
parents: 6005
diff changeset
19 k = _toolstr(ui, tool, "regkey")
3c9dbb743d20 merge: add registry look up bits to tool search
Matt Mackall <mpm@selenic.com>
parents: 6005
diff changeset
20 if k:
3c9dbb743d20 merge: add registry look up bits to tool search
Matt Mackall <mpm@selenic.com>
parents: 6005
diff changeset
21 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
22 if p:
3c9dbb743d20 merge: add registry look up bits to tool search
Matt Mackall <mpm@selenic.com>
parents: 6005
diff changeset
23 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
24 if p:
3c9dbb743d20 merge: add registry look up bits to tool search
Matt Mackall <mpm@selenic.com>
parents: 6005
diff changeset
25 return p
6004
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
26 return util.find_exe(_toolstr(ui, tool, "executable", tool))
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
27
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
28 def _picktool(repo, ui, path, binary, symlink):
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
29 def check(tool, pat, symlink, binary):
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
30 tmsg = tool
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
31 if pat:
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
32 tmsg += " specified for " + pat
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
33 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
34 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
35 elif symlink and not _toolbool(ui, tool, "symlink"):
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
36 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
37 elif binary and not _toolbool(ui, tool, "binary"):
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
38 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
39 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
40 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
41 else:
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
42 return True
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
43 return False
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
44
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
45 # HGMERGE takes precedence
6025
f2335246e5c7 filemerge: wrap quotes around tool path
Steve Borho <steve@borho.org>
parents: 6016
diff changeset
46 hgmerge = os.environ.get("HGMERGE")
f2335246e5c7 filemerge: wrap quotes around tool path
Steve Borho <steve@borho.org>
parents: 6016
diff changeset
47 if hgmerge:
f2335246e5c7 filemerge: wrap quotes around tool path
Steve Borho <steve@borho.org>
parents: 6016
diff changeset
48 return (hgmerge, hgmerge)
6004
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
49
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
50 # then patterns
6016
288ec2f6faa2 filemerge: fix pattern matching
dhruva <dhruvakm@gmail.com>
parents: 6015
diff changeset
51 for pat, tool in ui.configitems("merge-patterns"):
6004
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
52 mf = util.matcher(repo.root, "", [pat], [], [])[1]
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
53 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
54 toolpath = _findtool(ui, tool)
f2335246e5c7 filemerge: wrap quotes around tool path
Steve Borho <steve@borho.org>
parents: 6016
diff changeset
55 return (tool, '"' + toolpath + '"')
6004
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
56
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
57 # then merge tools
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
58 tools = {}
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
59 for k,v in ui.configitems("merge-tools"):
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
60 t = k.split('.')[0]
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
61 if t not in tools:
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
62 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
63 names = tools.keys()
6004
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
64 tools = [(-p,t) for t,p in tools.items()]
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
65 tools.sort()
6076
0ee885fea464 filemerge: more backwards compatible behavior for ui.merge
Steve Borho <steve@borho.org>
parents: 6075
diff changeset
66 uimerge = ui.config("ui", "merge")
0ee885fea464 filemerge: more backwards compatible behavior for ui.merge
Steve Borho <steve@borho.org>
parents: 6075
diff changeset
67 if uimerge:
0ee885fea464 filemerge: more backwards compatible behavior for ui.merge
Steve Borho <steve@borho.org>
parents: 6075
diff changeset
68 if uimerge not in names:
0ee885fea464 filemerge: more backwards compatible behavior for ui.merge
Steve Borho <steve@borho.org>
parents: 6075
diff changeset
69 return (uimerge, uimerge)
0ee885fea464 filemerge: more backwards compatible behavior for ui.merge
Steve Borho <steve@borho.org>
parents: 6075
diff changeset
70 tools.insert(0, (None, uimerge)) # highest priority
6004
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
71 tools.append((None, "hgmerge")) # the old default, if found
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
72 for p,t in tools:
6025
f2335246e5c7 filemerge: wrap quotes around tool path
Steve Borho <steve@borho.org>
parents: 6016
diff changeset
73 toolpath = _findtool(ui, t)
f2335246e5c7 filemerge: wrap quotes around tool path
Steve Borho <steve@borho.org>
parents: 6016
diff changeset
74 if toolpath and check(t, None, symlink, binary):
f2335246e5c7 filemerge: wrap quotes around tool path
Steve Borho <steve@borho.org>
parents: 6016
diff changeset
75 return (t, '"' + toolpath + '"')
f2335246e5c7 filemerge: wrap quotes around tool path
Steve Borho <steve@borho.org>
parents: 6016
diff changeset
76 # internal merge as last resort
f2335246e5c7 filemerge: wrap quotes around tool path
Steve Borho <steve@borho.org>
parents: 6016
diff changeset
77 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
78
6005
3c33032d8906 merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents: 6004
diff changeset
79 def _eoltype(data):
3c33032d8906 merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents: 6004
diff changeset
80 "Guess the EOL type of a file"
3c33032d8906 merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents: 6004
diff changeset
81 if '\0' in data: # binary
3c33032d8906 merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents: 6004
diff changeset
82 return None
3c33032d8906 merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents: 6004
diff changeset
83 if '\r\n' in data: # Windows
3c33032d8906 merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents: 6004
diff changeset
84 return '\r\n'
3c33032d8906 merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents: 6004
diff changeset
85 if '\r' in data: # Old Mac
3c33032d8906 merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents: 6004
diff changeset
86 return '\r'
3c33032d8906 merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents: 6004
diff changeset
87 if '\n' in data: # UNIX
3c33032d8906 merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents: 6004
diff changeset
88 return '\n'
3c33032d8906 merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents: 6004
diff changeset
89 return None # unknown
3c33032d8906 merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents: 6004
diff changeset
90
3c33032d8906 merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents: 6004
diff changeset
91 def _matcheol(file, origfile):
3c33032d8906 merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents: 6004
diff changeset
92 "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
93 tostyle = _eoltype(open(origfile, "rb").read())
3c33032d8906 merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents: 6004
diff changeset
94 if tostyle:
3c33032d8906 merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents: 6004
diff changeset
95 data = open(file, "rb").read()
3c33032d8906 merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents: 6004
diff changeset
96 style = _eoltype(data)
3c33032d8906 merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents: 6004
diff changeset
97 if style:
3c33032d8906 merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents: 6004
diff changeset
98 newdata = data.replace(style, tostyle)
3c33032d8906 merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents: 6004
diff changeset
99 if newdata != data:
3c33032d8906 merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents: 6004
diff changeset
100 open(file, "wb").write(newdata)
3c33032d8906 merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents: 6004
diff changeset
101
6003
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
102 def filemerge(repo, fw, fd, fo, wctx, mctx):
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
103 """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
104
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
105 fw = original filename in the working directory
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
106 fd = destination filename in the working directory
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
107 fo = filename in other parent
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
108 wctx, mctx = working and merge changecontexts
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
109 """
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
110
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
111 def temp(prefix, ctx):
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
112 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
113 (fd, name) = tempfile.mkstemp(prefix=pre)
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
114 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
115 f = os.fdopen(fd, "wb")
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
116 f.write(data)
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
117 f.close()
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
118 return name
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
119
6004
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
120 def isbin(ctx):
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
121 try:
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
122 return util.binary(ctx.data())
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
123 except IOError:
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
124 return False
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
125
6003
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
126 fco = mctx.filectx(fo)
6004
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
127 if not fco.cmp(wctx.filectx(fd).data()): # files identical?
6003
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
128 return None
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
129
6004
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
130 ui = repo.ui
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
131 fcm = wctx.filectx(fw)
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
132 fca = fcm.ancestor(fco) or repo.filectx(fw, fileid=nullrev)
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
133 binary = isbin(fcm) or isbin(fco) or isbin(fca)
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
134 symlink = fcm.islink() or fco.islink()
6025
f2335246e5c7 filemerge: wrap quotes around tool path
Steve Borho <steve@borho.org>
parents: 6016
diff changeset
135 tool, toolpath = _picktool(repo, ui, fw, binary, symlink)
6004
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
136 ui.debug(_("picked tool '%s' for %s (binary %s symlink %s)\n") %
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
137 (tool, fw, binary, symlink))
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
138
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
139 if not tool:
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
140 tool = "internal:local"
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
141 if ui.prompt(_(" no tool found to merge %s\n"
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
142 "keep (l)ocal or take (o)ther?") % fw,
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
143 _("[lo]"), _("l")) != _("l"):
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
144 tool = "internal:other"
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
145 if tool == "internal:local":
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
146 return 0
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
147 if tool == "internal:other":
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
148 repo.wwrite(fd, fco.data(), fco.fileflags())
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
149 return 0
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
150 if tool == "internal:fail":
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
151 return 1
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
152
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
153 # do the actual merge
6003
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
154 a = repo.wjoin(fd)
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
155 b = temp("base", fca)
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
156 c = temp("other", fco)
6004
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
157 out = ""
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
158 back = a + ".orig"
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
159 util.copyfile(a, back)
6003
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
160
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
161 if fw != fo:
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
162 repo.ui.status(_("merging %s and %s\n") % (fw, fo))
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
163 else:
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
164 repo.ui.status(_("merging %s\n") % fw)
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
165 repo.ui.debug(_("my %s other %s ancestor %s\n") % (fcm, fco, fca))
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
166
6004
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
167 # do we attempt to simplemerge first?
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
168 if _toolbool(ui, tool, "premerge", not (binary or symlink)):
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
169 r = simplemerge.simplemerge(a, b, c, quiet=True)
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
170 if not r:
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
171 ui.debug(_(" premerge successful\n"))
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
172 os.unlink(back)
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
173 os.unlink(b)
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
174 os.unlink(c)
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
175 return 0
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
176 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
177
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
178 env = dict(HG_FILE=fd,
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
179 HG_MY_NODE=str(wctx.parents()[0]),
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
180 HG_OTHER_NODE=str(mctx),
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
181 HG_MY_ISLINK=fcm.islink(),
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
182 HG_OTHER_ISLINK=fco.islink(),
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
183 HG_BASE_ISLINK=fca.islink())
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
184
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
185 if tool == "internal:merge":
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
186 r = simplemerge.simplemerge(a, b, c, label=['local', 'other'])
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
187 else:
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
188 args = _toolstr(ui, tool, "args", '$local $base $other')
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
189 if "$output" in args:
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
190 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
191 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
192 args = re.sub("\$(local|base|other|output)",
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
193 lambda x: '"%s"' % replace[x.group()[1:]], args)
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
194 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
195
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
196 if not r and _toolbool(ui, tool, "checkconflicts"):
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
197 if re.match("^(<<<<<<< .*|=======|>>>>>>> .*)$", fcm.data()):
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
198 r = 1
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
199
6075
63e0e57ab157 filemerge: add 'checkchanged' merge tool property
Steve Borho <steve@borho.org>
parents: 6025
diff changeset
200 if not r and _toolbool(ui, tool, "checkchanged"):
63e0e57ab157 filemerge: add 'checkchanged' merge tool property
Steve Borho <steve@borho.org>
parents: 6025
diff changeset
201 if filecmp.cmp(repo.wjoin(fd), back):
63e0e57ab157 filemerge: add 'checkchanged' merge tool property
Steve Borho <steve@borho.org>
parents: 6025
diff changeset
202 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
203 "was merge successful (yn)?") % fd,
63e0e57ab157 filemerge: add 'checkchanged' merge tool property
Steve Borho <steve@borho.org>
parents: 6025
diff changeset
204 _("[yn]"), _("n")) != _("y"):
63e0e57ab157 filemerge: add 'checkchanged' merge tool property
Steve Borho <steve@borho.org>
parents: 6025
diff changeset
205 r = 1
63e0e57ab157 filemerge: add 'checkchanged' merge tool property
Steve Borho <steve@borho.org>
parents: 6025
diff changeset
206
6005
3c33032d8906 merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents: 6004
diff changeset
207 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
208 _matcheol(repo.wjoin(fd), back)
6005
3c33032d8906 merge: add support for tool EOL fixups
Matt Mackall <mpm@selenic.com>
parents: 6004
diff changeset
209
6003
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
210 if r:
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
211 repo.ui.warn(_("merging %s failed!\n") % fd)
6004
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
212 else:
5af5f0f9d724 merge: allow smarter tool configuration
Matt Mackall <mpm@selenic.com>
parents: 6003
diff changeset
213 os.unlink(back)
6003
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
214
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
215 os.unlink(b)
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
216 os.unlink(c)
7855b88ba838 filemerge: pull file-merging code into its own module
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
217 return r