##// END OF EJS Templates
filemerge: add a 'leave unresolved' option to regular prompts...
Siddharth Agarwal -
r27162:4ab69be0 default
parent child Browse files
Show More
@@ -1,682 +1,685 b''
1 # filemerge.py - file-level merge handling for Mercurial
1 # filemerge.py - file-level merge handling for Mercurial
2 #
2 #
3 # Copyright 2006, 2007, 2008 Matt Mackall <mpm@selenic.com>
3 # Copyright 2006, 2007, 2008 Matt Mackall <mpm@selenic.com>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 from __future__ import absolute_import
8 from __future__ import absolute_import
9
9
10 import filecmp
10 import filecmp
11 import os
11 import os
12 import re
12 import re
13 import tempfile
13 import tempfile
14
14
15 from .i18n import _
15 from .i18n import _
16 from .node import nullid, short
16 from .node import nullid, short
17
17
18 from . import (
18 from . import (
19 cmdutil,
19 cmdutil,
20 error,
20 error,
21 match,
21 match,
22 simplemerge,
22 simplemerge,
23 tagmerge,
23 tagmerge,
24 templatekw,
24 templatekw,
25 templater,
25 templater,
26 util,
26 util,
27 )
27 )
28
28
29 def _toolstr(ui, tool, part, default=""):
29 def _toolstr(ui, tool, part, default=""):
30 return ui.config("merge-tools", tool + "." + part, default)
30 return ui.config("merge-tools", tool + "." + part, default)
31
31
32 def _toolbool(ui, tool, part, default=False):
32 def _toolbool(ui, tool, part, default=False):
33 return ui.configbool("merge-tools", tool + "." + part, default)
33 return ui.configbool("merge-tools", tool + "." + part, default)
34
34
35 def _toollist(ui, tool, part, default=[]):
35 def _toollist(ui, tool, part, default=[]):
36 return ui.configlist("merge-tools", tool + "." + part, default)
36 return ui.configlist("merge-tools", tool + "." + part, default)
37
37
38 internals = {}
38 internals = {}
39 # Merge tools to document.
39 # Merge tools to document.
40 internalsdoc = {}
40 internalsdoc = {}
41
41
42 # internal tool merge types
42 # internal tool merge types
43 nomerge = None
43 nomerge = None
44 mergeonly = 'mergeonly' # just the full merge, no premerge
44 mergeonly = 'mergeonly' # just the full merge, no premerge
45 fullmerge = 'fullmerge' # both premerge and merge
45 fullmerge = 'fullmerge' # both premerge and merge
46
46
47 class absentfilectx(object):
47 class absentfilectx(object):
48 """Represents a file that's ostensibly in a context but is actually not
48 """Represents a file that's ostensibly in a context but is actually not
49 present in it.
49 present in it.
50
50
51 This is here because it's very specific to the filemerge code for now --
51 This is here because it's very specific to the filemerge code for now --
52 other code is likely going to break with the values this returns."""
52 other code is likely going to break with the values this returns."""
53 def __init__(self, ctx, f):
53 def __init__(self, ctx, f):
54 self._ctx = ctx
54 self._ctx = ctx
55 self._f = f
55 self._f = f
56
56
57 def path(self):
57 def path(self):
58 return self._f
58 return self._f
59
59
60 def size(self):
60 def size(self):
61 return None
61 return None
62
62
63 def data(self):
63 def data(self):
64 return None
64 return None
65
65
66 def filenode(self):
66 def filenode(self):
67 return nullid
67 return nullid
68
68
69 _customcmp = True
69 _customcmp = True
70 def cmp(self, fctx):
70 def cmp(self, fctx):
71 """compare with other file context
71 """compare with other file context
72
72
73 returns True if different from fctx.
73 returns True if different from fctx.
74 """
74 """
75 return not (fctx.isabsent() and
75 return not (fctx.isabsent() and
76 fctx.ctx() == self.ctx() and
76 fctx.ctx() == self.ctx() and
77 fctx.path() == self.path())
77 fctx.path() == self.path())
78
78
79 def flags(self):
79 def flags(self):
80 return ''
80 return ''
81
81
82 def changectx(self):
82 def changectx(self):
83 return self._ctx
83 return self._ctx
84
84
85 def isbinary(self):
85 def isbinary(self):
86 return False
86 return False
87
87
88 def isabsent(self):
88 def isabsent(self):
89 return True
89 return True
90
90
91 def internaltool(name, mergetype, onfailure=None, precheck=None):
91 def internaltool(name, mergetype, onfailure=None, precheck=None):
92 '''return a decorator for populating internal merge tool table'''
92 '''return a decorator for populating internal merge tool table'''
93 def decorator(func):
93 def decorator(func):
94 fullname = ':' + name
94 fullname = ':' + name
95 func.__doc__ = "``%s``\n" % fullname + func.__doc__.strip()
95 func.__doc__ = "``%s``\n" % fullname + func.__doc__.strip()
96 internals[fullname] = func
96 internals[fullname] = func
97 internals['internal:' + name] = func
97 internals['internal:' + name] = func
98 internalsdoc[fullname] = func
98 internalsdoc[fullname] = func
99 func.mergetype = mergetype
99 func.mergetype = mergetype
100 func.onfailure = onfailure
100 func.onfailure = onfailure
101 func.precheck = precheck
101 func.precheck = precheck
102 return func
102 return func
103 return decorator
103 return decorator
104
104
105 def _findtool(ui, tool):
105 def _findtool(ui, tool):
106 if tool in internals:
106 if tool in internals:
107 return tool
107 return tool
108 return findexternaltool(ui, tool)
108 return findexternaltool(ui, tool)
109
109
110 def findexternaltool(ui, tool):
110 def findexternaltool(ui, tool):
111 for kn in ("regkey", "regkeyalt"):
111 for kn in ("regkey", "regkeyalt"):
112 k = _toolstr(ui, tool, kn)
112 k = _toolstr(ui, tool, kn)
113 if not k:
113 if not k:
114 continue
114 continue
115 p = util.lookupreg(k, _toolstr(ui, tool, "regname"))
115 p = util.lookupreg(k, _toolstr(ui, tool, "regname"))
116 if p:
116 if p:
117 p = util.findexe(p + _toolstr(ui, tool, "regappend"))
117 p = util.findexe(p + _toolstr(ui, tool, "regappend"))
118 if p:
118 if p:
119 return p
119 return p
120 exe = _toolstr(ui, tool, "executable", tool)
120 exe = _toolstr(ui, tool, "executable", tool)
121 return util.findexe(util.expandpath(exe))
121 return util.findexe(util.expandpath(exe))
122
122
123 def _picktool(repo, ui, path, binary, symlink, changedelete):
123 def _picktool(repo, ui, path, binary, symlink, changedelete):
124 def supportscd(tool):
124 def supportscd(tool):
125 return tool in internals and internals[tool].mergetype == nomerge
125 return tool in internals and internals[tool].mergetype == nomerge
126
126
127 def check(tool, pat, symlink, binary, changedelete):
127 def check(tool, pat, symlink, binary, changedelete):
128 tmsg = tool
128 tmsg = tool
129 if pat:
129 if pat:
130 tmsg += " specified for " + pat
130 tmsg += " specified for " + pat
131 if not _findtool(ui, tool):
131 if not _findtool(ui, tool):
132 if pat: # explicitly requested tool deserves a warning
132 if pat: # explicitly requested tool deserves a warning
133 ui.warn(_("couldn't find merge tool %s\n") % tmsg)
133 ui.warn(_("couldn't find merge tool %s\n") % tmsg)
134 else: # configured but non-existing tools are more silent
134 else: # configured but non-existing tools are more silent
135 ui.note(_("couldn't find merge tool %s\n") % tmsg)
135 ui.note(_("couldn't find merge tool %s\n") % tmsg)
136 elif symlink and not _toolbool(ui, tool, "symlink"):
136 elif symlink and not _toolbool(ui, tool, "symlink"):
137 ui.warn(_("tool %s can't handle symlinks\n") % tmsg)
137 ui.warn(_("tool %s can't handle symlinks\n") % tmsg)
138 elif binary and not _toolbool(ui, tool, "binary"):
138 elif binary and not _toolbool(ui, tool, "binary"):
139 ui.warn(_("tool %s can't handle binary\n") % tmsg)
139 ui.warn(_("tool %s can't handle binary\n") % tmsg)
140 elif changedelete and not supportscd(tool):
140 elif changedelete and not supportscd(tool):
141 # the nomerge tools are the only tools that support change/delete
141 # the nomerge tools are the only tools that support change/delete
142 # conflicts
142 # conflicts
143 pass
143 pass
144 elif not util.gui() and _toolbool(ui, tool, "gui"):
144 elif not util.gui() and _toolbool(ui, tool, "gui"):
145 ui.warn(_("tool %s requires a GUI\n") % tmsg)
145 ui.warn(_("tool %s requires a GUI\n") % tmsg)
146 else:
146 else:
147 return True
147 return True
148 return False
148 return False
149
149
150 # internal config: ui.forcemerge
150 # internal config: ui.forcemerge
151 # forcemerge comes from command line arguments, highest priority
151 # forcemerge comes from command line arguments, highest priority
152 force = ui.config('ui', 'forcemerge')
152 force = ui.config('ui', 'forcemerge')
153 if force:
153 if force:
154 toolpath = _findtool(ui, force)
154 toolpath = _findtool(ui, force)
155 if changedelete and not supportscd(toolpath):
155 if changedelete and not supportscd(toolpath):
156 return ":prompt", None
156 return ":prompt", None
157 else:
157 else:
158 if toolpath:
158 if toolpath:
159 return (force, util.shellquote(toolpath))
159 return (force, util.shellquote(toolpath))
160 else:
160 else:
161 # mimic HGMERGE if given tool not found
161 # mimic HGMERGE if given tool not found
162 return (force, force)
162 return (force, force)
163
163
164 # HGMERGE takes next precedence
164 # HGMERGE takes next precedence
165 hgmerge = os.environ.get("HGMERGE")
165 hgmerge = os.environ.get("HGMERGE")
166 if hgmerge:
166 if hgmerge:
167 if changedelete and not supportscd(hgmerge):
167 if changedelete and not supportscd(hgmerge):
168 return ":prompt", None
168 return ":prompt", None
169 else:
169 else:
170 return (hgmerge, hgmerge)
170 return (hgmerge, hgmerge)
171
171
172 # then patterns
172 # then patterns
173 for pat, tool in ui.configitems("merge-patterns"):
173 for pat, tool in ui.configitems("merge-patterns"):
174 mf = match.match(repo.root, '', [pat])
174 mf = match.match(repo.root, '', [pat])
175 if mf(path) and check(tool, pat, symlink, False, changedelete):
175 if mf(path) and check(tool, pat, symlink, False, changedelete):
176 toolpath = _findtool(ui, tool)
176 toolpath = _findtool(ui, tool)
177 return (tool, util.shellquote(toolpath))
177 return (tool, util.shellquote(toolpath))
178
178
179 # then merge tools
179 # then merge tools
180 tools = {}
180 tools = {}
181 disabled = set()
181 disabled = set()
182 for k, v in ui.configitems("merge-tools"):
182 for k, v in ui.configitems("merge-tools"):
183 t = k.split('.')[0]
183 t = k.split('.')[0]
184 if t not in tools:
184 if t not in tools:
185 tools[t] = int(_toolstr(ui, t, "priority", "0"))
185 tools[t] = int(_toolstr(ui, t, "priority", "0"))
186 if _toolbool(ui, t, "disabled", False):
186 if _toolbool(ui, t, "disabled", False):
187 disabled.add(t)
187 disabled.add(t)
188 names = tools.keys()
188 names = tools.keys()
189 tools = sorted([(-p, t) for t, p in tools.items() if t not in disabled])
189 tools = sorted([(-p, t) for t, p in tools.items() if t not in disabled])
190 uimerge = ui.config("ui", "merge")
190 uimerge = ui.config("ui", "merge")
191 if uimerge:
191 if uimerge:
192 # external tools defined in uimerge won't be able to handle
192 # external tools defined in uimerge won't be able to handle
193 # change/delete conflicts
193 # change/delete conflicts
194 if uimerge not in names and not changedelete:
194 if uimerge not in names and not changedelete:
195 return (uimerge, uimerge)
195 return (uimerge, uimerge)
196 tools.insert(0, (None, uimerge)) # highest priority
196 tools.insert(0, (None, uimerge)) # highest priority
197 tools.append((None, "hgmerge")) # the old default, if found
197 tools.append((None, "hgmerge")) # the old default, if found
198 for p, t in tools:
198 for p, t in tools:
199 if check(t, None, symlink, binary, changedelete):
199 if check(t, None, symlink, binary, changedelete):
200 toolpath = _findtool(ui, t)
200 toolpath = _findtool(ui, t)
201 return (t, util.shellquote(toolpath))
201 return (t, util.shellquote(toolpath))
202
202
203 # internal merge or prompt as last resort
203 # internal merge or prompt as last resort
204 if symlink or binary or changedelete:
204 if symlink or binary or changedelete:
205 return ":prompt", None
205 return ":prompt", None
206 return ":merge", None
206 return ":merge", None
207
207
208 def _eoltype(data):
208 def _eoltype(data):
209 "Guess the EOL type of a file"
209 "Guess the EOL type of a file"
210 if '\0' in data: # binary
210 if '\0' in data: # binary
211 return None
211 return None
212 if '\r\n' in data: # Windows
212 if '\r\n' in data: # Windows
213 return '\r\n'
213 return '\r\n'
214 if '\r' in data: # Old Mac
214 if '\r' in data: # Old Mac
215 return '\r'
215 return '\r'
216 if '\n' in data: # UNIX
216 if '\n' in data: # UNIX
217 return '\n'
217 return '\n'
218 return None # unknown
218 return None # unknown
219
219
220 def _matcheol(file, origfile):
220 def _matcheol(file, origfile):
221 "Convert EOL markers in a file to match origfile"
221 "Convert EOL markers in a file to match origfile"
222 tostyle = _eoltype(util.readfile(origfile))
222 tostyle = _eoltype(util.readfile(origfile))
223 if tostyle:
223 if tostyle:
224 data = util.readfile(file)
224 data = util.readfile(file)
225 style = _eoltype(data)
225 style = _eoltype(data)
226 if style:
226 if style:
227 newdata = data.replace(style, tostyle)
227 newdata = data.replace(style, tostyle)
228 if newdata != data:
228 if newdata != data:
229 util.writefile(file, newdata)
229 util.writefile(file, newdata)
230
230
231 @internaltool('prompt', nomerge)
231 @internaltool('prompt', nomerge)
232 def _iprompt(repo, mynode, orig, fcd, fco, fca, toolconf):
232 def _iprompt(repo, mynode, orig, fcd, fco, fca, toolconf):
233 """Asks the user which of the local or the other version to keep as
233 """Asks the user which of the local or the other version to keep as
234 the merged version."""
234 the merged version."""
235 ui = repo.ui
235 ui = repo.ui
236 fd = fcd.path()
236 fd = fcd.path()
237
237
238 try:
238 try:
239 if fco.isabsent():
239 if fco.isabsent():
240 index = ui.promptchoice(
240 index = ui.promptchoice(
241 _("local changed %s which remote deleted\n"
241 _("local changed %s which remote deleted\n"
242 "use (c)hanged version or (d)elete?"
242 "use (c)hanged version or (d)elete?"
243 "$$ &Changed $$ &Delete") % fd, 0)
243 "$$ &Changed $$ &Delete") % fd, 0)
244 choice = ['local', 'other'][index]
244 choice = ['local', 'other'][index]
245 elif fcd.isabsent():
245 elif fcd.isabsent():
246 index = ui.promptchoice(
246 index = ui.promptchoice(
247 _("remote changed %s which local deleted\n"
247 _("remote changed %s which local deleted\n"
248 "use (c)hanged version or leave (d)eleted?"
248 "use (c)hanged version or leave (d)eleted?"
249 "$$ &Changed $$ &Deleted") % fd, 0)
249 "$$ &Changed $$ &Deleted") % fd, 0)
250 choice = ['other', 'local'][index]
250 choice = ['other', 'local'][index]
251 else:
251 else:
252 index = ui.promptchoice(_("no tool found to merge %s\n"
252 index = ui.promptchoice(
253 "keep (l)ocal or take (o)ther?"
253 _("no tool found to merge %s\n"
254 "$$ &Local $$ &Other") % fd, 0)
254 "keep (l)ocal, take (o)ther, or leave (u)nresolved?"
255 choice = ['local', 'other'][index]
255 "$$ &Local $$ &Other $$ &Unresolved") % fd, 0)
256 choice = ['local', 'other', 'unresolved'][index]
256
257
257 if choice == 'other':
258 if choice == 'other':
258 return _iother(repo, mynode, orig, fcd, fco, fca, toolconf)
259 return _iother(repo, mynode, orig, fcd, fco, fca, toolconf)
259 else:
260 elif choice == 'local':
260 return _ilocal(repo, mynode, orig, fcd, fco, fca, toolconf)
261 return _ilocal(repo, mynode, orig, fcd, fco, fca, toolconf)
262 elif choice == 'unresolved':
263 return _ifail(repo, mynode, orig, fcd, fco, fca, toolconf)
261 except error.ResponseExpected:
264 except error.ResponseExpected:
262 ui.write("\n")
265 ui.write("\n")
263 return _ifail(repo, mynode, orig, fcd, fco, fca, toolconf)
266 return _ifail(repo, mynode, orig, fcd, fco, fca, toolconf)
264
267
265 @internaltool('local', nomerge)
268 @internaltool('local', nomerge)
266 def _ilocal(repo, mynode, orig, fcd, fco, fca, toolconf):
269 def _ilocal(repo, mynode, orig, fcd, fco, fca, toolconf):
267 """Uses the local version of files as the merged version."""
270 """Uses the local version of files as the merged version."""
268 return 0, fcd.isabsent()
271 return 0, fcd.isabsent()
269
272
270 @internaltool('other', nomerge)
273 @internaltool('other', nomerge)
271 def _iother(repo, mynode, orig, fcd, fco, fca, toolconf):
274 def _iother(repo, mynode, orig, fcd, fco, fca, toolconf):
272 """Uses the other version of files as the merged version."""
275 """Uses the other version of files as the merged version."""
273 if fco.isabsent():
276 if fco.isabsent():
274 # local changed, remote deleted -- 'deleted' picked
277 # local changed, remote deleted -- 'deleted' picked
275 repo.wvfs.unlinkpath(fcd.path())
278 repo.wvfs.unlinkpath(fcd.path())
276 deleted = True
279 deleted = True
277 else:
280 else:
278 repo.wwrite(fcd.path(), fco.data(), fco.flags())
281 repo.wwrite(fcd.path(), fco.data(), fco.flags())
279 deleted = False
282 deleted = False
280 return 0, deleted
283 return 0, deleted
281
284
282 @internaltool('fail', nomerge)
285 @internaltool('fail', nomerge)
283 def _ifail(repo, mynode, orig, fcd, fco, fca, toolconf):
286 def _ifail(repo, mynode, orig, fcd, fco, fca, toolconf):
284 """
287 """
285 Rather than attempting to merge files that were modified on both
288 Rather than attempting to merge files that were modified on both
286 branches, it marks them as unresolved. The resolve command must be
289 branches, it marks them as unresolved. The resolve command must be
287 used to resolve these conflicts."""
290 used to resolve these conflicts."""
288 # for change/delete conflicts write out the changed version, then fail
291 # for change/delete conflicts write out the changed version, then fail
289 if fcd.isabsent():
292 if fcd.isabsent():
290 repo.wwrite(fcd.path(), fco.data(), fco.flags())
293 repo.wwrite(fcd.path(), fco.data(), fco.flags())
291 return 1, False
294 return 1, False
292
295
293 def _premerge(repo, fcd, fco, fca, toolconf, files, labels=None):
296 def _premerge(repo, fcd, fco, fca, toolconf, files, labels=None):
294 tool, toolpath, binary, symlink = toolconf
297 tool, toolpath, binary, symlink = toolconf
295 if symlink or fcd.isabsent() or fco.isabsent():
298 if symlink or fcd.isabsent() or fco.isabsent():
296 return 1
299 return 1
297 a, b, c, back = files
300 a, b, c, back = files
298
301
299 ui = repo.ui
302 ui = repo.ui
300
303
301 validkeep = ['keep', 'keep-merge3']
304 validkeep = ['keep', 'keep-merge3']
302
305
303 # do we attempt to simplemerge first?
306 # do we attempt to simplemerge first?
304 try:
307 try:
305 premerge = _toolbool(ui, tool, "premerge", not binary)
308 premerge = _toolbool(ui, tool, "premerge", not binary)
306 except error.ConfigError:
309 except error.ConfigError:
307 premerge = _toolstr(ui, tool, "premerge").lower()
310 premerge = _toolstr(ui, tool, "premerge").lower()
308 if premerge not in validkeep:
311 if premerge not in validkeep:
309 _valid = ', '.join(["'" + v + "'" for v in validkeep])
312 _valid = ', '.join(["'" + v + "'" for v in validkeep])
310 raise error.ConfigError(_("%s.premerge not valid "
313 raise error.ConfigError(_("%s.premerge not valid "
311 "('%s' is neither boolean nor %s)") %
314 "('%s' is neither boolean nor %s)") %
312 (tool, premerge, _valid))
315 (tool, premerge, _valid))
313
316
314 if premerge:
317 if premerge:
315 if premerge == 'keep-merge3':
318 if premerge == 'keep-merge3':
316 if not labels:
319 if not labels:
317 labels = _defaultconflictlabels
320 labels = _defaultconflictlabels
318 if len(labels) < 3:
321 if len(labels) < 3:
319 labels.append('base')
322 labels.append('base')
320 r = simplemerge.simplemerge(ui, a, b, c, quiet=True, label=labels)
323 r = simplemerge.simplemerge(ui, a, b, c, quiet=True, label=labels)
321 if not r:
324 if not r:
322 ui.debug(" premerge successful\n")
325 ui.debug(" premerge successful\n")
323 return 0
326 return 0
324 if premerge not in validkeep:
327 if premerge not in validkeep:
325 util.copyfile(back, a) # restore from backup and try again
328 util.copyfile(back, a) # restore from backup and try again
326 return 1 # continue merging
329 return 1 # continue merging
327
330
328 def _mergecheck(repo, mynode, orig, fcd, fco, fca, toolconf):
331 def _mergecheck(repo, mynode, orig, fcd, fco, fca, toolconf):
329 tool, toolpath, binary, symlink = toolconf
332 tool, toolpath, binary, symlink = toolconf
330 if symlink:
333 if symlink:
331 repo.ui.warn(_('warning: internal %s cannot merge symlinks '
334 repo.ui.warn(_('warning: internal %s cannot merge symlinks '
332 'for %s\n') % (tool, fcd.path()))
335 'for %s\n') % (tool, fcd.path()))
333 return False
336 return False
334 if fcd.isabsent() or fco.isabsent():
337 if fcd.isabsent() or fco.isabsent():
335 repo.ui.warn(_('warning: internal %s cannot merge change/delete '
338 repo.ui.warn(_('warning: internal %s cannot merge change/delete '
336 'conflict for %s\n') % (tool, fcd.path()))
339 'conflict for %s\n') % (tool, fcd.path()))
337 return False
340 return False
338 return True
341 return True
339
342
340 def _merge(repo, mynode, orig, fcd, fco, fca, toolconf, files, labels, mode):
343 def _merge(repo, mynode, orig, fcd, fco, fca, toolconf, files, labels, mode):
341 """
344 """
342 Uses the internal non-interactive simple merge algorithm for merging
345 Uses the internal non-interactive simple merge algorithm for merging
343 files. It will fail if there are any conflicts and leave markers in
346 files. It will fail if there are any conflicts and leave markers in
344 the partially merged file. Markers will have two sections, one for each side
347 the partially merged file. Markers will have two sections, one for each side
345 of merge, unless mode equals 'union' which suppresses the markers."""
348 of merge, unless mode equals 'union' which suppresses the markers."""
346 a, b, c, back = files
349 a, b, c, back = files
347
350
348 ui = repo.ui
351 ui = repo.ui
349
352
350 r = simplemerge.simplemerge(ui, a, b, c, label=labels, mode=mode)
353 r = simplemerge.simplemerge(ui, a, b, c, label=labels, mode=mode)
351 return True, r, False
354 return True, r, False
352
355
353 @internaltool('union', fullmerge,
356 @internaltool('union', fullmerge,
354 _("warning: conflicts while merging %s! "
357 _("warning: conflicts while merging %s! "
355 "(edit, then use 'hg resolve --mark')\n"),
358 "(edit, then use 'hg resolve --mark')\n"),
356 precheck=_mergecheck)
359 precheck=_mergecheck)
357 def _iunion(repo, mynode, orig, fcd, fco, fca, toolconf, files, labels=None):
360 def _iunion(repo, mynode, orig, fcd, fco, fca, toolconf, files, labels=None):
358 """
361 """
359 Uses the internal non-interactive simple merge algorithm for merging
362 Uses the internal non-interactive simple merge algorithm for merging
360 files. It will use both left and right sides for conflict regions.
363 files. It will use both left and right sides for conflict regions.
361 No markers are inserted."""
364 No markers are inserted."""
362 return _merge(repo, mynode, orig, fcd, fco, fca, toolconf,
365 return _merge(repo, mynode, orig, fcd, fco, fca, toolconf,
363 files, labels, 'union')
366 files, labels, 'union')
364
367
365 @internaltool('merge', fullmerge,
368 @internaltool('merge', fullmerge,
366 _("warning: conflicts while merging %s! "
369 _("warning: conflicts while merging %s! "
367 "(edit, then use 'hg resolve --mark')\n"),
370 "(edit, then use 'hg resolve --mark')\n"),
368 precheck=_mergecheck)
371 precheck=_mergecheck)
369 def _imerge(repo, mynode, orig, fcd, fco, fca, toolconf, files, labels=None):
372 def _imerge(repo, mynode, orig, fcd, fco, fca, toolconf, files, labels=None):
370 """
373 """
371 Uses the internal non-interactive simple merge algorithm for merging
374 Uses the internal non-interactive simple merge algorithm for merging
372 files. It will fail if there are any conflicts and leave markers in
375 files. It will fail if there are any conflicts and leave markers in
373 the partially merged file. Markers will have two sections, one for each side
376 the partially merged file. Markers will have two sections, one for each side
374 of merge."""
377 of merge."""
375 return _merge(repo, mynode, orig, fcd, fco, fca, toolconf,
378 return _merge(repo, mynode, orig, fcd, fco, fca, toolconf,
376 files, labels, 'merge')
379 files, labels, 'merge')
377
380
378 @internaltool('merge3', fullmerge,
381 @internaltool('merge3', fullmerge,
379 _("warning: conflicts while merging %s! "
382 _("warning: conflicts while merging %s! "
380 "(edit, then use 'hg resolve --mark')\n"),
383 "(edit, then use 'hg resolve --mark')\n"),
381 precheck=_mergecheck)
384 precheck=_mergecheck)
382 def _imerge3(repo, mynode, orig, fcd, fco, fca, toolconf, files, labels=None):
385 def _imerge3(repo, mynode, orig, fcd, fco, fca, toolconf, files, labels=None):
383 """
386 """
384 Uses the internal non-interactive simple merge algorithm for merging
387 Uses the internal non-interactive simple merge algorithm for merging
385 files. It will fail if there are any conflicts and leave markers in
388 files. It will fail if there are any conflicts and leave markers in
386 the partially merged file. Marker will have three sections, one from each
389 the partially merged file. Marker will have three sections, one from each
387 side of the merge and one for the base content."""
390 side of the merge and one for the base content."""
388 if not labels:
391 if not labels:
389 labels = _defaultconflictlabels
392 labels = _defaultconflictlabels
390 if len(labels) < 3:
393 if len(labels) < 3:
391 labels.append('base')
394 labels.append('base')
392 return _imerge(repo, mynode, orig, fcd, fco, fca, toolconf, files, labels)
395 return _imerge(repo, mynode, orig, fcd, fco, fca, toolconf, files, labels)
393
396
394 def _imergeauto(repo, mynode, orig, fcd, fco, fca, toolconf, files,
397 def _imergeauto(repo, mynode, orig, fcd, fco, fca, toolconf, files,
395 labels=None, localorother=None):
398 labels=None, localorother=None):
396 """
399 """
397 Generic driver for _imergelocal and _imergeother
400 Generic driver for _imergelocal and _imergeother
398 """
401 """
399 assert localorother is not None
402 assert localorother is not None
400 tool, toolpath, binary, symlink = toolconf
403 tool, toolpath, binary, symlink = toolconf
401 a, b, c, back = files
404 a, b, c, back = files
402 r = simplemerge.simplemerge(repo.ui, a, b, c, label=labels,
405 r = simplemerge.simplemerge(repo.ui, a, b, c, label=labels,
403 localorother=localorother)
406 localorother=localorother)
404 return True, r
407 return True, r
405
408
406 @internaltool('merge-local', mergeonly, precheck=_mergecheck)
409 @internaltool('merge-local', mergeonly, precheck=_mergecheck)
407 def _imergelocal(*args, **kwargs):
410 def _imergelocal(*args, **kwargs):
408 """
411 """
409 Like :merge, but resolve all conflicts non-interactively in favor
412 Like :merge, but resolve all conflicts non-interactively in favor
410 of the local changes."""
413 of the local changes."""
411 success, status = _imergeauto(localorother='local', *args, **kwargs)
414 success, status = _imergeauto(localorother='local', *args, **kwargs)
412 return success, status, False
415 return success, status, False
413
416
414 @internaltool('merge-other', mergeonly, precheck=_mergecheck)
417 @internaltool('merge-other', mergeonly, precheck=_mergecheck)
415 def _imergeother(*args, **kwargs):
418 def _imergeother(*args, **kwargs):
416 """
419 """
417 Like :merge, but resolve all conflicts non-interactively in favor
420 Like :merge, but resolve all conflicts non-interactively in favor
418 of the other changes."""
421 of the other changes."""
419 success, status = _imergeauto(localorother='other', *args, **kwargs)
422 success, status = _imergeauto(localorother='other', *args, **kwargs)
420 return success, status, False
423 return success, status, False
421
424
422 @internaltool('tagmerge', mergeonly,
425 @internaltool('tagmerge', mergeonly,
423 _("automatic tag merging of %s failed! "
426 _("automatic tag merging of %s failed! "
424 "(use 'hg resolve --tool :merge' or another merge "
427 "(use 'hg resolve --tool :merge' or another merge "
425 "tool of your choice)\n"))
428 "tool of your choice)\n"))
426 def _itagmerge(repo, mynode, orig, fcd, fco, fca, toolconf, files, labels=None):
429 def _itagmerge(repo, mynode, orig, fcd, fco, fca, toolconf, files, labels=None):
427 """
430 """
428 Uses the internal tag merge algorithm (experimental).
431 Uses the internal tag merge algorithm (experimental).
429 """
432 """
430 success, status = tagmerge.merge(repo, fcd, fco, fca)
433 success, status = tagmerge.merge(repo, fcd, fco, fca)
431 return success, status, False
434 return success, status, False
432
435
433 @internaltool('dump', fullmerge)
436 @internaltool('dump', fullmerge)
434 def _idump(repo, mynode, orig, fcd, fco, fca, toolconf, files, labels=None):
437 def _idump(repo, mynode, orig, fcd, fco, fca, toolconf, files, labels=None):
435 """
438 """
436 Creates three versions of the files to merge, containing the
439 Creates three versions of the files to merge, containing the
437 contents of local, other and base. These files can then be used to
440 contents of local, other and base. These files can then be used to
438 perform a merge manually. If the file to be merged is named
441 perform a merge manually. If the file to be merged is named
439 ``a.txt``, these files will accordingly be named ``a.txt.local``,
442 ``a.txt``, these files will accordingly be named ``a.txt.local``,
440 ``a.txt.other`` and ``a.txt.base`` and they will be placed in the
443 ``a.txt.other`` and ``a.txt.base`` and they will be placed in the
441 same directory as ``a.txt``."""
444 same directory as ``a.txt``."""
442 a, b, c, back = files
445 a, b, c, back = files
443
446
444 fd = fcd.path()
447 fd = fcd.path()
445
448
446 util.copyfile(a, a + ".local")
449 util.copyfile(a, a + ".local")
447 repo.wwrite(fd + ".other", fco.data(), fco.flags())
450 repo.wwrite(fd + ".other", fco.data(), fco.flags())
448 repo.wwrite(fd + ".base", fca.data(), fca.flags())
451 repo.wwrite(fd + ".base", fca.data(), fca.flags())
449 return False, 1, False
452 return False, 1, False
450
453
451 def _xmerge(repo, mynode, orig, fcd, fco, fca, toolconf, files, labels=None):
454 def _xmerge(repo, mynode, orig, fcd, fco, fca, toolconf, files, labels=None):
452 tool, toolpath, binary, symlink = toolconf
455 tool, toolpath, binary, symlink = toolconf
453 if fcd.isabsent() or fco.isabsent():
456 if fcd.isabsent() or fco.isabsent():
454 repo.ui.warn(_('warning: %s cannot merge change/delete conflict '
457 repo.ui.warn(_('warning: %s cannot merge change/delete conflict '
455 'for %s\n') % (tool, fcd.path()))
458 'for %s\n') % (tool, fcd.path()))
456 return False, 1, None
459 return False, 1, None
457 a, b, c, back = files
460 a, b, c, back = files
458 out = ""
461 out = ""
459 env = {'HG_FILE': fcd.path(),
462 env = {'HG_FILE': fcd.path(),
460 'HG_MY_NODE': short(mynode),
463 'HG_MY_NODE': short(mynode),
461 'HG_OTHER_NODE': str(fco.changectx()),
464 'HG_OTHER_NODE': str(fco.changectx()),
462 'HG_BASE_NODE': str(fca.changectx()),
465 'HG_BASE_NODE': str(fca.changectx()),
463 'HG_MY_ISLINK': 'l' in fcd.flags(),
466 'HG_MY_ISLINK': 'l' in fcd.flags(),
464 'HG_OTHER_ISLINK': 'l' in fco.flags(),
467 'HG_OTHER_ISLINK': 'l' in fco.flags(),
465 'HG_BASE_ISLINK': 'l' in fca.flags(),
468 'HG_BASE_ISLINK': 'l' in fca.flags(),
466 }
469 }
467
470
468 ui = repo.ui
471 ui = repo.ui
469
472
470 args = _toolstr(ui, tool, "args", '$local $base $other')
473 args = _toolstr(ui, tool, "args", '$local $base $other')
471 if "$output" in args:
474 if "$output" in args:
472 out, a = a, back # read input from backup, write to original
475 out, a = a, back # read input from backup, write to original
473 replace = {'local': a, 'base': b, 'other': c, 'output': out}
476 replace = {'local': a, 'base': b, 'other': c, 'output': out}
474 args = util.interpolate(r'\$', replace, args,
477 args = util.interpolate(r'\$', replace, args,
475 lambda s: util.shellquote(util.localpath(s)))
478 lambda s: util.shellquote(util.localpath(s)))
476 cmd = toolpath + ' ' + args
479 cmd = toolpath + ' ' + args
477 repo.ui.debug('launching merge tool: %s\n' % cmd)
480 repo.ui.debug('launching merge tool: %s\n' % cmd)
478 r = ui.system(cmd, cwd=repo.root, environ=env)
481 r = ui.system(cmd, cwd=repo.root, environ=env)
479 repo.ui.debug('merge tool returned: %s\n' % r)
482 repo.ui.debug('merge tool returned: %s\n' % r)
480 return True, r, False
483 return True, r, False
481
484
482 def _formatconflictmarker(repo, ctx, template, label, pad):
485 def _formatconflictmarker(repo, ctx, template, label, pad):
483 """Applies the given template to the ctx, prefixed by the label.
486 """Applies the given template to the ctx, prefixed by the label.
484
487
485 Pad is the minimum width of the label prefix, so that multiple markers
488 Pad is the minimum width of the label prefix, so that multiple markers
486 can have aligned templated parts.
489 can have aligned templated parts.
487 """
490 """
488 if ctx.node() is None:
491 if ctx.node() is None:
489 ctx = ctx.p1()
492 ctx = ctx.p1()
490
493
491 props = templatekw.keywords.copy()
494 props = templatekw.keywords.copy()
492 props['templ'] = template
495 props['templ'] = template
493 props['ctx'] = ctx
496 props['ctx'] = ctx
494 props['repo'] = repo
497 props['repo'] = repo
495 templateresult = template('conflictmarker', **props)
498 templateresult = template('conflictmarker', **props)
496
499
497 label = ('%s:' % label).ljust(pad + 1)
500 label = ('%s:' % label).ljust(pad + 1)
498 mark = '%s %s' % (label, templater.stringify(templateresult))
501 mark = '%s %s' % (label, templater.stringify(templateresult))
499
502
500 if mark:
503 if mark:
501 mark = mark.splitlines()[0] # split for safety
504 mark = mark.splitlines()[0] # split for safety
502
505
503 # 8 for the prefix of conflict marker lines (e.g. '<<<<<<< ')
506 # 8 for the prefix of conflict marker lines (e.g. '<<<<<<< ')
504 return util.ellipsis(mark, 80 - 8)
507 return util.ellipsis(mark, 80 - 8)
505
508
506 _defaultconflictmarker = ('{node|short} ' +
509 _defaultconflictmarker = ('{node|short} ' +
507 '{ifeq(tags, "tip", "", "{tags} ")}' +
510 '{ifeq(tags, "tip", "", "{tags} ")}' +
508 '{if(bookmarks, "{bookmarks} ")}' +
511 '{if(bookmarks, "{bookmarks} ")}' +
509 '{ifeq(branch, "default", "", "{branch} ")}' +
512 '{ifeq(branch, "default", "", "{branch} ")}' +
510 '- {author|user}: {desc|firstline}')
513 '- {author|user}: {desc|firstline}')
511
514
512 _defaultconflictlabels = ['local', 'other']
515 _defaultconflictlabels = ['local', 'other']
513
516
514 def _formatlabels(repo, fcd, fco, fca, labels):
517 def _formatlabels(repo, fcd, fco, fca, labels):
515 """Formats the given labels using the conflict marker template.
518 """Formats the given labels using the conflict marker template.
516
519
517 Returns a list of formatted labels.
520 Returns a list of formatted labels.
518 """
521 """
519 cd = fcd.changectx()
522 cd = fcd.changectx()
520 co = fco.changectx()
523 co = fco.changectx()
521 ca = fca.changectx()
524 ca = fca.changectx()
522
525
523 ui = repo.ui
526 ui = repo.ui
524 template = ui.config('ui', 'mergemarkertemplate', _defaultconflictmarker)
527 template = ui.config('ui', 'mergemarkertemplate', _defaultconflictmarker)
525 tmpl = templater.templater(None, cache={'conflictmarker': template})
528 tmpl = templater.templater(None, cache={'conflictmarker': template})
526
529
527 pad = max(len(l) for l in labels)
530 pad = max(len(l) for l in labels)
528
531
529 newlabels = [_formatconflictmarker(repo, cd, tmpl, labels[0], pad),
532 newlabels = [_formatconflictmarker(repo, cd, tmpl, labels[0], pad),
530 _formatconflictmarker(repo, co, tmpl, labels[1], pad)]
533 _formatconflictmarker(repo, co, tmpl, labels[1], pad)]
531 if len(labels) > 2:
534 if len(labels) > 2:
532 newlabels.append(_formatconflictmarker(repo, ca, tmpl, labels[2], pad))
535 newlabels.append(_formatconflictmarker(repo, ca, tmpl, labels[2], pad))
533 return newlabels
536 return newlabels
534
537
535 def _filemerge(premerge, repo, mynode, orig, fcd, fco, fca, labels=None):
538 def _filemerge(premerge, repo, mynode, orig, fcd, fco, fca, labels=None):
536 """perform a 3-way merge in the working directory
539 """perform a 3-way merge in the working directory
537
540
538 premerge = whether this is a premerge
541 premerge = whether this is a premerge
539 mynode = parent node before merge
542 mynode = parent node before merge
540 orig = original local filename before merge
543 orig = original local filename before merge
541 fco = other file context
544 fco = other file context
542 fca = ancestor file context
545 fca = ancestor file context
543 fcd = local file context for current/destination file
546 fcd = local file context for current/destination file
544
547
545 Returns whether the merge is complete, the return value of the merge, and
548 Returns whether the merge is complete, the return value of the merge, and
546 a boolean indicating whether the file was deleted from disk."""
549 a boolean indicating whether the file was deleted from disk."""
547
550
548 def temp(prefix, ctx):
551 def temp(prefix, ctx):
549 pre = "%s~%s." % (os.path.basename(ctx.path()), prefix)
552 pre = "%s~%s." % (os.path.basename(ctx.path()), prefix)
550 (fd, name) = tempfile.mkstemp(prefix=pre)
553 (fd, name) = tempfile.mkstemp(prefix=pre)
551 data = repo.wwritedata(ctx.path(), ctx.data())
554 data = repo.wwritedata(ctx.path(), ctx.data())
552 f = os.fdopen(fd, "wb")
555 f = os.fdopen(fd, "wb")
553 f.write(data)
556 f.write(data)
554 f.close()
557 f.close()
555 return name
558 return name
556
559
557 if not fco.cmp(fcd): # files identical?
560 if not fco.cmp(fcd): # files identical?
558 return True, None, False
561 return True, None, False
559
562
560 ui = repo.ui
563 ui = repo.ui
561 fd = fcd.path()
564 fd = fcd.path()
562 binary = fcd.isbinary() or fco.isbinary() or fca.isbinary()
565 binary = fcd.isbinary() or fco.isbinary() or fca.isbinary()
563 symlink = 'l' in fcd.flags() + fco.flags()
566 symlink = 'l' in fcd.flags() + fco.flags()
564 changedelete = fcd.isabsent() or fco.isabsent()
567 changedelete = fcd.isabsent() or fco.isabsent()
565 tool, toolpath = _picktool(repo, ui, fd, binary, symlink, changedelete)
568 tool, toolpath = _picktool(repo, ui, fd, binary, symlink, changedelete)
566 if tool in internals and tool.startswith('internal:'):
569 if tool in internals and tool.startswith('internal:'):
567 # normalize to new-style names (':merge' etc)
570 # normalize to new-style names (':merge' etc)
568 tool = tool[len('internal'):]
571 tool = tool[len('internal'):]
569 ui.debug("picked tool '%s' for %s (binary %s symlink %s changedelete %s)\n"
572 ui.debug("picked tool '%s' for %s (binary %s symlink %s changedelete %s)\n"
570 % (tool, fd, binary, symlink, changedelete))
573 % (tool, fd, binary, symlink, changedelete))
571
574
572 if tool in internals:
575 if tool in internals:
573 func = internals[tool]
576 func = internals[tool]
574 mergetype = func.mergetype
577 mergetype = func.mergetype
575 onfailure = func.onfailure
578 onfailure = func.onfailure
576 precheck = func.precheck
579 precheck = func.precheck
577 else:
580 else:
578 func = _xmerge
581 func = _xmerge
579 mergetype = fullmerge
582 mergetype = fullmerge
580 onfailure = _("merging %s failed!\n")
583 onfailure = _("merging %s failed!\n")
581 precheck = None
584 precheck = None
582
585
583 toolconf = tool, toolpath, binary, symlink
586 toolconf = tool, toolpath, binary, symlink
584
587
585 if mergetype == nomerge:
588 if mergetype == nomerge:
586 r, deleted = func(repo, mynode, orig, fcd, fco, fca, toolconf)
589 r, deleted = func(repo, mynode, orig, fcd, fco, fca, toolconf)
587 return True, r, deleted
590 return True, r, deleted
588
591
589 if premerge:
592 if premerge:
590 if orig != fco.path():
593 if orig != fco.path():
591 ui.status(_("merging %s and %s to %s\n") % (orig, fco.path(), fd))
594 ui.status(_("merging %s and %s to %s\n") % (orig, fco.path(), fd))
592 else:
595 else:
593 ui.status(_("merging %s\n") % fd)
596 ui.status(_("merging %s\n") % fd)
594
597
595 ui.debug("my %s other %s ancestor %s\n" % (fcd, fco, fca))
598 ui.debug("my %s other %s ancestor %s\n" % (fcd, fco, fca))
596
599
597 if precheck and not precheck(repo, mynode, orig, fcd, fco, fca,
600 if precheck and not precheck(repo, mynode, orig, fcd, fco, fca,
598 toolconf):
601 toolconf):
599 if onfailure:
602 if onfailure:
600 ui.warn(onfailure % fd)
603 ui.warn(onfailure % fd)
601 return True, 1, False
604 return True, 1, False
602
605
603 a = repo.wjoin(fd)
606 a = repo.wjoin(fd)
604 b = temp("base", fca)
607 b = temp("base", fca)
605 c = temp("other", fco)
608 c = temp("other", fco)
606 if not fcd.isabsent():
609 if not fcd.isabsent():
607 back = cmdutil.origpath(ui, repo, a)
610 back = cmdutil.origpath(ui, repo, a)
608 if premerge:
611 if premerge:
609 util.copyfile(a, back)
612 util.copyfile(a, back)
610 else:
613 else:
611 back = None
614 back = None
612 files = (a, b, c, back)
615 files = (a, b, c, back)
613
616
614 r = 1
617 r = 1
615 try:
618 try:
616 markerstyle = ui.config('ui', 'mergemarkers', 'basic')
619 markerstyle = ui.config('ui', 'mergemarkers', 'basic')
617 if not labels:
620 if not labels:
618 labels = _defaultconflictlabels
621 labels = _defaultconflictlabels
619 if markerstyle != 'basic':
622 if markerstyle != 'basic':
620 labels = _formatlabels(repo, fcd, fco, fca, labels)
623 labels = _formatlabels(repo, fcd, fco, fca, labels)
621
624
622 if premerge and mergetype == fullmerge:
625 if premerge and mergetype == fullmerge:
623 r = _premerge(repo, fcd, fco, fca, toolconf, files, labels=labels)
626 r = _premerge(repo, fcd, fco, fca, toolconf, files, labels=labels)
624 # complete if premerge successful (r is 0)
627 # complete if premerge successful (r is 0)
625 return not r, r, False
628 return not r, r, False
626
629
627 needcheck, r, deleted = func(repo, mynode, orig, fcd, fco, fca,
630 needcheck, r, deleted = func(repo, mynode, orig, fcd, fco, fca,
628 toolconf, files, labels=labels)
631 toolconf, files, labels=labels)
629
632
630 if needcheck:
633 if needcheck:
631 r = _check(r, ui, tool, fcd, files)
634 r = _check(r, ui, tool, fcd, files)
632
635
633 if r:
636 if r:
634 if onfailure:
637 if onfailure:
635 ui.warn(onfailure % fd)
638 ui.warn(onfailure % fd)
636
639
637 return True, r, deleted
640 return True, r, deleted
638 finally:
641 finally:
639 if not r and back is not None:
642 if not r and back is not None:
640 util.unlink(back)
643 util.unlink(back)
641 util.unlink(b)
644 util.unlink(b)
642 util.unlink(c)
645 util.unlink(c)
643
646
644 def _check(r, ui, tool, fcd, files):
647 def _check(r, ui, tool, fcd, files):
645 fd = fcd.path()
648 fd = fcd.path()
646 a, b, c, back = files
649 a, b, c, back = files
647
650
648 if not r and (_toolbool(ui, tool, "checkconflicts") or
651 if not r and (_toolbool(ui, tool, "checkconflicts") or
649 'conflicts' in _toollist(ui, tool, "check")):
652 'conflicts' in _toollist(ui, tool, "check")):
650 if re.search("^(<<<<<<< .*|=======|>>>>>>> .*)$", fcd.data(),
653 if re.search("^(<<<<<<< .*|=======|>>>>>>> .*)$", fcd.data(),
651 re.MULTILINE):
654 re.MULTILINE):
652 r = 1
655 r = 1
653
656
654 checked = False
657 checked = False
655 if 'prompt' in _toollist(ui, tool, "check"):
658 if 'prompt' in _toollist(ui, tool, "check"):
656 checked = True
659 checked = True
657 if ui.promptchoice(_("was merge of '%s' successful (yn)?"
660 if ui.promptchoice(_("was merge of '%s' successful (yn)?"
658 "$$ &Yes $$ &No") % fd, 1):
661 "$$ &Yes $$ &No") % fd, 1):
659 r = 1
662 r = 1
660
663
661 if not r and not checked and (_toolbool(ui, tool, "checkchanged") or
664 if not r and not checked and (_toolbool(ui, tool, "checkchanged") or
662 'changed' in
665 'changed' in
663 _toollist(ui, tool, "check")):
666 _toollist(ui, tool, "check")):
664 if back is not None and filecmp.cmp(a, back):
667 if back is not None and filecmp.cmp(a, back):
665 if ui.promptchoice(_(" output file %s appears unchanged\n"
668 if ui.promptchoice(_(" output file %s appears unchanged\n"
666 "was merge successful (yn)?"
669 "was merge successful (yn)?"
667 "$$ &Yes $$ &No") % fd, 1):
670 "$$ &Yes $$ &No") % fd, 1):
668 r = 1
671 r = 1
669
672
670 if back is not None and _toolbool(ui, tool, "fixeol"):
673 if back is not None and _toolbool(ui, tool, "fixeol"):
671 _matcheol(a, back)
674 _matcheol(a, back)
672
675
673 return r
676 return r
674
677
675 def premerge(repo, mynode, orig, fcd, fco, fca, labels=None):
678 def premerge(repo, mynode, orig, fcd, fco, fca, labels=None):
676 return _filemerge(True, repo, mynode, orig, fcd, fco, fca, labels=labels)
679 return _filemerge(True, repo, mynode, orig, fcd, fco, fca, labels=labels)
677
680
678 def filemerge(repo, mynode, orig, fcd, fco, fca, labels=None):
681 def filemerge(repo, mynode, orig, fcd, fco, fca, labels=None):
679 return _filemerge(False, repo, mynode, orig, fcd, fco, fca, labels=labels)
682 return _filemerge(False, repo, mynode, orig, fcd, fco, fca, labels=labels)
680
683
681 # tell hggettext to extract docstrings from these functions:
684 # tell hggettext to extract docstrings from these functions:
682 i18nfunctions = internals.values()
685 i18nfunctions = internals.values()
@@ -1,987 +1,987 b''
1 Tests for change/delete conflicts, including:
1 Tests for change/delete conflicts, including:
2 b5605d88dc27: Make ui.prompt repeat on "unrecognized response" again
2 b5605d88dc27: Make ui.prompt repeat on "unrecognized response" again
3 (issue897)
3 (issue897)
4
4
5 840e2b315c1f: Fix misleading error and prompts during update/merge
5 840e2b315c1f: Fix misleading error and prompts during update/merge
6 (issue556)
6 (issue556)
7
7
8 Make sure HGMERGE doesn't interfere with the test
8 Make sure HGMERGE doesn't interfere with the test
9 $ unset HGMERGE
9 $ unset HGMERGE
10
10
11 $ status() {
11 $ status() {
12 > echo "--- status ---"
12 > echo "--- status ---"
13 > hg st -A file1 file2 file3
13 > hg st -A file1 file2 file3
14 > echo "--- resolve --list ---"
14 > echo "--- resolve --list ---"
15 > hg resolve --list file1 file2 file3
15 > hg resolve --list file1 file2 file3
16 > echo "--- debugmergestate ---"
16 > echo "--- debugmergestate ---"
17 > hg debugmergestate
17 > hg debugmergestate
18 > for file in file1 file2 file3; do
18 > for file in file1 file2 file3; do
19 > if [ -f $file ]; then
19 > if [ -f $file ]; then
20 > echo "--- $file ---"
20 > echo "--- $file ---"
21 > cat $file
21 > cat $file
22 > else
22 > else
23 > echo "*** $file does not exist"
23 > echo "*** $file does not exist"
24 > fi
24 > fi
25 > done
25 > done
26 > }
26 > }
27
27
28 $ hg init repo
28 $ hg init repo
29 $ cd repo
29 $ cd repo
30
30
31 $ echo 1 > file1
31 $ echo 1 > file1
32 $ echo 2 > file2
32 $ echo 2 > file2
33 $ echo 3 > file3
33 $ echo 3 > file3
34 $ hg ci -Am 'added files'
34 $ hg ci -Am 'added files'
35 adding file1
35 adding file1
36 adding file2
36 adding file2
37 adding file3
37 adding file3
38
38
39 $ hg rm file1
39 $ hg rm file1
40 $ echo changed >> file2
40 $ echo changed >> file2
41 $ echo changed1 >> file3
41 $ echo changed1 >> file3
42 $ hg ci -m 'removed file1, changed file2, changed file3'
42 $ hg ci -m 'removed file1, changed file2, changed file3'
43
43
44 $ hg co 0
44 $ hg co 0
45 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
45 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
46
46
47 $ echo changed >> file1
47 $ echo changed >> file1
48 $ hg rm file2
48 $ hg rm file2
49 $ echo changed2 >> file3
49 $ echo changed2 >> file3
50 $ hg ci -m 'changed file1, removed file2, changed file3'
50 $ hg ci -m 'changed file1, removed file2, changed file3'
51 created new head
51 created new head
52
52
53
53
54 Non-interactive merge:
54 Non-interactive merge:
55
55
56 $ hg merge -y
56 $ hg merge -y
57 local changed file1 which remote deleted
57 local changed file1 which remote deleted
58 use (c)hanged version or (d)elete? c
58 use (c)hanged version or (d)elete? c
59 remote changed file2 which local deleted
59 remote changed file2 which local deleted
60 use (c)hanged version or leave (d)eleted? c
60 use (c)hanged version or leave (d)eleted? c
61 merging file3
61 merging file3
62 warning: conflicts while merging file3! (edit, then use 'hg resolve --mark')
62 warning: conflicts while merging file3! (edit, then use 'hg resolve --mark')
63 0 files updated, 2 files merged, 0 files removed, 1 files unresolved
63 0 files updated, 2 files merged, 0 files removed, 1 files unresolved
64 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
64 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
65 [1]
65 [1]
66
66
67 $ status
67 $ status
68 --- status ---
68 --- status ---
69 M file2
69 M file2
70 M file3
70 M file3
71 C file1
71 C file1
72 --- resolve --list ---
72 --- resolve --list ---
73 R file1
73 R file1
74 R file2
74 R file2
75 U file3
75 U file3
76 --- debugmergestate ---
76 --- debugmergestate ---
77 * version 2 records
77 * version 2 records
78 local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
78 local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
79 other: 10f9a0a634e82080907e62f075ab119cbc565ea6
79 other: 10f9a0a634e82080907e62f075ab119cbc565ea6
80 file: file1 (record type "C", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
80 file: file1 (record type "C", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
81 local path: file1 (flags "")
81 local path: file1 (flags "")
82 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
82 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
83 other path: file1 (node null)
83 other path: file1 (node null)
84 file: file2 (record type "C", state "r", hash null)
84 file: file2 (record type "C", state "r", hash null)
85 local path: file2 (flags "")
85 local path: file2 (flags "")
86 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
86 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
87 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
87 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
88 file: file3 (record type "F", state "u", hash d5b0a58bc47161b1b8a831084b366f757c4f0b11)
88 file: file3 (record type "F", state "u", hash d5b0a58bc47161b1b8a831084b366f757c4f0b11)
89 local path: file3 (flags "")
89 local path: file3 (flags "")
90 ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
90 ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
91 other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
91 other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
92 --- file1 ---
92 --- file1 ---
93 1
93 1
94 changed
94 changed
95 --- file2 ---
95 --- file2 ---
96 2
96 2
97 changed
97 changed
98 --- file3 ---
98 --- file3 ---
99 3
99 3
100 <<<<<<< local: 13910f48cf7b - test: changed file1, removed file2, changed file3
100 <<<<<<< local: 13910f48cf7b - test: changed file1, removed file2, changed file3
101 changed2
101 changed2
102 =======
102 =======
103 changed1
103 changed1
104 >>>>>>> other: 10f9a0a634e8 - test: removed file1, changed file2, changed file3
104 >>>>>>> other: 10f9a0a634e8 - test: removed file1, changed file2, changed file3
105
105
106
106
107 Interactive merge:
107 Interactive merge:
108
108
109 $ hg co -C
109 $ hg co -C
110 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
110 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
111
111
112 $ hg merge --config ui.interactive=true <<EOF
112 $ hg merge --config ui.interactive=true <<EOF
113 > c
113 > c
114 > d
114 > d
115 > EOF
115 > EOF
116 local changed file1 which remote deleted
116 local changed file1 which remote deleted
117 use (c)hanged version or (d)elete? c
117 use (c)hanged version or (d)elete? c
118 remote changed file2 which local deleted
118 remote changed file2 which local deleted
119 use (c)hanged version or leave (d)eleted? d
119 use (c)hanged version or leave (d)eleted? d
120 merging file3
120 merging file3
121 warning: conflicts while merging file3! (edit, then use 'hg resolve --mark')
121 warning: conflicts while merging file3! (edit, then use 'hg resolve --mark')
122 0 files updated, 2 files merged, 0 files removed, 1 files unresolved
122 0 files updated, 2 files merged, 0 files removed, 1 files unresolved
123 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
123 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
124 [1]
124 [1]
125
125
126 $ status
126 $ status
127 --- status ---
127 --- status ---
128 file2: * (glob)
128 file2: * (glob)
129 M file3
129 M file3
130 C file1
130 C file1
131 --- resolve --list ---
131 --- resolve --list ---
132 R file1
132 R file1
133 R file2
133 R file2
134 U file3
134 U file3
135 --- debugmergestate ---
135 --- debugmergestate ---
136 * version 2 records
136 * version 2 records
137 local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
137 local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
138 other: 10f9a0a634e82080907e62f075ab119cbc565ea6
138 other: 10f9a0a634e82080907e62f075ab119cbc565ea6
139 file: file1 (record type "C", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
139 file: file1 (record type "C", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
140 local path: file1 (flags "")
140 local path: file1 (flags "")
141 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
141 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
142 other path: file1 (node null)
142 other path: file1 (node null)
143 file: file2 (record type "C", state "r", hash null)
143 file: file2 (record type "C", state "r", hash null)
144 local path: file2 (flags "")
144 local path: file2 (flags "")
145 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
145 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
146 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
146 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
147 file: file3 (record type "F", state "u", hash d5b0a58bc47161b1b8a831084b366f757c4f0b11)
147 file: file3 (record type "F", state "u", hash d5b0a58bc47161b1b8a831084b366f757c4f0b11)
148 local path: file3 (flags "")
148 local path: file3 (flags "")
149 ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
149 ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
150 other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
150 other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
151 --- file1 ---
151 --- file1 ---
152 1
152 1
153 changed
153 changed
154 *** file2 does not exist
154 *** file2 does not exist
155 --- file3 ---
155 --- file3 ---
156 3
156 3
157 <<<<<<< local: 13910f48cf7b - test: changed file1, removed file2, changed file3
157 <<<<<<< local: 13910f48cf7b - test: changed file1, removed file2, changed file3
158 changed2
158 changed2
159 =======
159 =======
160 changed1
160 changed1
161 >>>>>>> other: 10f9a0a634e8 - test: removed file1, changed file2, changed file3
161 >>>>>>> other: 10f9a0a634e8 - test: removed file1, changed file2, changed file3
162
162
163
163
164 Interactive merge with bad input:
164 Interactive merge with bad input:
165
165
166 $ hg co -C
166 $ hg co -C
167 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
167 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
168
168
169 $ hg merge --config ui.interactive=true <<EOF
169 $ hg merge --config ui.interactive=true <<EOF
170 > foo
170 > foo
171 > bar
171 > bar
172 > d
172 > d
173 > baz
173 > baz
174 > c
174 > c
175 > EOF
175 > EOF
176 local changed file1 which remote deleted
176 local changed file1 which remote deleted
177 use (c)hanged version or (d)elete? foo
177 use (c)hanged version or (d)elete? foo
178 unrecognized response
178 unrecognized response
179 local changed file1 which remote deleted
179 local changed file1 which remote deleted
180 use (c)hanged version or (d)elete? bar
180 use (c)hanged version or (d)elete? bar
181 unrecognized response
181 unrecognized response
182 local changed file1 which remote deleted
182 local changed file1 which remote deleted
183 use (c)hanged version or (d)elete? d
183 use (c)hanged version or (d)elete? d
184 remote changed file2 which local deleted
184 remote changed file2 which local deleted
185 use (c)hanged version or leave (d)eleted? baz
185 use (c)hanged version or leave (d)eleted? baz
186 unrecognized response
186 unrecognized response
187 remote changed file2 which local deleted
187 remote changed file2 which local deleted
188 use (c)hanged version or leave (d)eleted? c
188 use (c)hanged version or leave (d)eleted? c
189 merging file3
189 merging file3
190 warning: conflicts while merging file3! (edit, then use 'hg resolve --mark')
190 warning: conflicts while merging file3! (edit, then use 'hg resolve --mark')
191 0 files updated, 1 files merged, 1 files removed, 1 files unresolved
191 0 files updated, 1 files merged, 1 files removed, 1 files unresolved
192 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
192 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
193 [1]
193 [1]
194
194
195 $ status
195 $ status
196 --- status ---
196 --- status ---
197 M file2
197 M file2
198 M file3
198 M file3
199 R file1
199 R file1
200 --- resolve --list ---
200 --- resolve --list ---
201 R file1
201 R file1
202 R file2
202 R file2
203 U file3
203 U file3
204 --- debugmergestate ---
204 --- debugmergestate ---
205 * version 2 records
205 * version 2 records
206 local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
206 local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
207 other: 10f9a0a634e82080907e62f075ab119cbc565ea6
207 other: 10f9a0a634e82080907e62f075ab119cbc565ea6
208 file: file1 (record type "C", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
208 file: file1 (record type "C", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
209 local path: file1 (flags "")
209 local path: file1 (flags "")
210 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
210 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
211 other path: file1 (node null)
211 other path: file1 (node null)
212 file: file2 (record type "C", state "r", hash null)
212 file: file2 (record type "C", state "r", hash null)
213 local path: file2 (flags "")
213 local path: file2 (flags "")
214 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
214 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
215 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
215 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
216 file: file3 (record type "F", state "u", hash d5b0a58bc47161b1b8a831084b366f757c4f0b11)
216 file: file3 (record type "F", state "u", hash d5b0a58bc47161b1b8a831084b366f757c4f0b11)
217 local path: file3 (flags "")
217 local path: file3 (flags "")
218 ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
218 ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
219 other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
219 other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
220 *** file1 does not exist
220 *** file1 does not exist
221 --- file2 ---
221 --- file2 ---
222 2
222 2
223 changed
223 changed
224 --- file3 ---
224 --- file3 ---
225 3
225 3
226 <<<<<<< local: 13910f48cf7b - test: changed file1, removed file2, changed file3
226 <<<<<<< local: 13910f48cf7b - test: changed file1, removed file2, changed file3
227 changed2
227 changed2
228 =======
228 =======
229 changed1
229 changed1
230 >>>>>>> other: 10f9a0a634e8 - test: removed file1, changed file2, changed file3
230 >>>>>>> other: 10f9a0a634e8 - test: removed file1, changed file2, changed file3
231
231
232
232
233 Interactive merge with not enough input:
233 Interactive merge with not enough input:
234
234
235 $ hg co -C
235 $ hg co -C
236 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
236 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
237
237
238 $ hg merge --config ui.interactive=true <<EOF
238 $ hg merge --config ui.interactive=true <<EOF
239 > d
239 > d
240 > EOF
240 > EOF
241 local changed file1 which remote deleted
241 local changed file1 which remote deleted
242 use (c)hanged version or (d)elete? d
242 use (c)hanged version or (d)elete? d
243 remote changed file2 which local deleted
243 remote changed file2 which local deleted
244 use (c)hanged version or leave (d)eleted?
244 use (c)hanged version or leave (d)eleted?
245 merging file3
245 merging file3
246 warning: conflicts while merging file3! (edit, then use 'hg resolve --mark')
246 warning: conflicts while merging file3! (edit, then use 'hg resolve --mark')
247 0 files updated, 0 files merged, 1 files removed, 2 files unresolved
247 0 files updated, 0 files merged, 1 files removed, 2 files unresolved
248 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
248 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
249 [1]
249 [1]
250
250
251 $ status
251 $ status
252 --- status ---
252 --- status ---
253 M file2
253 M file2
254 M file3
254 M file3
255 R file1
255 R file1
256 --- resolve --list ---
256 --- resolve --list ---
257 R file1
257 R file1
258 U file2
258 U file2
259 U file3
259 U file3
260 --- debugmergestate ---
260 --- debugmergestate ---
261 * version 2 records
261 * version 2 records
262 local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
262 local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
263 other: 10f9a0a634e82080907e62f075ab119cbc565ea6
263 other: 10f9a0a634e82080907e62f075ab119cbc565ea6
264 file: file1 (record type "C", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
264 file: file1 (record type "C", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
265 local path: file1 (flags "")
265 local path: file1 (flags "")
266 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
266 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
267 other path: file1 (node null)
267 other path: file1 (node null)
268 file: file2 (record type "C", state "u", hash null)
268 file: file2 (record type "C", state "u", hash null)
269 local path: file2 (flags "")
269 local path: file2 (flags "")
270 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
270 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
271 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
271 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
272 file: file3 (record type "F", state "u", hash d5b0a58bc47161b1b8a831084b366f757c4f0b11)
272 file: file3 (record type "F", state "u", hash d5b0a58bc47161b1b8a831084b366f757c4f0b11)
273 local path: file3 (flags "")
273 local path: file3 (flags "")
274 ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
274 ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
275 other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
275 other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
276 *** file1 does not exist
276 *** file1 does not exist
277 --- file2 ---
277 --- file2 ---
278 2
278 2
279 changed
279 changed
280 --- file3 ---
280 --- file3 ---
281 3
281 3
282 <<<<<<< local: 13910f48cf7b - test: changed file1, removed file2, changed file3
282 <<<<<<< local: 13910f48cf7b - test: changed file1, removed file2, changed file3
283 changed2
283 changed2
284 =======
284 =======
285 changed1
285 changed1
286 >>>>>>> other: 10f9a0a634e8 - test: removed file1, changed file2, changed file3
286 >>>>>>> other: 10f9a0a634e8 - test: removed file1, changed file2, changed file3
287
287
288 Choose local versions of files
288 Choose local versions of files
289
289
290 $ hg co -C
290 $ hg co -C
291 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
291 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
292
292
293 $ hg merge --tool :local
293 $ hg merge --tool :local
294 0 files updated, 3 files merged, 0 files removed, 0 files unresolved
294 0 files updated, 3 files merged, 0 files removed, 0 files unresolved
295 (branch merge, don't forget to commit)
295 (branch merge, don't forget to commit)
296 $ status 2>&1 | tee $TESTTMP/local.status
296 $ status 2>&1 | tee $TESTTMP/local.status
297 --- status ---
297 --- status ---
298 file2: * (glob)
298 file2: * (glob)
299 M file3
299 M file3
300 C file1
300 C file1
301 --- resolve --list ---
301 --- resolve --list ---
302 R file1
302 R file1
303 R file2
303 R file2
304 R file3
304 R file3
305 --- debugmergestate ---
305 --- debugmergestate ---
306 * version 2 records
306 * version 2 records
307 local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
307 local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
308 other: 10f9a0a634e82080907e62f075ab119cbc565ea6
308 other: 10f9a0a634e82080907e62f075ab119cbc565ea6
309 file: file1 (record type "C", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
309 file: file1 (record type "C", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
310 local path: file1 (flags "")
310 local path: file1 (flags "")
311 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
311 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
312 other path: file1 (node null)
312 other path: file1 (node null)
313 file: file2 (record type "C", state "r", hash null)
313 file: file2 (record type "C", state "r", hash null)
314 local path: file2 (flags "")
314 local path: file2 (flags "")
315 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
315 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
316 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
316 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
317 file: file3 (record type "F", state "r", hash d5b0a58bc47161b1b8a831084b366f757c4f0b11)
317 file: file3 (record type "F", state "r", hash d5b0a58bc47161b1b8a831084b366f757c4f0b11)
318 local path: file3 (flags "")
318 local path: file3 (flags "")
319 ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
319 ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
320 other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
320 other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
321 --- file1 ---
321 --- file1 ---
322 1
322 1
323 changed
323 changed
324 *** file2 does not exist
324 *** file2 does not exist
325 --- file3 ---
325 --- file3 ---
326 3
326 3
327 changed2
327 changed2
328
328
329 Choose other versions of files
329 Choose other versions of files
330
330
331 $ hg co -C
331 $ hg co -C
332 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
332 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
333
333
334 $ hg merge --tool :other
334 $ hg merge --tool :other
335 0 files updated, 2 files merged, 1 files removed, 0 files unresolved
335 0 files updated, 2 files merged, 1 files removed, 0 files unresolved
336 (branch merge, don't forget to commit)
336 (branch merge, don't forget to commit)
337 $ status 2>&1 | tee $TESTTMP/other.status
337 $ status 2>&1 | tee $TESTTMP/other.status
338 --- status ---
338 --- status ---
339 M file2
339 M file2
340 M file3
340 M file3
341 R file1
341 R file1
342 --- resolve --list ---
342 --- resolve --list ---
343 R file1
343 R file1
344 R file2
344 R file2
345 R file3
345 R file3
346 --- debugmergestate ---
346 --- debugmergestate ---
347 * version 2 records
347 * version 2 records
348 local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
348 local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
349 other: 10f9a0a634e82080907e62f075ab119cbc565ea6
349 other: 10f9a0a634e82080907e62f075ab119cbc565ea6
350 file: file1 (record type "C", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
350 file: file1 (record type "C", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
351 local path: file1 (flags "")
351 local path: file1 (flags "")
352 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
352 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
353 other path: file1 (node null)
353 other path: file1 (node null)
354 file: file2 (record type "C", state "r", hash null)
354 file: file2 (record type "C", state "r", hash null)
355 local path: file2 (flags "")
355 local path: file2 (flags "")
356 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
356 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
357 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
357 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
358 file: file3 (record type "F", state "r", hash d5b0a58bc47161b1b8a831084b366f757c4f0b11)
358 file: file3 (record type "F", state "r", hash d5b0a58bc47161b1b8a831084b366f757c4f0b11)
359 local path: file3 (flags "")
359 local path: file3 (flags "")
360 ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
360 ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
361 other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
361 other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
362 *** file1 does not exist
362 *** file1 does not exist
363 --- file2 ---
363 --- file2 ---
364 2
364 2
365 changed
365 changed
366 --- file3 ---
366 --- file3 ---
367 3
367 3
368 changed1
368 changed1
369
369
370 Fail
370 Fail
371
371
372 $ hg co -C
372 $ hg co -C
373 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
373 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
374
374
375 $ hg merge --tool :fail
375 $ hg merge --tool :fail
376 0 files updated, 0 files merged, 0 files removed, 3 files unresolved
376 0 files updated, 0 files merged, 0 files removed, 3 files unresolved
377 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
377 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
378 [1]
378 [1]
379 $ status 2>&1 | tee $TESTTMP/fail.status
379 $ status 2>&1 | tee $TESTTMP/fail.status
380 --- status ---
380 --- status ---
381 M file2
381 M file2
382 M file3
382 M file3
383 C file1
383 C file1
384 --- resolve --list ---
384 --- resolve --list ---
385 U file1
385 U file1
386 U file2
386 U file2
387 U file3
387 U file3
388 --- debugmergestate ---
388 --- debugmergestate ---
389 * version 2 records
389 * version 2 records
390 local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
390 local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
391 other: 10f9a0a634e82080907e62f075ab119cbc565ea6
391 other: 10f9a0a634e82080907e62f075ab119cbc565ea6
392 file: file1 (record type "C", state "u", hash 60b27f004e454aca81b0480209cce5081ec52390)
392 file: file1 (record type "C", state "u", hash 60b27f004e454aca81b0480209cce5081ec52390)
393 local path: file1 (flags "")
393 local path: file1 (flags "")
394 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
394 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
395 other path: file1 (node null)
395 other path: file1 (node null)
396 file: file2 (record type "C", state "u", hash null)
396 file: file2 (record type "C", state "u", hash null)
397 local path: file2 (flags "")
397 local path: file2 (flags "")
398 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
398 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
399 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
399 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
400 file: file3 (record type "F", state "u", hash d5b0a58bc47161b1b8a831084b366f757c4f0b11)
400 file: file3 (record type "F", state "u", hash d5b0a58bc47161b1b8a831084b366f757c4f0b11)
401 local path: file3 (flags "")
401 local path: file3 (flags "")
402 ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
402 ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
403 other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
403 other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
404 --- file1 ---
404 --- file1 ---
405 1
405 1
406 changed
406 changed
407 --- file2 ---
407 --- file2 ---
408 2
408 2
409 changed
409 changed
410 --- file3 ---
410 --- file3 ---
411 3
411 3
412 changed2
412 changed2
413
413
414 Force prompts with no input (should be similar to :fail)
414 Force prompts with no input (should be similar to :fail)
415
415
416 $ hg co -C
416 $ hg co -C
417 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
417 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
418
418
419 $ hg merge --config ui.interactive=True --tool :prompt
419 $ hg merge --config ui.interactive=True --tool :prompt
420 local changed file1 which remote deleted
420 local changed file1 which remote deleted
421 use (c)hanged version or (d)elete?
421 use (c)hanged version or (d)elete?
422 remote changed file2 which local deleted
422 remote changed file2 which local deleted
423 use (c)hanged version or leave (d)eleted?
423 use (c)hanged version or leave (d)eleted?
424 no tool found to merge file3
424 no tool found to merge file3
425 keep (l)ocal or take (o)ther?
425 keep (l)ocal, take (o)ther, or leave (u)nresolved?
426 0 files updated, 0 files merged, 0 files removed, 3 files unresolved
426 0 files updated, 0 files merged, 0 files removed, 3 files unresolved
427 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
427 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
428 [1]
428 [1]
429 $ status 2>&1 | tee $TESTTMP/prompt.status
429 $ status 2>&1 | tee $TESTTMP/prompt.status
430 --- status ---
430 --- status ---
431 M file2
431 M file2
432 M file3
432 M file3
433 C file1
433 C file1
434 --- resolve --list ---
434 --- resolve --list ---
435 U file1
435 U file1
436 U file2
436 U file2
437 U file3
437 U file3
438 --- debugmergestate ---
438 --- debugmergestate ---
439 * version 2 records
439 * version 2 records
440 local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
440 local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
441 other: 10f9a0a634e82080907e62f075ab119cbc565ea6
441 other: 10f9a0a634e82080907e62f075ab119cbc565ea6
442 file: file1 (record type "C", state "u", hash 60b27f004e454aca81b0480209cce5081ec52390)
442 file: file1 (record type "C", state "u", hash 60b27f004e454aca81b0480209cce5081ec52390)
443 local path: file1 (flags "")
443 local path: file1 (flags "")
444 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
444 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
445 other path: file1 (node null)
445 other path: file1 (node null)
446 file: file2 (record type "C", state "u", hash null)
446 file: file2 (record type "C", state "u", hash null)
447 local path: file2 (flags "")
447 local path: file2 (flags "")
448 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
448 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
449 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
449 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
450 file: file3 (record type "F", state "u", hash d5b0a58bc47161b1b8a831084b366f757c4f0b11)
450 file: file3 (record type "F", state "u", hash d5b0a58bc47161b1b8a831084b366f757c4f0b11)
451 local path: file3 (flags "")
451 local path: file3 (flags "")
452 ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
452 ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
453 other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
453 other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
454 --- file1 ---
454 --- file1 ---
455 1
455 1
456 changed
456 changed
457 --- file2 ---
457 --- file2 ---
458 2
458 2
459 changed
459 changed
460 --- file3 ---
460 --- file3 ---
461 3
461 3
462 changed2
462 changed2
463 $ diff -U8 $TESTTMP/fail.status $TESTTMP/prompt.status
463 $ diff -U8 $TESTTMP/fail.status $TESTTMP/prompt.status
464
464
465
465
466 Force prompts
466 Force prompts
467
467
468 $ hg co -C
468 $ hg co -C
469 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
469 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
470
470
471 $ hg merge --tool :prompt
471 $ hg merge --tool :prompt
472 local changed file1 which remote deleted
472 local changed file1 which remote deleted
473 use (c)hanged version or (d)elete? c
473 use (c)hanged version or (d)elete? c
474 remote changed file2 which local deleted
474 remote changed file2 which local deleted
475 use (c)hanged version or leave (d)eleted? c
475 use (c)hanged version or leave (d)eleted? c
476 no tool found to merge file3
476 no tool found to merge file3
477 keep (l)ocal or take (o)ther? l
477 keep (l)ocal, take (o)ther, or leave (u)nresolved? l
478 0 files updated, 3 files merged, 0 files removed, 0 files unresolved
478 0 files updated, 3 files merged, 0 files removed, 0 files unresolved
479 (branch merge, don't forget to commit)
479 (branch merge, don't forget to commit)
480 $ status
480 $ status
481 --- status ---
481 --- status ---
482 M file2
482 M file2
483 M file3
483 M file3
484 C file1
484 C file1
485 --- resolve --list ---
485 --- resolve --list ---
486 R file1
486 R file1
487 R file2
487 R file2
488 R file3
488 R file3
489 --- debugmergestate ---
489 --- debugmergestate ---
490 * version 2 records
490 * version 2 records
491 local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
491 local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
492 other: 10f9a0a634e82080907e62f075ab119cbc565ea6
492 other: 10f9a0a634e82080907e62f075ab119cbc565ea6
493 file: file1 (record type "C", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
493 file: file1 (record type "C", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
494 local path: file1 (flags "")
494 local path: file1 (flags "")
495 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
495 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
496 other path: file1 (node null)
496 other path: file1 (node null)
497 file: file2 (record type "C", state "r", hash null)
497 file: file2 (record type "C", state "r", hash null)
498 local path: file2 (flags "")
498 local path: file2 (flags "")
499 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
499 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
500 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
500 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
501 file: file3 (record type "F", state "r", hash d5b0a58bc47161b1b8a831084b366f757c4f0b11)
501 file: file3 (record type "F", state "r", hash d5b0a58bc47161b1b8a831084b366f757c4f0b11)
502 local path: file3 (flags "")
502 local path: file3 (flags "")
503 ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
503 ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
504 other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
504 other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
505 --- file1 ---
505 --- file1 ---
506 1
506 1
507 changed
507 changed
508 --- file2 ---
508 --- file2 ---
509 2
509 2
510 changed
510 changed
511 --- file3 ---
511 --- file3 ---
512 3
512 3
513 changed2
513 changed2
514
514
515 Choose to merge all files
515 Choose to merge all files
516
516
517 $ hg co -C
517 $ hg co -C
518 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
518 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
519
519
520 $ hg merge --tool :merge3
520 $ hg merge --tool :merge3
521 local changed file1 which remote deleted
521 local changed file1 which remote deleted
522 use (c)hanged version or (d)elete? c
522 use (c)hanged version or (d)elete? c
523 remote changed file2 which local deleted
523 remote changed file2 which local deleted
524 use (c)hanged version or leave (d)eleted? c
524 use (c)hanged version or leave (d)eleted? c
525 merging file3
525 merging file3
526 warning: conflicts while merging file3! (edit, then use 'hg resolve --mark')
526 warning: conflicts while merging file3! (edit, then use 'hg resolve --mark')
527 0 files updated, 2 files merged, 0 files removed, 1 files unresolved
527 0 files updated, 2 files merged, 0 files removed, 1 files unresolved
528 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
528 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
529 [1]
529 [1]
530 $ status
530 $ status
531 --- status ---
531 --- status ---
532 M file2
532 M file2
533 M file3
533 M file3
534 C file1
534 C file1
535 --- resolve --list ---
535 --- resolve --list ---
536 R file1
536 R file1
537 R file2
537 R file2
538 U file3
538 U file3
539 --- debugmergestate ---
539 --- debugmergestate ---
540 * version 2 records
540 * version 2 records
541 local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
541 local: 13910f48cf7bdb2a0ba6e24b4900e4fdd5739dd4
542 other: 10f9a0a634e82080907e62f075ab119cbc565ea6
542 other: 10f9a0a634e82080907e62f075ab119cbc565ea6
543 file: file1 (record type "C", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
543 file: file1 (record type "C", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
544 local path: file1 (flags "")
544 local path: file1 (flags "")
545 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
545 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
546 other path: file1 (node null)
546 other path: file1 (node null)
547 file: file2 (record type "C", state "r", hash null)
547 file: file2 (record type "C", state "r", hash null)
548 local path: file2 (flags "")
548 local path: file2 (flags "")
549 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
549 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
550 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
550 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
551 file: file3 (record type "F", state "u", hash d5b0a58bc47161b1b8a831084b366f757c4f0b11)
551 file: file3 (record type "F", state "u", hash d5b0a58bc47161b1b8a831084b366f757c4f0b11)
552 local path: file3 (flags "")
552 local path: file3 (flags "")
553 ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
553 ancestor path: file3 (node 2661d26c649684b482d10f91960cc3db683c38b4)
554 other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
554 other path: file3 (node a2644c43e210356772c7772a8674544a62e06beb)
555 --- file1 ---
555 --- file1 ---
556 1
556 1
557 changed
557 changed
558 --- file2 ---
558 --- file2 ---
559 2
559 2
560 changed
560 changed
561 --- file3 ---
561 --- file3 ---
562 3
562 3
563 <<<<<<< local: 13910f48cf7b - test: changed file1, removed file2, changed file3
563 <<<<<<< local: 13910f48cf7b - test: changed file1, removed file2, changed file3
564 changed2
564 changed2
565 ||||||| base
565 ||||||| base
566 =======
566 =======
567 changed1
567 changed1
568 >>>>>>> other: 10f9a0a634e8 - test: removed file1, changed file2, changed file3
568 >>>>>>> other: 10f9a0a634e8 - test: removed file1, changed file2, changed file3
569
569
570 Exercise transitions between local, other, fail and prompt, and make sure the
570 Exercise transitions between local, other, fail and prompt, and make sure the
571 dirstate stays consistent. (Compare with each other and to the above
571 dirstate stays consistent. (Compare with each other and to the above
572 invocations.)
572 invocations.)
573
573
574 $ testtransitions() {
574 $ testtransitions() {
575 > # this traversal order covers every transition
575 > # this traversal order covers every transition
576 > tools="local other prompt local fail other local prompt other fail prompt fail local"
576 > tools="local other prompt local fail other local prompt other fail prompt fail local"
577 > lasttool="merge3"
577 > lasttool="merge3"
578 > for tool in $tools; do
578 > for tool in $tools; do
579 > echo "=== :$lasttool -> :$tool ==="
579 > echo "=== :$lasttool -> :$tool ==="
580 > ref="$TESTTMP/$tool.status"
580 > ref="$TESTTMP/$tool.status"
581 > hg resolve --unmark --all
581 > hg resolve --unmark --all
582 > hg resolve --tool ":$tool" --all --config ui.interactive=True
582 > hg resolve --tool ":$tool" --all --config ui.interactive=True
583 > status > "$TESTTMP/compare.status" 2>&1
583 > status > "$TESTTMP/compare.status" 2>&1
584 > echo '--- diff of status ---'
584 > echo '--- diff of status ---'
585 > if diff -U8 "$TESTTMP/$tool.status" "$TESTTMP/compare.status"; then
585 > if diff -U8 "$TESTTMP/$tool.status" "$TESTTMP/compare.status"; then
586 > echo '(status identical)'
586 > echo '(status identical)'
587 > fi
587 > fi
588 > lasttool="$tool"
588 > lasttool="$tool"
589 > echo
589 > echo
590 > done
590 > done
591 > }
591 > }
592
592
593 $ testtransitions
593 $ testtransitions
594 === :merge3 -> :local ===
594 === :merge3 -> :local ===
595 (no more unresolved files)
595 (no more unresolved files)
596 --- diff of status ---
596 --- diff of status ---
597 (status identical)
597 (status identical)
598
598
599 === :local -> :other ===
599 === :local -> :other ===
600 (no more unresolved files)
600 (no more unresolved files)
601 --- diff of status ---
601 --- diff of status ---
602 (status identical)
602 (status identical)
603
603
604 === :other -> :prompt ===
604 === :other -> :prompt ===
605 local changed file1 which remote deleted
605 local changed file1 which remote deleted
606 use (c)hanged version or (d)elete?
606 use (c)hanged version or (d)elete?
607 remote changed file2 which local deleted
607 remote changed file2 which local deleted
608 use (c)hanged version or leave (d)eleted?
608 use (c)hanged version or leave (d)eleted?
609 no tool found to merge file3
609 no tool found to merge file3
610 keep (l)ocal or take (o)ther?
610 keep (l)ocal, take (o)ther, or leave (u)nresolved?
611 --- diff of status ---
611 --- diff of status ---
612 (status identical)
612 (status identical)
613
613
614 === :prompt -> :local ===
614 === :prompt -> :local ===
615 (no more unresolved files)
615 (no more unresolved files)
616 --- diff of status ---
616 --- diff of status ---
617 (status identical)
617 (status identical)
618
618
619 === :local -> :fail ===
619 === :local -> :fail ===
620 --- diff of status ---
620 --- diff of status ---
621 (status identical)
621 (status identical)
622
622
623 === :fail -> :other ===
623 === :fail -> :other ===
624 (no more unresolved files)
624 (no more unresolved files)
625 --- diff of status ---
625 --- diff of status ---
626 (status identical)
626 (status identical)
627
627
628 === :other -> :local ===
628 === :other -> :local ===
629 (no more unresolved files)
629 (no more unresolved files)
630 --- diff of status ---
630 --- diff of status ---
631 (status identical)
631 (status identical)
632
632
633 === :local -> :prompt ===
633 === :local -> :prompt ===
634 local changed file1 which remote deleted
634 local changed file1 which remote deleted
635 use (c)hanged version or (d)elete?
635 use (c)hanged version or (d)elete?
636 remote changed file2 which local deleted
636 remote changed file2 which local deleted
637 use (c)hanged version or leave (d)eleted?
637 use (c)hanged version or leave (d)eleted?
638 no tool found to merge file3
638 no tool found to merge file3
639 keep (l)ocal or take (o)ther?
639 keep (l)ocal, take (o)ther, or leave (u)nresolved?
640 --- diff of status ---
640 --- diff of status ---
641 (status identical)
641 (status identical)
642
642
643 === :prompt -> :other ===
643 === :prompt -> :other ===
644 (no more unresolved files)
644 (no more unresolved files)
645 --- diff of status ---
645 --- diff of status ---
646 (status identical)
646 (status identical)
647
647
648 === :other -> :fail ===
648 === :other -> :fail ===
649 --- diff of status ---
649 --- diff of status ---
650 (status identical)
650 (status identical)
651
651
652 === :fail -> :prompt ===
652 === :fail -> :prompt ===
653 local changed file1 which remote deleted
653 local changed file1 which remote deleted
654 use (c)hanged version or (d)elete?
654 use (c)hanged version or (d)elete?
655 remote changed file2 which local deleted
655 remote changed file2 which local deleted
656 use (c)hanged version or leave (d)eleted?
656 use (c)hanged version or leave (d)eleted?
657 no tool found to merge file3
657 no tool found to merge file3
658 keep (l)ocal or take (o)ther?
658 keep (l)ocal, take (o)ther, or leave (u)nresolved?
659 --- diff of status ---
659 --- diff of status ---
660 (status identical)
660 (status identical)
661
661
662 === :prompt -> :fail ===
662 === :prompt -> :fail ===
663 --- diff of status ---
663 --- diff of status ---
664 (status identical)
664 (status identical)
665
665
666 === :fail -> :local ===
666 === :fail -> :local ===
667 (no more unresolved files)
667 (no more unresolved files)
668 --- diff of status ---
668 --- diff of status ---
669 (status identical)
669 (status identical)
670
670
671
671
672
672
673 Non-interactive linear update
673 Non-interactive linear update
674
674
675 $ hg co -C 0
675 $ hg co -C 0
676 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
676 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
677 $ echo changed >> file1
677 $ echo changed >> file1
678 $ hg rm file2
678 $ hg rm file2
679 $ hg update 1 -y
679 $ hg update 1 -y
680 local changed file1 which remote deleted
680 local changed file1 which remote deleted
681 use (c)hanged version or (d)elete? c
681 use (c)hanged version or (d)elete? c
682 remote changed file2 which local deleted
682 remote changed file2 which local deleted
683 use (c)hanged version or leave (d)eleted? c
683 use (c)hanged version or leave (d)eleted? c
684 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
684 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
685 $ status
685 $ status
686 --- status ---
686 --- status ---
687 A file1
687 A file1
688 C file2
688 C file2
689 C file3
689 C file3
690 --- resolve --list ---
690 --- resolve --list ---
691 R file1
691 R file1
692 R file2
692 R file2
693 --- debugmergestate ---
693 --- debugmergestate ---
694 * version 2 records
694 * version 2 records
695 local: ab57bf49aa276a22d35a473592d4c34b5abc3eff
695 local: ab57bf49aa276a22d35a473592d4c34b5abc3eff
696 other: 10f9a0a634e82080907e62f075ab119cbc565ea6
696 other: 10f9a0a634e82080907e62f075ab119cbc565ea6
697 file: file1 (record type "C", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
697 file: file1 (record type "C", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
698 local path: file1 (flags "")
698 local path: file1 (flags "")
699 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
699 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
700 other path: file1 (node null)
700 other path: file1 (node null)
701 file: file2 (record type "C", state "r", hash null)
701 file: file2 (record type "C", state "r", hash null)
702 local path: file2 (flags "")
702 local path: file2 (flags "")
703 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
703 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
704 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
704 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
705 --- file1 ---
705 --- file1 ---
706 1
706 1
707 changed
707 changed
708 --- file2 ---
708 --- file2 ---
709 2
709 2
710 changed
710 changed
711 --- file3 ---
711 --- file3 ---
712 3
712 3
713 changed1
713 changed1
714
714
715 Choose local versions of files
715 Choose local versions of files
716
716
717 $ hg co -C 0
717 $ hg co -C 0
718 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
718 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
719 $ echo changed >> file1
719 $ echo changed >> file1
720 $ hg rm file2
720 $ hg rm file2
721 $ hg update 1 --tool :local
721 $ hg update 1 --tool :local
722 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
722 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
723 $ status 2>&1 | tee $TESTTMP/local.status
723 $ status 2>&1 | tee $TESTTMP/local.status
724 --- status ---
724 --- status ---
725 file2: * (glob)
725 file2: * (glob)
726 A file1
726 A file1
727 C file3
727 C file3
728 --- resolve --list ---
728 --- resolve --list ---
729 R file1
729 R file1
730 R file2
730 R file2
731 --- debugmergestate ---
731 --- debugmergestate ---
732 * version 2 records
732 * version 2 records
733 local: ab57bf49aa276a22d35a473592d4c34b5abc3eff
733 local: ab57bf49aa276a22d35a473592d4c34b5abc3eff
734 other: 10f9a0a634e82080907e62f075ab119cbc565ea6
734 other: 10f9a0a634e82080907e62f075ab119cbc565ea6
735 file: file1 (record type "C", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
735 file: file1 (record type "C", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
736 local path: file1 (flags "")
736 local path: file1 (flags "")
737 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
737 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
738 other path: file1 (node null)
738 other path: file1 (node null)
739 file: file2 (record type "C", state "r", hash null)
739 file: file2 (record type "C", state "r", hash null)
740 local path: file2 (flags "")
740 local path: file2 (flags "")
741 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
741 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
742 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
742 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
743 --- file1 ---
743 --- file1 ---
744 1
744 1
745 changed
745 changed
746 *** file2 does not exist
746 *** file2 does not exist
747 --- file3 ---
747 --- file3 ---
748 3
748 3
749 changed1
749 changed1
750
750
751 Choose other versions of files
751 Choose other versions of files
752
752
753 $ hg co -C 0
753 $ hg co -C 0
754 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
754 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
755 $ echo changed >> file1
755 $ echo changed >> file1
756 $ hg rm file2
756 $ hg rm file2
757 $ hg update 1 --tool :other
757 $ hg update 1 --tool :other
758 1 files updated, 1 files merged, 1 files removed, 0 files unresolved
758 1 files updated, 1 files merged, 1 files removed, 0 files unresolved
759 $ status 2>&1 | tee $TESTTMP/other.status
759 $ status 2>&1 | tee $TESTTMP/other.status
760 --- status ---
760 --- status ---
761 file1: * (glob)
761 file1: * (glob)
762 C file2
762 C file2
763 C file3
763 C file3
764 --- resolve --list ---
764 --- resolve --list ---
765 R file1
765 R file1
766 R file2
766 R file2
767 --- debugmergestate ---
767 --- debugmergestate ---
768 * version 2 records
768 * version 2 records
769 local: ab57bf49aa276a22d35a473592d4c34b5abc3eff
769 local: ab57bf49aa276a22d35a473592d4c34b5abc3eff
770 other: 10f9a0a634e82080907e62f075ab119cbc565ea6
770 other: 10f9a0a634e82080907e62f075ab119cbc565ea6
771 file: file1 (record type "C", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
771 file: file1 (record type "C", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
772 local path: file1 (flags "")
772 local path: file1 (flags "")
773 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
773 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
774 other path: file1 (node null)
774 other path: file1 (node null)
775 file: file2 (record type "C", state "r", hash null)
775 file: file2 (record type "C", state "r", hash null)
776 local path: file2 (flags "")
776 local path: file2 (flags "")
777 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
777 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
778 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
778 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
779 *** file1 does not exist
779 *** file1 does not exist
780 --- file2 ---
780 --- file2 ---
781 2
781 2
782 changed
782 changed
783 --- file3 ---
783 --- file3 ---
784 3
784 3
785 changed1
785 changed1
786
786
787 Fail
787 Fail
788
788
789 $ hg co -C 0
789 $ hg co -C 0
790 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
790 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
791 $ echo changed >> file1
791 $ echo changed >> file1
792 $ hg rm file2
792 $ hg rm file2
793 $ hg update 1 --tool :fail
793 $ hg update 1 --tool :fail
794 1 files updated, 0 files merged, 0 files removed, 2 files unresolved
794 1 files updated, 0 files merged, 0 files removed, 2 files unresolved
795 use 'hg resolve' to retry unresolved file merges
795 use 'hg resolve' to retry unresolved file merges
796 [1]
796 [1]
797 $ status 2>&1 | tee $TESTTMP/fail.status
797 $ status 2>&1 | tee $TESTTMP/fail.status
798 --- status ---
798 --- status ---
799 A file1
799 A file1
800 C file2
800 C file2
801 C file3
801 C file3
802 --- resolve --list ---
802 --- resolve --list ---
803 U file1
803 U file1
804 U file2
804 U file2
805 --- debugmergestate ---
805 --- debugmergestate ---
806 * version 2 records
806 * version 2 records
807 local: ab57bf49aa276a22d35a473592d4c34b5abc3eff
807 local: ab57bf49aa276a22d35a473592d4c34b5abc3eff
808 other: 10f9a0a634e82080907e62f075ab119cbc565ea6
808 other: 10f9a0a634e82080907e62f075ab119cbc565ea6
809 file: file1 (record type "C", state "u", hash 60b27f004e454aca81b0480209cce5081ec52390)
809 file: file1 (record type "C", state "u", hash 60b27f004e454aca81b0480209cce5081ec52390)
810 local path: file1 (flags "")
810 local path: file1 (flags "")
811 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
811 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
812 other path: file1 (node null)
812 other path: file1 (node null)
813 file: file2 (record type "C", state "u", hash null)
813 file: file2 (record type "C", state "u", hash null)
814 local path: file2 (flags "")
814 local path: file2 (flags "")
815 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
815 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
816 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
816 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
817 --- file1 ---
817 --- file1 ---
818 1
818 1
819 changed
819 changed
820 --- file2 ---
820 --- file2 ---
821 2
821 2
822 changed
822 changed
823 --- file3 ---
823 --- file3 ---
824 3
824 3
825 changed1
825 changed1
826
826
827 Force prompts with no input
827 Force prompts with no input
828
828
829 $ hg co -C 0
829 $ hg co -C 0
830 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
830 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
831 $ echo changed >> file1
831 $ echo changed >> file1
832 $ hg rm file2
832 $ hg rm file2
833 $ hg update 1 --config ui.interactive=True --tool :prompt
833 $ hg update 1 --config ui.interactive=True --tool :prompt
834 local changed file1 which remote deleted
834 local changed file1 which remote deleted
835 use (c)hanged version or (d)elete?
835 use (c)hanged version or (d)elete?
836 remote changed file2 which local deleted
836 remote changed file2 which local deleted
837 use (c)hanged version or leave (d)eleted?
837 use (c)hanged version or leave (d)eleted?
838 1 files updated, 0 files merged, 0 files removed, 2 files unresolved
838 1 files updated, 0 files merged, 0 files removed, 2 files unresolved
839 use 'hg resolve' to retry unresolved file merges
839 use 'hg resolve' to retry unresolved file merges
840 [1]
840 [1]
841 $ status 2>&1 | tee $TESTTMP/prompt.status
841 $ status 2>&1 | tee $TESTTMP/prompt.status
842 --- status ---
842 --- status ---
843 A file1
843 A file1
844 C file2
844 C file2
845 C file3
845 C file3
846 --- resolve --list ---
846 --- resolve --list ---
847 U file1
847 U file1
848 U file2
848 U file2
849 --- debugmergestate ---
849 --- debugmergestate ---
850 * version 2 records
850 * version 2 records
851 local: ab57bf49aa276a22d35a473592d4c34b5abc3eff
851 local: ab57bf49aa276a22d35a473592d4c34b5abc3eff
852 other: 10f9a0a634e82080907e62f075ab119cbc565ea6
852 other: 10f9a0a634e82080907e62f075ab119cbc565ea6
853 file: file1 (record type "C", state "u", hash 60b27f004e454aca81b0480209cce5081ec52390)
853 file: file1 (record type "C", state "u", hash 60b27f004e454aca81b0480209cce5081ec52390)
854 local path: file1 (flags "")
854 local path: file1 (flags "")
855 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
855 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
856 other path: file1 (node null)
856 other path: file1 (node null)
857 file: file2 (record type "C", state "u", hash null)
857 file: file2 (record type "C", state "u", hash null)
858 local path: file2 (flags "")
858 local path: file2 (flags "")
859 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
859 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
860 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
860 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
861 --- file1 ---
861 --- file1 ---
862 1
862 1
863 changed
863 changed
864 --- file2 ---
864 --- file2 ---
865 2
865 2
866 changed
866 changed
867 --- file3 ---
867 --- file3 ---
868 3
868 3
869 changed1
869 changed1
870 $ diff -U8 $TESTTMP/fail.status $TESTTMP/prompt.status
870 $ diff -U8 $TESTTMP/fail.status $TESTTMP/prompt.status
871
871
872 Choose to merge all files
872 Choose to merge all files
873
873
874 $ hg co -C 0
874 $ hg co -C 0
875 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
875 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
876 $ echo changed >> file1
876 $ echo changed >> file1
877 $ hg rm file2
877 $ hg rm file2
878 $ hg update 1 --tool :merge3
878 $ hg update 1 --tool :merge3
879 local changed file1 which remote deleted
879 local changed file1 which remote deleted
880 use (c)hanged version or (d)elete? c
880 use (c)hanged version or (d)elete? c
881 remote changed file2 which local deleted
881 remote changed file2 which local deleted
882 use (c)hanged version or leave (d)eleted? c
882 use (c)hanged version or leave (d)eleted? c
883 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
883 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
884 $ status
884 $ status
885 --- status ---
885 --- status ---
886 A file1
886 A file1
887 C file2
887 C file2
888 C file3
888 C file3
889 --- resolve --list ---
889 --- resolve --list ---
890 R file1
890 R file1
891 R file2
891 R file2
892 --- debugmergestate ---
892 --- debugmergestate ---
893 * version 2 records
893 * version 2 records
894 local: ab57bf49aa276a22d35a473592d4c34b5abc3eff
894 local: ab57bf49aa276a22d35a473592d4c34b5abc3eff
895 other: 10f9a0a634e82080907e62f075ab119cbc565ea6
895 other: 10f9a0a634e82080907e62f075ab119cbc565ea6
896 file: file1 (record type "C", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
896 file: file1 (record type "C", state "r", hash 60b27f004e454aca81b0480209cce5081ec52390)
897 local path: file1 (flags "")
897 local path: file1 (flags "")
898 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
898 ancestor path: file1 (node b8e02f6433738021a065f94175c7cd23db5f05be)
899 other path: file1 (node null)
899 other path: file1 (node null)
900 file: file2 (record type "C", state "r", hash null)
900 file: file2 (record type "C", state "r", hash null)
901 local path: file2 (flags "")
901 local path: file2 (flags "")
902 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
902 ancestor path: file2 (node 5d9299349fc01ddd25d0070d149b124d8f10411e)
903 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
903 other path: file2 (node e7c1328648519852e723de86c0c0525acd779257)
904 --- file1 ---
904 --- file1 ---
905 1
905 1
906 changed
906 changed
907 --- file2 ---
907 --- file2 ---
908 2
908 2
909 changed
909 changed
910 --- file3 ---
910 --- file3 ---
911 3
911 3
912 changed1
912 changed1
913
913
914 Test transitions between different merge tools
914 Test transitions between different merge tools
915
915
916 $ testtransitions
916 $ testtransitions
917 === :merge3 -> :local ===
917 === :merge3 -> :local ===
918 (no more unresolved files)
918 (no more unresolved files)
919 --- diff of status ---
919 --- diff of status ---
920 (status identical)
920 (status identical)
921
921
922 === :local -> :other ===
922 === :local -> :other ===
923 (no more unresolved files)
923 (no more unresolved files)
924 --- diff of status ---
924 --- diff of status ---
925 (status identical)
925 (status identical)
926
926
927 === :other -> :prompt ===
927 === :other -> :prompt ===
928 local changed file1 which remote deleted
928 local changed file1 which remote deleted
929 use (c)hanged version or (d)elete?
929 use (c)hanged version or (d)elete?
930 remote changed file2 which local deleted
930 remote changed file2 which local deleted
931 use (c)hanged version or leave (d)eleted?
931 use (c)hanged version or leave (d)eleted?
932 --- diff of status ---
932 --- diff of status ---
933 (status identical)
933 (status identical)
934
934
935 === :prompt -> :local ===
935 === :prompt -> :local ===
936 (no more unresolved files)
936 (no more unresolved files)
937 --- diff of status ---
937 --- diff of status ---
938 (status identical)
938 (status identical)
939
939
940 === :local -> :fail ===
940 === :local -> :fail ===
941 --- diff of status ---
941 --- diff of status ---
942 (status identical)
942 (status identical)
943
943
944 === :fail -> :other ===
944 === :fail -> :other ===
945 (no more unresolved files)
945 (no more unresolved files)
946 --- diff of status ---
946 --- diff of status ---
947 (status identical)
947 (status identical)
948
948
949 === :other -> :local ===
949 === :other -> :local ===
950 (no more unresolved files)
950 (no more unresolved files)
951 --- diff of status ---
951 --- diff of status ---
952 (status identical)
952 (status identical)
953
953
954 === :local -> :prompt ===
954 === :local -> :prompt ===
955 local changed file1 which remote deleted
955 local changed file1 which remote deleted
956 use (c)hanged version or (d)elete?
956 use (c)hanged version or (d)elete?
957 remote changed file2 which local deleted
957 remote changed file2 which local deleted
958 use (c)hanged version or leave (d)eleted?
958 use (c)hanged version or leave (d)eleted?
959 --- diff of status ---
959 --- diff of status ---
960 (status identical)
960 (status identical)
961
961
962 === :prompt -> :other ===
962 === :prompt -> :other ===
963 (no more unresolved files)
963 (no more unresolved files)
964 --- diff of status ---
964 --- diff of status ---
965 (status identical)
965 (status identical)
966
966
967 === :other -> :fail ===
967 === :other -> :fail ===
968 --- diff of status ---
968 --- diff of status ---
969 (status identical)
969 (status identical)
970
970
971 === :fail -> :prompt ===
971 === :fail -> :prompt ===
972 local changed file1 which remote deleted
972 local changed file1 which remote deleted
973 use (c)hanged version or (d)elete?
973 use (c)hanged version or (d)elete?
974 remote changed file2 which local deleted
974 remote changed file2 which local deleted
975 use (c)hanged version or leave (d)eleted?
975 use (c)hanged version or leave (d)eleted?
976 --- diff of status ---
976 --- diff of status ---
977 (status identical)
977 (status identical)
978
978
979 === :prompt -> :fail ===
979 === :prompt -> :fail ===
980 --- diff of status ---
980 --- diff of status ---
981 (status identical)
981 (status identical)
982
982
983 === :fail -> :local ===
983 === :fail -> :local ===
984 (no more unresolved files)
984 (no more unresolved files)
985 --- diff of status ---
985 --- diff of status ---
986 (status identical)
986 (status identical)
987
987
@@ -1,1185 +1,1210 b''
1 test merge-tools configuration - mostly exercising filemerge.py
1 test merge-tools configuration - mostly exercising filemerge.py
2
2
3 $ unset HGMERGE # make sure HGMERGE doesn't interfere with the test
3 $ unset HGMERGE # make sure HGMERGE doesn't interfere with the test
4 $ hg init
4 $ hg init
5
5
6 revision 0
6 revision 0
7
7
8 $ echo "revision 0" > f
8 $ echo "revision 0" > f
9 $ echo "space" >> f
9 $ echo "space" >> f
10 $ hg commit -Am "revision 0"
10 $ hg commit -Am "revision 0"
11 adding f
11 adding f
12
12
13 revision 1
13 revision 1
14
14
15 $ echo "revision 1" > f
15 $ echo "revision 1" > f
16 $ echo "space" >> f
16 $ echo "space" >> f
17 $ hg commit -Am "revision 1"
17 $ hg commit -Am "revision 1"
18 $ hg update 0 > /dev/null
18 $ hg update 0 > /dev/null
19
19
20 revision 2
20 revision 2
21
21
22 $ echo "revision 2" > f
22 $ echo "revision 2" > f
23 $ echo "space" >> f
23 $ echo "space" >> f
24 $ hg commit -Am "revision 2"
24 $ hg commit -Am "revision 2"
25 created new head
25 created new head
26 $ hg update 0 > /dev/null
26 $ hg update 0 > /dev/null
27
27
28 revision 3 - simple to merge
28 revision 3 - simple to merge
29
29
30 $ echo "revision 3" >> f
30 $ echo "revision 3" >> f
31 $ hg commit -Am "revision 3"
31 $ hg commit -Am "revision 3"
32 created new head
32 created new head
33
33
34 revision 4 - hard to merge
34 revision 4 - hard to merge
35
35
36 $ hg update 0 > /dev/null
36 $ hg update 0 > /dev/null
37 $ echo "revision 4" > f
37 $ echo "revision 4" > f
38 $ hg commit -Am "revision 4"
38 $ hg commit -Am "revision 4"
39 created new head
39 created new head
40
40
41 $ echo "[merge-tools]" > .hg/hgrc
41 $ echo "[merge-tools]" > .hg/hgrc
42
42
43 $ beforemerge() {
43 $ beforemerge() {
44 > cat .hg/hgrc
44 > cat .hg/hgrc
45 > echo "# hg update -C 1"
45 > echo "# hg update -C 1"
46 > hg update -C 1 > /dev/null
46 > hg update -C 1 > /dev/null
47 > }
47 > }
48 $ aftermerge() {
48 $ aftermerge() {
49 > echo "# cat f"
49 > echo "# cat f"
50 > cat f
50 > cat f
51 > echo "# hg stat"
51 > echo "# hg stat"
52 > hg stat
52 > hg stat
53 > echo "# hg resolve --list"
53 > echo "# hg resolve --list"
54 > hg resolve --list
54 > hg resolve --list
55 > rm -f f.orig
55 > rm -f f.orig
56 > }
56 > }
57
57
58 Tool selection
58 Tool selection
59
59
60 default is internal merge:
60 default is internal merge:
61
61
62 $ beforemerge
62 $ beforemerge
63 [merge-tools]
63 [merge-tools]
64 # hg update -C 1
64 # hg update -C 1
65
65
66 hg merge -r 2
66 hg merge -r 2
67 override $PATH to ensure hgmerge not visible; use $PYTHON in case we're
67 override $PATH to ensure hgmerge not visible; use $PYTHON in case we're
68 running from a devel copy, not a temp installation
68 running from a devel copy, not a temp installation
69
69
70 $ PATH="$BINDIR:/usr/sbin" $PYTHON "$BINDIR"/hg merge -r 2
70 $ PATH="$BINDIR:/usr/sbin" $PYTHON "$BINDIR"/hg merge -r 2
71 merging f
71 merging f
72 warning: conflicts while merging f! (edit, then use 'hg resolve --mark')
72 warning: conflicts while merging f! (edit, then use 'hg resolve --mark')
73 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
73 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
74 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
74 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
75 [1]
75 [1]
76 $ aftermerge
76 $ aftermerge
77 # cat f
77 # cat f
78 <<<<<<< local: ef83787e2614 - test: revision 1
78 <<<<<<< local: ef83787e2614 - test: revision 1
79 revision 1
79 revision 1
80 =======
80 =======
81 revision 2
81 revision 2
82 >>>>>>> other: 0185f4e0cf02 - test: revision 2
82 >>>>>>> other: 0185f4e0cf02 - test: revision 2
83 space
83 space
84 # hg stat
84 # hg stat
85 M f
85 M f
86 ? f.orig
86 ? f.orig
87 # hg resolve --list
87 # hg resolve --list
88 U f
88 U f
89
89
90 simplest hgrc using false for merge:
90 simplest hgrc using false for merge:
91
91
92 $ echo "false.whatever=" >> .hg/hgrc
92 $ echo "false.whatever=" >> .hg/hgrc
93 $ beforemerge
93 $ beforemerge
94 [merge-tools]
94 [merge-tools]
95 false.whatever=
95 false.whatever=
96 # hg update -C 1
96 # hg update -C 1
97 $ hg merge -r 2
97 $ hg merge -r 2
98 merging f
98 merging f
99 merging f failed!
99 merging f failed!
100 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
100 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
101 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
101 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
102 [1]
102 [1]
103 $ aftermerge
103 $ aftermerge
104 # cat f
104 # cat f
105 revision 1
105 revision 1
106 space
106 space
107 # hg stat
107 # hg stat
108 M f
108 M f
109 ? f.orig
109 ? f.orig
110 # hg resolve --list
110 # hg resolve --list
111 U f
111 U f
112
112
113 #if unix-permissions
113 #if unix-permissions
114
114
115 unexecutable file in $PATH shouldn't be found:
115 unexecutable file in $PATH shouldn't be found:
116
116
117 $ echo "echo fail" > false
117 $ echo "echo fail" > false
118 $ hg up -qC 1
118 $ hg up -qC 1
119 $ PATH="`pwd`:$BINDIR:/usr/sbin" $PYTHON "$BINDIR"/hg merge -r 2
119 $ PATH="`pwd`:$BINDIR:/usr/sbin" $PYTHON "$BINDIR"/hg merge -r 2
120 merging f
120 merging f
121 warning: conflicts while merging f! (edit, then use 'hg resolve --mark')
121 warning: conflicts while merging f! (edit, then use 'hg resolve --mark')
122 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
122 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
123 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
123 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
124 [1]
124 [1]
125 $ rm false
125 $ rm false
126
126
127 #endif
127 #endif
128
128
129 executable directory in $PATH shouldn't be found:
129 executable directory in $PATH shouldn't be found:
130
130
131 $ mkdir false
131 $ mkdir false
132 $ hg up -qC 1
132 $ hg up -qC 1
133 $ PATH="`pwd`:$BINDIR:/usr/sbin" $PYTHON "$BINDIR"/hg merge -r 2
133 $ PATH="`pwd`:$BINDIR:/usr/sbin" $PYTHON "$BINDIR"/hg merge -r 2
134 merging f
134 merging f
135 warning: conflicts while merging f! (edit, then use 'hg resolve --mark')
135 warning: conflicts while merging f! (edit, then use 'hg resolve --mark')
136 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
136 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
137 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
137 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
138 [1]
138 [1]
139 $ rmdir false
139 $ rmdir false
140
140
141 true with higher .priority gets precedence:
141 true with higher .priority gets precedence:
142
142
143 $ echo "true.priority=1" >> .hg/hgrc
143 $ echo "true.priority=1" >> .hg/hgrc
144 $ beforemerge
144 $ beforemerge
145 [merge-tools]
145 [merge-tools]
146 false.whatever=
146 false.whatever=
147 true.priority=1
147 true.priority=1
148 # hg update -C 1
148 # hg update -C 1
149 $ hg merge -r 2
149 $ hg merge -r 2
150 merging f
150 merging f
151 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
151 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
152 (branch merge, don't forget to commit)
152 (branch merge, don't forget to commit)
153 $ aftermerge
153 $ aftermerge
154 # cat f
154 # cat f
155 revision 1
155 revision 1
156 space
156 space
157 # hg stat
157 # hg stat
158 M f
158 M f
159 # hg resolve --list
159 # hg resolve --list
160 R f
160 R f
161
161
162 unless lowered on command line:
162 unless lowered on command line:
163
163
164 $ beforemerge
164 $ beforemerge
165 [merge-tools]
165 [merge-tools]
166 false.whatever=
166 false.whatever=
167 true.priority=1
167 true.priority=1
168 # hg update -C 1
168 # hg update -C 1
169 $ hg merge -r 2 --config merge-tools.true.priority=-7
169 $ hg merge -r 2 --config merge-tools.true.priority=-7
170 merging f
170 merging f
171 merging f failed!
171 merging f failed!
172 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
172 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
173 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
173 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
174 [1]
174 [1]
175 $ aftermerge
175 $ aftermerge
176 # cat f
176 # cat f
177 revision 1
177 revision 1
178 space
178 space
179 # hg stat
179 # hg stat
180 M f
180 M f
181 ? f.orig
181 ? f.orig
182 # hg resolve --list
182 # hg resolve --list
183 U f
183 U f
184
184
185 or false set higher on command line:
185 or false set higher on command line:
186
186
187 $ beforemerge
187 $ beforemerge
188 [merge-tools]
188 [merge-tools]
189 false.whatever=
189 false.whatever=
190 true.priority=1
190 true.priority=1
191 # hg update -C 1
191 # hg update -C 1
192 $ hg merge -r 2 --config merge-tools.false.priority=117
192 $ hg merge -r 2 --config merge-tools.false.priority=117
193 merging f
193 merging f
194 merging f failed!
194 merging f failed!
195 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
195 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
196 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
196 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
197 [1]
197 [1]
198 $ aftermerge
198 $ aftermerge
199 # cat f
199 # cat f
200 revision 1
200 revision 1
201 space
201 space
202 # hg stat
202 # hg stat
203 M f
203 M f
204 ? f.orig
204 ? f.orig
205 # hg resolve --list
205 # hg resolve --list
206 U f
206 U f
207
207
208 or true set to disabled:
208 or true set to disabled:
209 $ beforemerge
209 $ beforemerge
210 [merge-tools]
210 [merge-tools]
211 false.whatever=
211 false.whatever=
212 true.priority=1
212 true.priority=1
213 # hg update -C 1
213 # hg update -C 1
214 $ hg merge -r 2 --config merge-tools.true.disabled=yes
214 $ hg merge -r 2 --config merge-tools.true.disabled=yes
215 merging f
215 merging f
216 merging f failed!
216 merging f failed!
217 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
217 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
218 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
218 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
219 [1]
219 [1]
220 $ aftermerge
220 $ aftermerge
221 # cat f
221 # cat f
222 revision 1
222 revision 1
223 space
223 space
224 # hg stat
224 # hg stat
225 M f
225 M f
226 ? f.orig
226 ? f.orig
227 # hg resolve --list
227 # hg resolve --list
228 U f
228 U f
229
229
230 or true.executable not found in PATH:
230 or true.executable not found in PATH:
231
231
232 $ beforemerge
232 $ beforemerge
233 [merge-tools]
233 [merge-tools]
234 false.whatever=
234 false.whatever=
235 true.priority=1
235 true.priority=1
236 # hg update -C 1
236 # hg update -C 1
237 $ hg merge -r 2 --config merge-tools.true.executable=nonexistentmergetool
237 $ hg merge -r 2 --config merge-tools.true.executable=nonexistentmergetool
238 merging f
238 merging f
239 merging f failed!
239 merging f failed!
240 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
240 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
241 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
241 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
242 [1]
242 [1]
243 $ aftermerge
243 $ aftermerge
244 # cat f
244 # cat f
245 revision 1
245 revision 1
246 space
246 space
247 # hg stat
247 # hg stat
248 M f
248 M f
249 ? f.orig
249 ? f.orig
250 # hg resolve --list
250 # hg resolve --list
251 U f
251 U f
252
252
253 or true.executable with bogus path:
253 or true.executable with bogus path:
254
254
255 $ beforemerge
255 $ beforemerge
256 [merge-tools]
256 [merge-tools]
257 false.whatever=
257 false.whatever=
258 true.priority=1
258 true.priority=1
259 # hg update -C 1
259 # hg update -C 1
260 $ hg merge -r 2 --config merge-tools.true.executable=/nonexistent/mergetool
260 $ hg merge -r 2 --config merge-tools.true.executable=/nonexistent/mergetool
261 merging f
261 merging f
262 merging f failed!
262 merging f failed!
263 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
263 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
264 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
264 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
265 [1]
265 [1]
266 $ aftermerge
266 $ aftermerge
267 # cat f
267 # cat f
268 revision 1
268 revision 1
269 space
269 space
270 # hg stat
270 # hg stat
271 M f
271 M f
272 ? f.orig
272 ? f.orig
273 # hg resolve --list
273 # hg resolve --list
274 U f
274 U f
275
275
276 but true.executable set to cat found in PATH works:
276 but true.executable set to cat found in PATH works:
277
277
278 $ echo "true.executable=cat" >> .hg/hgrc
278 $ echo "true.executable=cat" >> .hg/hgrc
279 $ beforemerge
279 $ beforemerge
280 [merge-tools]
280 [merge-tools]
281 false.whatever=
281 false.whatever=
282 true.priority=1
282 true.priority=1
283 true.executable=cat
283 true.executable=cat
284 # hg update -C 1
284 # hg update -C 1
285 $ hg merge -r 2
285 $ hg merge -r 2
286 merging f
286 merging f
287 revision 1
287 revision 1
288 space
288 space
289 revision 0
289 revision 0
290 space
290 space
291 revision 2
291 revision 2
292 space
292 space
293 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
293 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
294 (branch merge, don't forget to commit)
294 (branch merge, don't forget to commit)
295 $ aftermerge
295 $ aftermerge
296 # cat f
296 # cat f
297 revision 1
297 revision 1
298 space
298 space
299 # hg stat
299 # hg stat
300 M f
300 M f
301 # hg resolve --list
301 # hg resolve --list
302 R f
302 R f
303
303
304 and true.executable set to cat with path works:
304 and true.executable set to cat with path works:
305
305
306 $ beforemerge
306 $ beforemerge
307 [merge-tools]
307 [merge-tools]
308 false.whatever=
308 false.whatever=
309 true.priority=1
309 true.priority=1
310 true.executable=cat
310 true.executable=cat
311 # hg update -C 1
311 # hg update -C 1
312 $ hg merge -r 2 --config merge-tools.true.executable=cat
312 $ hg merge -r 2 --config merge-tools.true.executable=cat
313 merging f
313 merging f
314 revision 1
314 revision 1
315 space
315 space
316 revision 0
316 revision 0
317 space
317 space
318 revision 2
318 revision 2
319 space
319 space
320 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
320 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
321 (branch merge, don't forget to commit)
321 (branch merge, don't forget to commit)
322 $ aftermerge
322 $ aftermerge
323 # cat f
323 # cat f
324 revision 1
324 revision 1
325 space
325 space
326 # hg stat
326 # hg stat
327 M f
327 M f
328 # hg resolve --list
328 # hg resolve --list
329 R f
329 R f
330
330
331 #if unix-permissions
331 #if unix-permissions
332
332
333 environment variables in true.executable are handled:
333 environment variables in true.executable are handled:
334
334
335 $ echo 'echo "custom merge tool"' > .hg/merge.sh
335 $ echo 'echo "custom merge tool"' > .hg/merge.sh
336 $ beforemerge
336 $ beforemerge
337 [merge-tools]
337 [merge-tools]
338 false.whatever=
338 false.whatever=
339 true.priority=1
339 true.priority=1
340 true.executable=cat
340 true.executable=cat
341 # hg update -C 1
341 # hg update -C 1
342 $ hg --config merge-tools.true.executable='sh' \
342 $ hg --config merge-tools.true.executable='sh' \
343 > --config merge-tools.true.args=.hg/merge.sh \
343 > --config merge-tools.true.args=.hg/merge.sh \
344 > merge -r 2
344 > merge -r 2
345 merging f
345 merging f
346 custom merge tool
346 custom merge tool
347 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
347 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
348 (branch merge, don't forget to commit)
348 (branch merge, don't forget to commit)
349 $ aftermerge
349 $ aftermerge
350 # cat f
350 # cat f
351 revision 1
351 revision 1
352 space
352 space
353 # hg stat
353 # hg stat
354 M f
354 M f
355 # hg resolve --list
355 # hg resolve --list
356 R f
356 R f
357
357
358 #endif
358 #endif
359
359
360 Tool selection and merge-patterns
360 Tool selection and merge-patterns
361
361
362 merge-patterns specifies new tool false:
362 merge-patterns specifies new tool false:
363
363
364 $ beforemerge
364 $ beforemerge
365 [merge-tools]
365 [merge-tools]
366 false.whatever=
366 false.whatever=
367 true.priority=1
367 true.priority=1
368 true.executable=cat
368 true.executable=cat
369 # hg update -C 1
369 # hg update -C 1
370 $ hg merge -r 2 --config merge-patterns.f=false
370 $ hg merge -r 2 --config merge-patterns.f=false
371 merging f
371 merging f
372 merging f failed!
372 merging f failed!
373 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
373 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
374 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
374 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
375 [1]
375 [1]
376 $ aftermerge
376 $ aftermerge
377 # cat f
377 # cat f
378 revision 1
378 revision 1
379 space
379 space
380 # hg stat
380 # hg stat
381 M f
381 M f
382 ? f.orig
382 ? f.orig
383 # hg resolve --list
383 # hg resolve --list
384 U f
384 U f
385
385
386 merge-patterns specifies executable not found in PATH and gets warning:
386 merge-patterns specifies executable not found in PATH and gets warning:
387
387
388 $ beforemerge
388 $ beforemerge
389 [merge-tools]
389 [merge-tools]
390 false.whatever=
390 false.whatever=
391 true.priority=1
391 true.priority=1
392 true.executable=cat
392 true.executable=cat
393 # hg update -C 1
393 # hg update -C 1
394 $ hg merge -r 2 --config merge-patterns.f=true --config merge-tools.true.executable=nonexistentmergetool
394 $ hg merge -r 2 --config merge-patterns.f=true --config merge-tools.true.executable=nonexistentmergetool
395 couldn't find merge tool true specified for f
395 couldn't find merge tool true specified for f
396 merging f
396 merging f
397 couldn't find merge tool true specified for f
397 couldn't find merge tool true specified for f
398 merging f failed!
398 merging f failed!
399 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
399 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
400 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
400 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
401 [1]
401 [1]
402 $ aftermerge
402 $ aftermerge
403 # cat f
403 # cat f
404 revision 1
404 revision 1
405 space
405 space
406 # hg stat
406 # hg stat
407 M f
407 M f
408 ? f.orig
408 ? f.orig
409 # hg resolve --list
409 # hg resolve --list
410 U f
410 U f
411
411
412 merge-patterns specifies executable with bogus path and gets warning:
412 merge-patterns specifies executable with bogus path and gets warning:
413
413
414 $ beforemerge
414 $ beforemerge
415 [merge-tools]
415 [merge-tools]
416 false.whatever=
416 false.whatever=
417 true.priority=1
417 true.priority=1
418 true.executable=cat
418 true.executable=cat
419 # hg update -C 1
419 # hg update -C 1
420 $ hg merge -r 2 --config merge-patterns.f=true --config merge-tools.true.executable=/nonexistent/mergetool
420 $ hg merge -r 2 --config merge-patterns.f=true --config merge-tools.true.executable=/nonexistent/mergetool
421 couldn't find merge tool true specified for f
421 couldn't find merge tool true specified for f
422 merging f
422 merging f
423 couldn't find merge tool true specified for f
423 couldn't find merge tool true specified for f
424 merging f failed!
424 merging f failed!
425 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
425 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
426 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
426 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
427 [1]
427 [1]
428 $ aftermerge
428 $ aftermerge
429 # cat f
429 # cat f
430 revision 1
430 revision 1
431 space
431 space
432 # hg stat
432 # hg stat
433 M f
433 M f
434 ? f.orig
434 ? f.orig
435 # hg resolve --list
435 # hg resolve --list
436 U f
436 U f
437
437
438 ui.merge overrules priority
438 ui.merge overrules priority
439
439
440 ui.merge specifies false:
440 ui.merge specifies false:
441
441
442 $ beforemerge
442 $ beforemerge
443 [merge-tools]
443 [merge-tools]
444 false.whatever=
444 false.whatever=
445 true.priority=1
445 true.priority=1
446 true.executable=cat
446 true.executable=cat
447 # hg update -C 1
447 # hg update -C 1
448 $ hg merge -r 2 --config ui.merge=false
448 $ hg merge -r 2 --config ui.merge=false
449 merging f
449 merging f
450 merging f failed!
450 merging f failed!
451 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
451 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
452 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
452 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
453 [1]
453 [1]
454 $ aftermerge
454 $ aftermerge
455 # cat f
455 # cat f
456 revision 1
456 revision 1
457 space
457 space
458 # hg stat
458 # hg stat
459 M f
459 M f
460 ? f.orig
460 ? f.orig
461 # hg resolve --list
461 # hg resolve --list
462 U f
462 U f
463
463
464 ui.merge specifies internal:fail:
464 ui.merge specifies internal:fail:
465
465
466 $ beforemerge
466 $ beforemerge
467 [merge-tools]
467 [merge-tools]
468 false.whatever=
468 false.whatever=
469 true.priority=1
469 true.priority=1
470 true.executable=cat
470 true.executable=cat
471 # hg update -C 1
471 # hg update -C 1
472 $ hg merge -r 2 --config ui.merge=internal:fail
472 $ hg merge -r 2 --config ui.merge=internal:fail
473 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
473 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
474 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
474 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
475 [1]
475 [1]
476 $ aftermerge
476 $ aftermerge
477 # cat f
477 # cat f
478 revision 1
478 revision 1
479 space
479 space
480 # hg stat
480 # hg stat
481 M f
481 M f
482 # hg resolve --list
482 # hg resolve --list
483 U f
483 U f
484
484
485 ui.merge specifies :local (without internal prefix):
485 ui.merge specifies :local (without internal prefix):
486
486
487 $ beforemerge
487 $ beforemerge
488 [merge-tools]
488 [merge-tools]
489 false.whatever=
489 false.whatever=
490 true.priority=1
490 true.priority=1
491 true.executable=cat
491 true.executable=cat
492 # hg update -C 1
492 # hg update -C 1
493 $ hg merge -r 2 --config ui.merge=:local
493 $ hg merge -r 2 --config ui.merge=:local
494 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
494 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
495 (branch merge, don't forget to commit)
495 (branch merge, don't forget to commit)
496 $ aftermerge
496 $ aftermerge
497 # cat f
497 # cat f
498 revision 1
498 revision 1
499 space
499 space
500 # hg stat
500 # hg stat
501 M f
501 M f
502 # hg resolve --list
502 # hg resolve --list
503 R f
503 R f
504
504
505 ui.merge specifies internal:other:
505 ui.merge specifies internal:other:
506
506
507 $ beforemerge
507 $ beforemerge
508 [merge-tools]
508 [merge-tools]
509 false.whatever=
509 false.whatever=
510 true.priority=1
510 true.priority=1
511 true.executable=cat
511 true.executable=cat
512 # hg update -C 1
512 # hg update -C 1
513 $ hg merge -r 2 --config ui.merge=internal:other
513 $ hg merge -r 2 --config ui.merge=internal:other
514 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
514 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
515 (branch merge, don't forget to commit)
515 (branch merge, don't forget to commit)
516 $ aftermerge
516 $ aftermerge
517 # cat f
517 # cat f
518 revision 2
518 revision 2
519 space
519 space
520 # hg stat
520 # hg stat
521 M f
521 M f
522 # hg resolve --list
522 # hg resolve --list
523 R f
523 R f
524
524
525 ui.merge specifies internal:prompt:
525 ui.merge specifies internal:prompt:
526
526
527 $ beforemerge
527 $ beforemerge
528 [merge-tools]
528 [merge-tools]
529 false.whatever=
529 false.whatever=
530 true.priority=1
530 true.priority=1
531 true.executable=cat
531 true.executable=cat
532 # hg update -C 1
532 # hg update -C 1
533 $ hg merge -r 2 --config ui.merge=internal:prompt
533 $ hg merge -r 2 --config ui.merge=internal:prompt
534 no tool found to merge f
534 no tool found to merge f
535 keep (l)ocal or take (o)ther? l
535 keep (l)ocal, take (o)ther, or leave (u)nresolved? l
536 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
536 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
537 (branch merge, don't forget to commit)
537 (branch merge, don't forget to commit)
538 $ aftermerge
538 $ aftermerge
539 # cat f
539 # cat f
540 revision 1
540 revision 1
541 space
541 space
542 # hg stat
542 # hg stat
543 M f
543 M f
544 # hg resolve --list
544 # hg resolve --list
545 R f
545 R f
546
546
547 ui.merge specifies :prompt, with 'leave unresolved' chosen
548
549 $ beforemerge
550 [merge-tools]
551 false.whatever=
552 true.priority=1
553 true.executable=cat
554 # hg update -C 1
555 $ hg merge -r 2 --config ui.merge=:prompt --config ui.interactive=True << EOF
556 > u
557 > EOF
558 no tool found to merge f
559 keep (l)ocal, take (o)ther, or leave (u)nresolved? u
560 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
561 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
562 [1]
563 $ aftermerge
564 # cat f
565 revision 1
566 space
567 # hg stat
568 M f
569 # hg resolve --list
570 U f
571
547 prompt with EOF
572 prompt with EOF
548
573
549 $ beforemerge
574 $ beforemerge
550 [merge-tools]
575 [merge-tools]
551 false.whatever=
576 false.whatever=
552 true.priority=1
577 true.priority=1
553 true.executable=cat
578 true.executable=cat
554 # hg update -C 1
579 # hg update -C 1
555 $ hg merge -r 2 --config ui.merge=internal:prompt --config ui.interactive=true
580 $ hg merge -r 2 --config ui.merge=internal:prompt --config ui.interactive=true
556 no tool found to merge f
581 no tool found to merge f
557 keep (l)ocal or take (o)ther?
582 keep (l)ocal, take (o)ther, or leave (u)nresolved?
558 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
583 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
559 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
584 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
560 [1]
585 [1]
561 $ aftermerge
586 $ aftermerge
562 # cat f
587 # cat f
563 revision 1
588 revision 1
564 space
589 space
565 # hg stat
590 # hg stat
566 M f
591 M f
567 # hg resolve --list
592 # hg resolve --list
568 U f
593 U f
569 $ hg resolve --all --config ui.merge=internal:prompt --config ui.interactive=true
594 $ hg resolve --all --config ui.merge=internal:prompt --config ui.interactive=true
570 no tool found to merge f
595 no tool found to merge f
571 keep (l)ocal or take (o)ther?
596 keep (l)ocal, take (o)ther, or leave (u)nresolved?
572 [1]
597 [1]
573 $ aftermerge
598 $ aftermerge
574 # cat f
599 # cat f
575 revision 1
600 revision 1
576 space
601 space
577 # hg stat
602 # hg stat
578 M f
603 M f
579 ? f.orig
604 ? f.orig
580 # hg resolve --list
605 # hg resolve --list
581 U f
606 U f
582 $ rm f
607 $ rm f
583 $ hg resolve --all --config ui.merge=internal:prompt --config ui.interactive=true
608 $ hg resolve --all --config ui.merge=internal:prompt --config ui.interactive=true
584 no tool found to merge f
609 no tool found to merge f
585 keep (l)ocal or take (o)ther?
610 keep (l)ocal, take (o)ther, or leave (u)nresolved?
586 [1]
611 [1]
587 $ aftermerge
612 $ aftermerge
588 # cat f
613 # cat f
589 revision 1
614 revision 1
590 space
615 space
591 # hg stat
616 # hg stat
592 M f
617 M f
593 # hg resolve --list
618 # hg resolve --list
594 U f
619 U f
595 $ hg resolve --all --config ui.merge=internal:prompt
620 $ hg resolve --all --config ui.merge=internal:prompt
596 no tool found to merge f
621 no tool found to merge f
597 keep (l)ocal or take (o)ther? l
622 keep (l)ocal, take (o)ther, or leave (u)nresolved? l
598 (no more unresolved files)
623 (no more unresolved files)
599 $ aftermerge
624 $ aftermerge
600 # cat f
625 # cat f
601 revision 1
626 revision 1
602 space
627 space
603 # hg stat
628 # hg stat
604 M f
629 M f
605 ? f.orig
630 ? f.orig
606 # hg resolve --list
631 # hg resolve --list
607 R f
632 R f
608
633
609 ui.merge specifies internal:dump:
634 ui.merge specifies internal:dump:
610
635
611 $ beforemerge
636 $ beforemerge
612 [merge-tools]
637 [merge-tools]
613 false.whatever=
638 false.whatever=
614 true.priority=1
639 true.priority=1
615 true.executable=cat
640 true.executable=cat
616 # hg update -C 1
641 # hg update -C 1
617 $ hg merge -r 2 --config ui.merge=internal:dump
642 $ hg merge -r 2 --config ui.merge=internal:dump
618 merging f
643 merging f
619 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
644 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
620 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
645 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
621 [1]
646 [1]
622 $ aftermerge
647 $ aftermerge
623 # cat f
648 # cat f
624 revision 1
649 revision 1
625 space
650 space
626 # hg stat
651 # hg stat
627 M f
652 M f
628 ? f.base
653 ? f.base
629 ? f.local
654 ? f.local
630 ? f.orig
655 ? f.orig
631 ? f.other
656 ? f.other
632 # hg resolve --list
657 # hg resolve --list
633 U f
658 U f
634
659
635 f.base:
660 f.base:
636
661
637 $ cat f.base
662 $ cat f.base
638 revision 0
663 revision 0
639 space
664 space
640
665
641 f.local:
666 f.local:
642
667
643 $ cat f.local
668 $ cat f.local
644 revision 1
669 revision 1
645 space
670 space
646
671
647 f.other:
672 f.other:
648
673
649 $ cat f.other
674 $ cat f.other
650 revision 2
675 revision 2
651 space
676 space
652 $ rm f.base f.local f.other
677 $ rm f.base f.local f.other
653
678
654 ui.merge specifies internal:other but is overruled by pattern for false:
679 ui.merge specifies internal:other but is overruled by pattern for false:
655
680
656 $ beforemerge
681 $ beforemerge
657 [merge-tools]
682 [merge-tools]
658 false.whatever=
683 false.whatever=
659 true.priority=1
684 true.priority=1
660 true.executable=cat
685 true.executable=cat
661 # hg update -C 1
686 # hg update -C 1
662 $ hg merge -r 2 --config ui.merge=internal:other --config merge-patterns.f=false
687 $ hg merge -r 2 --config ui.merge=internal:other --config merge-patterns.f=false
663 merging f
688 merging f
664 merging f failed!
689 merging f failed!
665 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
690 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
666 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
691 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
667 [1]
692 [1]
668 $ aftermerge
693 $ aftermerge
669 # cat f
694 # cat f
670 revision 1
695 revision 1
671 space
696 space
672 # hg stat
697 # hg stat
673 M f
698 M f
674 ? f.orig
699 ? f.orig
675 # hg resolve --list
700 # hg resolve --list
676 U f
701 U f
677
702
678 Premerge
703 Premerge
679
704
680 ui.merge specifies internal:other but is overruled by --tool=false
705 ui.merge specifies internal:other but is overruled by --tool=false
681
706
682 $ beforemerge
707 $ beforemerge
683 [merge-tools]
708 [merge-tools]
684 false.whatever=
709 false.whatever=
685 true.priority=1
710 true.priority=1
686 true.executable=cat
711 true.executable=cat
687 # hg update -C 1
712 # hg update -C 1
688 $ hg merge -r 2 --config ui.merge=internal:other --tool=false
713 $ hg merge -r 2 --config ui.merge=internal:other --tool=false
689 merging f
714 merging f
690 merging f failed!
715 merging f failed!
691 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
716 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
692 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
717 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
693 [1]
718 [1]
694 $ aftermerge
719 $ aftermerge
695 # cat f
720 # cat f
696 revision 1
721 revision 1
697 space
722 space
698 # hg stat
723 # hg stat
699 M f
724 M f
700 ? f.orig
725 ? f.orig
701 # hg resolve --list
726 # hg resolve --list
702 U f
727 U f
703
728
704 HGMERGE specifies internal:other but is overruled by --tool=false
729 HGMERGE specifies internal:other but is overruled by --tool=false
705
730
706 $ HGMERGE=internal:other ; export HGMERGE
731 $ HGMERGE=internal:other ; export HGMERGE
707 $ beforemerge
732 $ beforemerge
708 [merge-tools]
733 [merge-tools]
709 false.whatever=
734 false.whatever=
710 true.priority=1
735 true.priority=1
711 true.executable=cat
736 true.executable=cat
712 # hg update -C 1
737 # hg update -C 1
713 $ hg merge -r 2 --tool=false
738 $ hg merge -r 2 --tool=false
714 merging f
739 merging f
715 merging f failed!
740 merging f failed!
716 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
741 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
717 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
742 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
718 [1]
743 [1]
719 $ aftermerge
744 $ aftermerge
720 # cat f
745 # cat f
721 revision 1
746 revision 1
722 space
747 space
723 # hg stat
748 # hg stat
724 M f
749 M f
725 ? f.orig
750 ? f.orig
726 # hg resolve --list
751 # hg resolve --list
727 U f
752 U f
728
753
729 $ unset HGMERGE # make sure HGMERGE doesn't interfere with remaining tests
754 $ unset HGMERGE # make sure HGMERGE doesn't interfere with remaining tests
730
755
731 update is a merge ...
756 update is a merge ...
732
757
733 (this also tests that files reverted with '--rev REV' are treated as
758 (this also tests that files reverted with '--rev REV' are treated as
734 "modified", even if none of mode, size and timestamp of them isn't
759 "modified", even if none of mode, size and timestamp of them isn't
735 changed on the filesystem (see also issue4583))
760 changed on the filesystem (see also issue4583))
736
761
737 $ cat >> $HGRCPATH <<EOF
762 $ cat >> $HGRCPATH <<EOF
738 > [fakedirstatewritetime]
763 > [fakedirstatewritetime]
739 > # emulate invoking dirstate.write() via repo.status()
764 > # emulate invoking dirstate.write() via repo.status()
740 > # at 2000-01-01 00:00
765 > # at 2000-01-01 00:00
741 > fakenow = 200001010000
766 > fakenow = 200001010000
742 > EOF
767 > EOF
743
768
744 $ beforemerge
769 $ beforemerge
745 [merge-tools]
770 [merge-tools]
746 false.whatever=
771 false.whatever=
747 true.priority=1
772 true.priority=1
748 true.executable=cat
773 true.executable=cat
749 # hg update -C 1
774 # hg update -C 1
750 $ hg update -q 0
775 $ hg update -q 0
751 $ f -s f
776 $ f -s f
752 f: size=17
777 f: size=17
753 $ touch -t 200001010000 f
778 $ touch -t 200001010000 f
754 $ hg debugrebuildstate
779 $ hg debugrebuildstate
755 $ cat >> $HGRCPATH <<EOF
780 $ cat >> $HGRCPATH <<EOF
756 > [extensions]
781 > [extensions]
757 > fakedirstatewritetime = $TESTDIR/fakedirstatewritetime.py
782 > fakedirstatewritetime = $TESTDIR/fakedirstatewritetime.py
758 > EOF
783 > EOF
759 $ hg revert -q -r 1 .
784 $ hg revert -q -r 1 .
760 $ cat >> $HGRCPATH <<EOF
785 $ cat >> $HGRCPATH <<EOF
761 > [extensions]
786 > [extensions]
762 > fakedirstatewritetime = !
787 > fakedirstatewritetime = !
763 > EOF
788 > EOF
764 $ f -s f
789 $ f -s f
765 f: size=17
790 f: size=17
766 $ touch -t 200001010000 f
791 $ touch -t 200001010000 f
767 $ hg status f
792 $ hg status f
768 M f
793 M f
769 $ hg update -r 2
794 $ hg update -r 2
770 merging f
795 merging f
771 revision 1
796 revision 1
772 space
797 space
773 revision 0
798 revision 0
774 space
799 space
775 revision 2
800 revision 2
776 space
801 space
777 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
802 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
778 $ aftermerge
803 $ aftermerge
779 # cat f
804 # cat f
780 revision 1
805 revision 1
781 space
806 space
782 # hg stat
807 # hg stat
783 M f
808 M f
784 # hg resolve --list
809 # hg resolve --list
785 R f
810 R f
786
811
787 update should also have --tool
812 update should also have --tool
788
813
789 $ beforemerge
814 $ beforemerge
790 [merge-tools]
815 [merge-tools]
791 false.whatever=
816 false.whatever=
792 true.priority=1
817 true.priority=1
793 true.executable=cat
818 true.executable=cat
794 # hg update -C 1
819 # hg update -C 1
795 $ hg update -q 0
820 $ hg update -q 0
796 $ f -s f
821 $ f -s f
797 f: size=17
822 f: size=17
798 $ touch -t 200001010000 f
823 $ touch -t 200001010000 f
799 $ hg debugrebuildstate
824 $ hg debugrebuildstate
800 $ cat >> $HGRCPATH <<EOF
825 $ cat >> $HGRCPATH <<EOF
801 > [extensions]
826 > [extensions]
802 > fakedirstatewritetime = $TESTDIR/fakedirstatewritetime.py
827 > fakedirstatewritetime = $TESTDIR/fakedirstatewritetime.py
803 > EOF
828 > EOF
804 $ hg revert -q -r 1 .
829 $ hg revert -q -r 1 .
805 $ cat >> $HGRCPATH <<EOF
830 $ cat >> $HGRCPATH <<EOF
806 > [extensions]
831 > [extensions]
807 > fakedirstatewritetime = !
832 > fakedirstatewritetime = !
808 > EOF
833 > EOF
809 $ f -s f
834 $ f -s f
810 f: size=17
835 f: size=17
811 $ touch -t 200001010000 f
836 $ touch -t 200001010000 f
812 $ hg status f
837 $ hg status f
813 M f
838 M f
814 $ hg update -r 2 --tool false
839 $ hg update -r 2 --tool false
815 merging f
840 merging f
816 merging f failed!
841 merging f failed!
817 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
842 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
818 use 'hg resolve' to retry unresolved file merges
843 use 'hg resolve' to retry unresolved file merges
819 [1]
844 [1]
820 $ aftermerge
845 $ aftermerge
821 # cat f
846 # cat f
822 revision 1
847 revision 1
823 space
848 space
824 # hg stat
849 # hg stat
825 M f
850 M f
826 ? f.orig
851 ? f.orig
827 # hg resolve --list
852 # hg resolve --list
828 U f
853 U f
829
854
830 Default is silent simplemerge:
855 Default is silent simplemerge:
831
856
832 $ beforemerge
857 $ beforemerge
833 [merge-tools]
858 [merge-tools]
834 false.whatever=
859 false.whatever=
835 true.priority=1
860 true.priority=1
836 true.executable=cat
861 true.executable=cat
837 # hg update -C 1
862 # hg update -C 1
838 $ hg merge -r 3
863 $ hg merge -r 3
839 merging f
864 merging f
840 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
865 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
841 (branch merge, don't forget to commit)
866 (branch merge, don't forget to commit)
842 $ aftermerge
867 $ aftermerge
843 # cat f
868 # cat f
844 revision 1
869 revision 1
845 space
870 space
846 revision 3
871 revision 3
847 # hg stat
872 # hg stat
848 M f
873 M f
849 # hg resolve --list
874 # hg resolve --list
850 R f
875 R f
851
876
852 .premerge=True is same:
877 .premerge=True is same:
853
878
854 $ beforemerge
879 $ beforemerge
855 [merge-tools]
880 [merge-tools]
856 false.whatever=
881 false.whatever=
857 true.priority=1
882 true.priority=1
858 true.executable=cat
883 true.executable=cat
859 # hg update -C 1
884 # hg update -C 1
860 $ hg merge -r 3 --config merge-tools.true.premerge=True
885 $ hg merge -r 3 --config merge-tools.true.premerge=True
861 merging f
886 merging f
862 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
887 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
863 (branch merge, don't forget to commit)
888 (branch merge, don't forget to commit)
864 $ aftermerge
889 $ aftermerge
865 # cat f
890 # cat f
866 revision 1
891 revision 1
867 space
892 space
868 revision 3
893 revision 3
869 # hg stat
894 # hg stat
870 M f
895 M f
871 # hg resolve --list
896 # hg resolve --list
872 R f
897 R f
873
898
874 .premerge=False executes merge-tool:
899 .premerge=False executes merge-tool:
875
900
876 $ beforemerge
901 $ beforemerge
877 [merge-tools]
902 [merge-tools]
878 false.whatever=
903 false.whatever=
879 true.priority=1
904 true.priority=1
880 true.executable=cat
905 true.executable=cat
881 # hg update -C 1
906 # hg update -C 1
882 $ hg merge -r 3 --config merge-tools.true.premerge=False
907 $ hg merge -r 3 --config merge-tools.true.premerge=False
883 merging f
908 merging f
884 revision 1
909 revision 1
885 space
910 space
886 revision 0
911 revision 0
887 space
912 space
888 revision 0
913 revision 0
889 space
914 space
890 revision 3
915 revision 3
891 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
916 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
892 (branch merge, don't forget to commit)
917 (branch merge, don't forget to commit)
893 $ aftermerge
918 $ aftermerge
894 # cat f
919 # cat f
895 revision 1
920 revision 1
896 space
921 space
897 # hg stat
922 # hg stat
898 M f
923 M f
899 # hg resolve --list
924 # hg resolve --list
900 R f
925 R f
901
926
902 premerge=keep keeps conflict markers in:
927 premerge=keep keeps conflict markers in:
903
928
904 $ beforemerge
929 $ beforemerge
905 [merge-tools]
930 [merge-tools]
906 false.whatever=
931 false.whatever=
907 true.priority=1
932 true.priority=1
908 true.executable=cat
933 true.executable=cat
909 # hg update -C 1
934 # hg update -C 1
910 $ hg merge -r 4 --config merge-tools.true.premerge=keep
935 $ hg merge -r 4 --config merge-tools.true.premerge=keep
911 merging f
936 merging f
912 <<<<<<< local: ef83787e2614 - test: revision 1
937 <<<<<<< local: ef83787e2614 - test: revision 1
913 revision 1
938 revision 1
914 space
939 space
915 =======
940 =======
916 revision 4
941 revision 4
917 >>>>>>> other: 81448d39c9a0 - test: revision 4
942 >>>>>>> other: 81448d39c9a0 - test: revision 4
918 revision 0
943 revision 0
919 space
944 space
920 revision 4
945 revision 4
921 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
946 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
922 (branch merge, don't forget to commit)
947 (branch merge, don't forget to commit)
923 $ aftermerge
948 $ aftermerge
924 # cat f
949 # cat f
925 <<<<<<< local: ef83787e2614 - test: revision 1
950 <<<<<<< local: ef83787e2614 - test: revision 1
926 revision 1
951 revision 1
927 space
952 space
928 =======
953 =======
929 revision 4
954 revision 4
930 >>>>>>> other: 81448d39c9a0 - test: revision 4
955 >>>>>>> other: 81448d39c9a0 - test: revision 4
931 # hg stat
956 # hg stat
932 M f
957 M f
933 # hg resolve --list
958 # hg resolve --list
934 R f
959 R f
935
960
936 premerge=keep-merge3 keeps conflict markers with base content:
961 premerge=keep-merge3 keeps conflict markers with base content:
937
962
938 $ beforemerge
963 $ beforemerge
939 [merge-tools]
964 [merge-tools]
940 false.whatever=
965 false.whatever=
941 true.priority=1
966 true.priority=1
942 true.executable=cat
967 true.executable=cat
943 # hg update -C 1
968 # hg update -C 1
944 $ hg merge -r 4 --config merge-tools.true.premerge=keep-merge3
969 $ hg merge -r 4 --config merge-tools.true.premerge=keep-merge3
945 merging f
970 merging f
946 <<<<<<< local: ef83787e2614 - test: revision 1
971 <<<<<<< local: ef83787e2614 - test: revision 1
947 revision 1
972 revision 1
948 space
973 space
949 ||||||| base
974 ||||||| base
950 revision 0
975 revision 0
951 space
976 space
952 =======
977 =======
953 revision 4
978 revision 4
954 >>>>>>> other: 81448d39c9a0 - test: revision 4
979 >>>>>>> other: 81448d39c9a0 - test: revision 4
955 revision 0
980 revision 0
956 space
981 space
957 revision 4
982 revision 4
958 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
983 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
959 (branch merge, don't forget to commit)
984 (branch merge, don't forget to commit)
960 $ aftermerge
985 $ aftermerge
961 # cat f
986 # cat f
962 <<<<<<< local: ef83787e2614 - test: revision 1
987 <<<<<<< local: ef83787e2614 - test: revision 1
963 revision 1
988 revision 1
964 space
989 space
965 ||||||| base
990 ||||||| base
966 revision 0
991 revision 0
967 space
992 space
968 =======
993 =======
969 revision 4
994 revision 4
970 >>>>>>> other: 81448d39c9a0 - test: revision 4
995 >>>>>>> other: 81448d39c9a0 - test: revision 4
971 # hg stat
996 # hg stat
972 M f
997 M f
973 # hg resolve --list
998 # hg resolve --list
974 R f
999 R f
975
1000
976
1001
977 Tool execution
1002 Tool execution
978
1003
979 set tools.args explicit to include $base $local $other $output:
1004 set tools.args explicit to include $base $local $other $output:
980
1005
981 $ beforemerge
1006 $ beforemerge
982 [merge-tools]
1007 [merge-tools]
983 false.whatever=
1008 false.whatever=
984 true.priority=1
1009 true.priority=1
985 true.executable=cat
1010 true.executable=cat
986 # hg update -C 1
1011 # hg update -C 1
987 $ hg merge -r 2 --config merge-tools.true.executable=head --config merge-tools.true.args='$base $local $other $output' \
1012 $ hg merge -r 2 --config merge-tools.true.executable=head --config merge-tools.true.args='$base $local $other $output' \
988 > | sed 's,==> .* <==,==> ... <==,g'
1013 > | sed 's,==> .* <==,==> ... <==,g'
989 merging f
1014 merging f
990 ==> ... <==
1015 ==> ... <==
991 revision 0
1016 revision 0
992 space
1017 space
993
1018
994 ==> ... <==
1019 ==> ... <==
995 revision 1
1020 revision 1
996 space
1021 space
997
1022
998 ==> ... <==
1023 ==> ... <==
999 revision 2
1024 revision 2
1000 space
1025 space
1001
1026
1002 ==> ... <==
1027 ==> ... <==
1003 revision 1
1028 revision 1
1004 space
1029 space
1005 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
1030 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
1006 (branch merge, don't forget to commit)
1031 (branch merge, don't forget to commit)
1007 $ aftermerge
1032 $ aftermerge
1008 # cat f
1033 # cat f
1009 revision 1
1034 revision 1
1010 space
1035 space
1011 # hg stat
1036 # hg stat
1012 M f
1037 M f
1013 # hg resolve --list
1038 # hg resolve --list
1014 R f
1039 R f
1015
1040
1016 Merge with "echo mergeresult > $local":
1041 Merge with "echo mergeresult > $local":
1017
1042
1018 $ beforemerge
1043 $ beforemerge
1019 [merge-tools]
1044 [merge-tools]
1020 false.whatever=
1045 false.whatever=
1021 true.priority=1
1046 true.priority=1
1022 true.executable=cat
1047 true.executable=cat
1023 # hg update -C 1
1048 # hg update -C 1
1024 $ hg merge -r 2 --config merge-tools.true.executable=echo --config merge-tools.true.args='mergeresult > $local'
1049 $ hg merge -r 2 --config merge-tools.true.executable=echo --config merge-tools.true.args='mergeresult > $local'
1025 merging f
1050 merging f
1026 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
1051 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
1027 (branch merge, don't forget to commit)
1052 (branch merge, don't forget to commit)
1028 $ aftermerge
1053 $ aftermerge
1029 # cat f
1054 # cat f
1030 mergeresult
1055 mergeresult
1031 # hg stat
1056 # hg stat
1032 M f
1057 M f
1033 # hg resolve --list
1058 # hg resolve --list
1034 R f
1059 R f
1035
1060
1036 - and $local is the file f:
1061 - and $local is the file f:
1037
1062
1038 $ beforemerge
1063 $ beforemerge
1039 [merge-tools]
1064 [merge-tools]
1040 false.whatever=
1065 false.whatever=
1041 true.priority=1
1066 true.priority=1
1042 true.executable=cat
1067 true.executable=cat
1043 # hg update -C 1
1068 # hg update -C 1
1044 $ hg merge -r 2 --config merge-tools.true.executable=echo --config merge-tools.true.args='mergeresult > f'
1069 $ hg merge -r 2 --config merge-tools.true.executable=echo --config merge-tools.true.args='mergeresult > f'
1045 merging f
1070 merging f
1046 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
1071 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
1047 (branch merge, don't forget to commit)
1072 (branch merge, don't forget to commit)
1048 $ aftermerge
1073 $ aftermerge
1049 # cat f
1074 # cat f
1050 mergeresult
1075 mergeresult
1051 # hg stat
1076 # hg stat
1052 M f
1077 M f
1053 # hg resolve --list
1078 # hg resolve --list
1054 R f
1079 R f
1055
1080
1056 Merge with "echo mergeresult > $output" - the variable is a bit magic:
1081 Merge with "echo mergeresult > $output" - the variable is a bit magic:
1057
1082
1058 $ beforemerge
1083 $ beforemerge
1059 [merge-tools]
1084 [merge-tools]
1060 false.whatever=
1085 false.whatever=
1061 true.priority=1
1086 true.priority=1
1062 true.executable=cat
1087 true.executable=cat
1063 # hg update -C 1
1088 # hg update -C 1
1064 $ hg merge -r 2 --config merge-tools.true.executable=echo --config merge-tools.true.args='mergeresult > $output'
1089 $ hg merge -r 2 --config merge-tools.true.executable=echo --config merge-tools.true.args='mergeresult > $output'
1065 merging f
1090 merging f
1066 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
1091 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
1067 (branch merge, don't forget to commit)
1092 (branch merge, don't forget to commit)
1068 $ aftermerge
1093 $ aftermerge
1069 # cat f
1094 # cat f
1070 mergeresult
1095 mergeresult
1071 # hg stat
1096 # hg stat
1072 M f
1097 M f
1073 # hg resolve --list
1098 # hg resolve --list
1074 R f
1099 R f
1075
1100
1076 Merge using tool with a path that must be quoted:
1101 Merge using tool with a path that must be quoted:
1077
1102
1078 $ beforemerge
1103 $ beforemerge
1079 [merge-tools]
1104 [merge-tools]
1080 false.whatever=
1105 false.whatever=
1081 true.priority=1
1106 true.priority=1
1082 true.executable=cat
1107 true.executable=cat
1083 # hg update -C 1
1108 # hg update -C 1
1084 $ cat <<EOF > 'my merge tool'
1109 $ cat <<EOF > 'my merge tool'
1085 > cat "\$1" "\$2" "\$3" > "\$4"
1110 > cat "\$1" "\$2" "\$3" > "\$4"
1086 > EOF
1111 > EOF
1087 $ hg --config merge-tools.true.executable='sh' \
1112 $ hg --config merge-tools.true.executable='sh' \
1088 > --config merge-tools.true.args='"./my merge tool" $base $local $other $output' \
1113 > --config merge-tools.true.args='"./my merge tool" $base $local $other $output' \
1089 > merge -r 2
1114 > merge -r 2
1090 merging f
1115 merging f
1091 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
1116 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
1092 (branch merge, don't forget to commit)
1117 (branch merge, don't forget to commit)
1093 $ rm -f 'my merge tool'
1118 $ rm -f 'my merge tool'
1094 $ aftermerge
1119 $ aftermerge
1095 # cat f
1120 # cat f
1096 revision 0
1121 revision 0
1097 space
1122 space
1098 revision 1
1123 revision 1
1099 space
1124 space
1100 revision 2
1125 revision 2
1101 space
1126 space
1102 # hg stat
1127 # hg stat
1103 M f
1128 M f
1104 # hg resolve --list
1129 # hg resolve --list
1105 R f
1130 R f
1106
1131
1107 Issue3581: Merging a filename that needs to be quoted
1132 Issue3581: Merging a filename that needs to be quoted
1108 (This test doesn't work on Windows filesystems even on Linux, so check
1133 (This test doesn't work on Windows filesystems even on Linux, so check
1109 for Unix-like permission)
1134 for Unix-like permission)
1110
1135
1111 #if unix-permissions
1136 #if unix-permissions
1112 $ beforemerge
1137 $ beforemerge
1113 [merge-tools]
1138 [merge-tools]
1114 false.whatever=
1139 false.whatever=
1115 true.priority=1
1140 true.priority=1
1116 true.executable=cat
1141 true.executable=cat
1117 # hg update -C 1
1142 # hg update -C 1
1118 $ echo "revision 5" > '"; exit 1; echo "'
1143 $ echo "revision 5" > '"; exit 1; echo "'
1119 $ hg commit -Am "revision 5"
1144 $ hg commit -Am "revision 5"
1120 adding "; exit 1; echo "
1145 adding "; exit 1; echo "
1121 warning: filename contains '"', which is reserved on Windows: '"; exit 1; echo "'
1146 warning: filename contains '"', which is reserved on Windows: '"; exit 1; echo "'
1122 $ hg update -C 1 > /dev/null
1147 $ hg update -C 1 > /dev/null
1123 $ echo "revision 6" > '"; exit 1; echo "'
1148 $ echo "revision 6" > '"; exit 1; echo "'
1124 $ hg commit -Am "revision 6"
1149 $ hg commit -Am "revision 6"
1125 adding "; exit 1; echo "
1150 adding "; exit 1; echo "
1126 warning: filename contains '"', which is reserved on Windows: '"; exit 1; echo "'
1151 warning: filename contains '"', which is reserved on Windows: '"; exit 1; echo "'
1127 created new head
1152 created new head
1128 $ hg merge --config merge-tools.true.executable="true" -r 5
1153 $ hg merge --config merge-tools.true.executable="true" -r 5
1129 merging "; exit 1; echo "
1154 merging "; exit 1; echo "
1130 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
1155 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
1131 (branch merge, don't forget to commit)
1156 (branch merge, don't forget to commit)
1132 $ hg update -C 1 > /dev/null
1157 $ hg update -C 1 > /dev/null
1133 #endif
1158 #endif
1134
1159
1135 Merge post-processing
1160 Merge post-processing
1136
1161
1137 cat is a bad merge-tool and doesn't change:
1162 cat is a bad merge-tool and doesn't change:
1138
1163
1139 $ beforemerge
1164 $ beforemerge
1140 [merge-tools]
1165 [merge-tools]
1141 false.whatever=
1166 false.whatever=
1142 true.priority=1
1167 true.priority=1
1143 true.executable=cat
1168 true.executable=cat
1144 # hg update -C 1
1169 # hg update -C 1
1145 $ hg merge -y -r 2 --config merge-tools.true.checkchanged=1
1170 $ hg merge -y -r 2 --config merge-tools.true.checkchanged=1
1146 merging f
1171 merging f
1147 revision 1
1172 revision 1
1148 space
1173 space
1149 revision 0
1174 revision 0
1150 space
1175 space
1151 revision 2
1176 revision 2
1152 space
1177 space
1153 output file f appears unchanged
1178 output file f appears unchanged
1154 was merge successful (yn)? n
1179 was merge successful (yn)? n
1155 merging f failed!
1180 merging f failed!
1156 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
1181 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
1157 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
1182 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
1158 [1]
1183 [1]
1159 $ aftermerge
1184 $ aftermerge
1160 # cat f
1185 # cat f
1161 revision 1
1186 revision 1
1162 space
1187 space
1163 # hg stat
1188 # hg stat
1164 M f
1189 M f
1165 ? f.orig
1190 ? f.orig
1166 # hg resolve --list
1191 # hg resolve --list
1167 U f
1192 U f
1168
1193
1169 #if symlink
1194 #if symlink
1170
1195
1171 internal merge cannot handle symlinks and shouldn't try:
1196 internal merge cannot handle symlinks and shouldn't try:
1172
1197
1173 $ hg update -q -C 1
1198 $ hg update -q -C 1
1174 $ rm f
1199 $ rm f
1175 $ ln -s symlink f
1200 $ ln -s symlink f
1176 $ hg commit -qm 'f is symlink'
1201 $ hg commit -qm 'f is symlink'
1177 $ hg merge -r 2 --tool internal:merge
1202 $ hg merge -r 2 --tool internal:merge
1178 merging f
1203 merging f
1179 warning: internal :merge cannot merge symlinks for f
1204 warning: internal :merge cannot merge symlinks for f
1180 warning: conflicts while merging f! (edit, then use 'hg resolve --mark')
1205 warning: conflicts while merging f! (edit, then use 'hg resolve --mark')
1181 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
1206 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
1182 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
1207 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
1183 [1]
1208 [1]
1184
1209
1185 #endif
1210 #endif
@@ -1,439 +1,439 b''
1 #require symlink execbit
1 #require symlink execbit
2
2
3 $ tellmeabout() {
3 $ tellmeabout() {
4 > if [ -h $1 ]; then
4 > if [ -h $1 ]; then
5 > echo $1 is a symlink:
5 > echo $1 is a symlink:
6 > $TESTDIR/readlink.py $1
6 > $TESTDIR/readlink.py $1
7 > elif [ -x $1 ]; then
7 > elif [ -x $1 ]; then
8 > echo $1 is an executable file with content:
8 > echo $1 is an executable file with content:
9 > cat $1
9 > cat $1
10 > else
10 > else
11 > echo $1 is a plain file with content:
11 > echo $1 is a plain file with content:
12 > cat $1
12 > cat $1
13 > fi
13 > fi
14 > }
14 > }
15
15
16 $ hg init test1
16 $ hg init test1
17 $ cd test1
17 $ cd test1
18
18
19 $ echo a > a
19 $ echo a > a
20 $ hg ci -Aqmadd
20 $ hg ci -Aqmadd
21 $ chmod +x a
21 $ chmod +x a
22 $ hg ci -mexecutable
22 $ hg ci -mexecutable
23
23
24 $ hg up -q 0
24 $ hg up -q 0
25 $ rm a
25 $ rm a
26 $ ln -s symlink a
26 $ ln -s symlink a
27 $ hg ci -msymlink
27 $ hg ci -msymlink
28 created new head
28 created new head
29
29
30 Symlink is local parent, executable is other:
30 Symlink is local parent, executable is other:
31
31
32 $ hg merge --debug
32 $ hg merge --debug
33 searching for copies back to rev 1
33 searching for copies back to rev 1
34 resolving manifests
34 resolving manifests
35 branchmerge: True, force: False, partial: False
35 branchmerge: True, force: False, partial: False
36 ancestor: c334dc3be0da, local: 521a1e40188f+, remote: 3574f3e69b1c
36 ancestor: c334dc3be0da, local: 521a1e40188f+, remote: 3574f3e69b1c
37 preserving a for resolve of a
37 preserving a for resolve of a
38 a: versions differ -> m (premerge)
38 a: versions differ -> m (premerge)
39 picked tool ':merge' for a (binary False symlink True changedelete False)
39 picked tool ':merge' for a (binary False symlink True changedelete False)
40 merging a
40 merging a
41 my a@521a1e40188f+ other a@3574f3e69b1c ancestor a@c334dc3be0da
41 my a@521a1e40188f+ other a@3574f3e69b1c ancestor a@c334dc3be0da
42 warning: internal :merge cannot merge symlinks for a
42 warning: internal :merge cannot merge symlinks for a
43 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
43 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
44 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
44 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
45 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
45 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
46 [1]
46 [1]
47
47
48 $ tellmeabout a
48 $ tellmeabout a
49 a is a symlink:
49 a is a symlink:
50 a -> symlink
50 a -> symlink
51 $ hg resolve a --tool internal:other
51 $ hg resolve a --tool internal:other
52 (no more unresolved files)
52 (no more unresolved files)
53 $ tellmeabout a
53 $ tellmeabout a
54 a is an executable file with content:
54 a is an executable file with content:
55 a
55 a
56 $ hg st
56 $ hg st
57 M a
57 M a
58 ? a.orig
58 ? a.orig
59
59
60 Symlink is other parent, executable is local:
60 Symlink is other parent, executable is local:
61
61
62 $ hg update -C 1
62 $ hg update -C 1
63 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
63 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
64
64
65 $ hg merge --debug --tool :union
65 $ hg merge --debug --tool :union
66 searching for copies back to rev 1
66 searching for copies back to rev 1
67 resolving manifests
67 resolving manifests
68 branchmerge: True, force: False, partial: False
68 branchmerge: True, force: False, partial: False
69 ancestor: c334dc3be0da, local: 3574f3e69b1c+, remote: 521a1e40188f
69 ancestor: c334dc3be0da, local: 3574f3e69b1c+, remote: 521a1e40188f
70 preserving a for resolve of a
70 preserving a for resolve of a
71 a: versions differ -> m (premerge)
71 a: versions differ -> m (premerge)
72 picked tool ':union' for a (binary False symlink True changedelete False)
72 picked tool ':union' for a (binary False symlink True changedelete False)
73 merging a
73 merging a
74 my a@3574f3e69b1c+ other a@521a1e40188f ancestor a@c334dc3be0da
74 my a@3574f3e69b1c+ other a@521a1e40188f ancestor a@c334dc3be0da
75 warning: internal :union cannot merge symlinks for a
75 warning: internal :union cannot merge symlinks for a
76 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
76 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
77 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
77 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
78 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
78 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
79 [1]
79 [1]
80
80
81 $ tellmeabout a
81 $ tellmeabout a
82 a is an executable file with content:
82 a is an executable file with content:
83 a
83 a
84
84
85 $ hg update -C 1
85 $ hg update -C 1
86 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
86 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
87
87
88 $ hg merge --debug --tool :merge3
88 $ hg merge --debug --tool :merge3
89 searching for copies back to rev 1
89 searching for copies back to rev 1
90 resolving manifests
90 resolving manifests
91 branchmerge: True, force: False, partial: False
91 branchmerge: True, force: False, partial: False
92 ancestor: c334dc3be0da, local: 3574f3e69b1c+, remote: 521a1e40188f
92 ancestor: c334dc3be0da, local: 3574f3e69b1c+, remote: 521a1e40188f
93 preserving a for resolve of a
93 preserving a for resolve of a
94 a: versions differ -> m (premerge)
94 a: versions differ -> m (premerge)
95 picked tool ':merge3' for a (binary False symlink True changedelete False)
95 picked tool ':merge3' for a (binary False symlink True changedelete False)
96 merging a
96 merging a
97 my a@3574f3e69b1c+ other a@521a1e40188f ancestor a@c334dc3be0da
97 my a@3574f3e69b1c+ other a@521a1e40188f ancestor a@c334dc3be0da
98 warning: internal :merge3 cannot merge symlinks for a
98 warning: internal :merge3 cannot merge symlinks for a
99 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
99 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
100 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
100 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
101 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
101 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
102 [1]
102 [1]
103
103
104 $ tellmeabout a
104 $ tellmeabout a
105 a is an executable file with content:
105 a is an executable file with content:
106 a
106 a
107
107
108 $ hg update -C 1
108 $ hg update -C 1
109 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
109 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
110
110
111 $ hg merge --debug --tool :merge-local
111 $ hg merge --debug --tool :merge-local
112 searching for copies back to rev 1
112 searching for copies back to rev 1
113 resolving manifests
113 resolving manifests
114 branchmerge: True, force: False, partial: False
114 branchmerge: True, force: False, partial: False
115 ancestor: c334dc3be0da, local: 3574f3e69b1c+, remote: 521a1e40188f
115 ancestor: c334dc3be0da, local: 3574f3e69b1c+, remote: 521a1e40188f
116 preserving a for resolve of a
116 preserving a for resolve of a
117 a: versions differ -> m (premerge)
117 a: versions differ -> m (premerge)
118 picked tool ':merge-local' for a (binary False symlink True changedelete False)
118 picked tool ':merge-local' for a (binary False symlink True changedelete False)
119 merging a
119 merging a
120 my a@3574f3e69b1c+ other a@521a1e40188f ancestor a@c334dc3be0da
120 my a@3574f3e69b1c+ other a@521a1e40188f ancestor a@c334dc3be0da
121 warning: internal :merge-local cannot merge symlinks for a
121 warning: internal :merge-local cannot merge symlinks for a
122 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
122 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
123 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
123 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
124 [1]
124 [1]
125
125
126 $ tellmeabout a
126 $ tellmeabout a
127 a is an executable file with content:
127 a is an executable file with content:
128 a
128 a
129
129
130 $ hg update -C 1
130 $ hg update -C 1
131 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
131 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
132
132
133 $ hg merge --debug --tool :merge-other
133 $ hg merge --debug --tool :merge-other
134 searching for copies back to rev 1
134 searching for copies back to rev 1
135 resolving manifests
135 resolving manifests
136 branchmerge: True, force: False, partial: False
136 branchmerge: True, force: False, partial: False
137 ancestor: c334dc3be0da, local: 3574f3e69b1c+, remote: 521a1e40188f
137 ancestor: c334dc3be0da, local: 3574f3e69b1c+, remote: 521a1e40188f
138 preserving a for resolve of a
138 preserving a for resolve of a
139 a: versions differ -> m (premerge)
139 a: versions differ -> m (premerge)
140 picked tool ':merge-other' for a (binary False symlink True changedelete False)
140 picked tool ':merge-other' for a (binary False symlink True changedelete False)
141 merging a
141 merging a
142 my a@3574f3e69b1c+ other a@521a1e40188f ancestor a@c334dc3be0da
142 my a@3574f3e69b1c+ other a@521a1e40188f ancestor a@c334dc3be0da
143 warning: internal :merge-other cannot merge symlinks for a
143 warning: internal :merge-other cannot merge symlinks for a
144 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
144 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
145 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
145 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
146 [1]
146 [1]
147
147
148 $ tellmeabout a
148 $ tellmeabout a
149 a is an executable file with content:
149 a is an executable file with content:
150 a
150 a
151
151
152 Update to link without local change should get us a symlink (issue3316):
152 Update to link without local change should get us a symlink (issue3316):
153
153
154 $ hg up -C 0
154 $ hg up -C 0
155 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
155 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
156 $ hg up
156 $ hg up
157 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
157 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
158 $ hg st
158 $ hg st
159 ? a.orig
159 ? a.orig
160
160
161 Update to link with local change should cause a merge prompt (issue3200):
161 Update to link with local change should cause a merge prompt (issue3200):
162
162
163 $ hg up -Cq 0
163 $ hg up -Cq 0
164 $ echo data > a
164 $ echo data > a
165 $ HGMERGE= hg up -y --debug
165 $ HGMERGE= hg up -y --debug
166 searching for copies back to rev 2
166 searching for copies back to rev 2
167 resolving manifests
167 resolving manifests
168 branchmerge: False, force: False, partial: False
168 branchmerge: False, force: False, partial: False
169 ancestor: c334dc3be0da, local: c334dc3be0da+, remote: 521a1e40188f
169 ancestor: c334dc3be0da, local: c334dc3be0da+, remote: 521a1e40188f
170 preserving a for resolve of a
170 preserving a for resolve of a
171 a: versions differ -> m (premerge)
171 a: versions differ -> m (premerge)
172 (couldn't find merge tool hgmerge|tool hgmerge can't handle symlinks) (re)
172 (couldn't find merge tool hgmerge|tool hgmerge can't handle symlinks) (re)
173 picked tool ':prompt' for a (binary False symlink True changedelete False)
173 picked tool ':prompt' for a (binary False symlink True changedelete False)
174 no tool found to merge a
174 no tool found to merge a
175 keep (l)ocal or take (o)ther? l
175 keep (l)ocal, take (o)ther, or leave (u)nresolved? l
176 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
176 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
177 $ hg diff --git
177 $ hg diff --git
178 diff --git a/a b/a
178 diff --git a/a b/a
179 old mode 120000
179 old mode 120000
180 new mode 100644
180 new mode 100644
181 --- a/a
181 --- a/a
182 +++ b/a
182 +++ b/a
183 @@ -1,1 +1,1 @@
183 @@ -1,1 +1,1 @@
184 -symlink
184 -symlink
185 \ No newline at end of file
185 \ No newline at end of file
186 +data
186 +data
187
187
188
188
189 Test only 'l' change - happens rarely, except when recovering from situations
189 Test only 'l' change - happens rarely, except when recovering from situations
190 where that was what happened.
190 where that was what happened.
191
191
192 $ hg init test2
192 $ hg init test2
193 $ cd test2
193 $ cd test2
194 $ printf base > f
194 $ printf base > f
195 $ hg ci -Aqm0
195 $ hg ci -Aqm0
196 $ echo file > f
196 $ echo file > f
197 $ echo content >> f
197 $ echo content >> f
198 $ hg ci -qm1
198 $ hg ci -qm1
199 $ hg up -qr0
199 $ hg up -qr0
200 $ rm f
200 $ rm f
201 $ ln -s base f
201 $ ln -s base f
202 $ hg ci -qm2
202 $ hg ci -qm2
203 $ hg merge
203 $ hg merge
204 merging f
204 merging f
205 warning: internal :merge cannot merge symlinks for f
205 warning: internal :merge cannot merge symlinks for f
206 warning: conflicts while merging f! (edit, then use 'hg resolve --mark')
206 warning: conflicts while merging f! (edit, then use 'hg resolve --mark')
207 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
207 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
208 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
208 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
209 [1]
209 [1]
210 $ tellmeabout f
210 $ tellmeabout f
211 f is a symlink:
211 f is a symlink:
212 f -> base
212 f -> base
213
213
214 $ hg up -Cqr1
214 $ hg up -Cqr1
215 $ hg merge
215 $ hg merge
216 merging f
216 merging f
217 warning: internal :merge cannot merge symlinks for f
217 warning: internal :merge cannot merge symlinks for f
218 warning: conflicts while merging f! (edit, then use 'hg resolve --mark')
218 warning: conflicts while merging f! (edit, then use 'hg resolve --mark')
219 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
219 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
220 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
220 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
221 [1]
221 [1]
222 $ tellmeabout f
222 $ tellmeabout f
223 f is a plain file with content:
223 f is a plain file with content:
224 file
224 file
225 content
225 content
226
226
227 $ cd ..
227 $ cd ..
228
228
229 Test removed 'x' flag merged with change to symlink
229 Test removed 'x' flag merged with change to symlink
230
230
231 $ hg init test3
231 $ hg init test3
232 $ cd test3
232 $ cd test3
233 $ echo f > f
233 $ echo f > f
234 $ chmod +x f
234 $ chmod +x f
235 $ hg ci -Aqm0
235 $ hg ci -Aqm0
236 $ chmod -x f
236 $ chmod -x f
237 $ hg ci -qm1
237 $ hg ci -qm1
238 $ hg up -qr0
238 $ hg up -qr0
239 $ rm f
239 $ rm f
240 $ ln -s dangling f
240 $ ln -s dangling f
241 $ hg ci -qm2
241 $ hg ci -qm2
242 $ hg merge
242 $ hg merge
243 merging f
243 merging f
244 warning: internal :merge cannot merge symlinks for f
244 warning: internal :merge cannot merge symlinks for f
245 warning: conflicts while merging f! (edit, then use 'hg resolve --mark')
245 warning: conflicts while merging f! (edit, then use 'hg resolve --mark')
246 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
246 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
247 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
247 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
248 [1]
248 [1]
249 $ tellmeabout f
249 $ tellmeabout f
250 f is a symlink:
250 f is a symlink:
251 f -> dangling
251 f -> dangling
252
252
253 $ hg up -Cqr1
253 $ hg up -Cqr1
254 $ hg merge
254 $ hg merge
255 merging f
255 merging f
256 warning: internal :merge cannot merge symlinks for f
256 warning: internal :merge cannot merge symlinks for f
257 warning: conflicts while merging f! (edit, then use 'hg resolve --mark')
257 warning: conflicts while merging f! (edit, then use 'hg resolve --mark')
258 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
258 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
259 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
259 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
260 [1]
260 [1]
261 $ tellmeabout f
261 $ tellmeabout f
262 f is a plain file with content:
262 f is a plain file with content:
263 f
263 f
264
264
265 Test removed 'x' flag merged with content change - both ways
265 Test removed 'x' flag merged with content change - both ways
266
266
267 $ hg up -Cqr0
267 $ hg up -Cqr0
268 $ echo change > f
268 $ echo change > f
269 $ hg ci -qm3
269 $ hg ci -qm3
270 $ hg merge -r1
270 $ hg merge -r1
271 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
271 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
272 (branch merge, don't forget to commit)
272 (branch merge, don't forget to commit)
273 $ tellmeabout f
273 $ tellmeabout f
274 f is a plain file with content:
274 f is a plain file with content:
275 change
275 change
276
276
277 $ hg up -qCr1
277 $ hg up -qCr1
278 $ hg merge -r3
278 $ hg merge -r3
279 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
279 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
280 (branch merge, don't forget to commit)
280 (branch merge, don't forget to commit)
281 $ tellmeabout f
281 $ tellmeabout f
282 f is a plain file with content:
282 f is a plain file with content:
283 change
283 change
284
284
285 $ cd ..
285 $ cd ..
286
286
287 Test merge with no common ancestor:
287 Test merge with no common ancestor:
288 a: just different
288 a: just different
289 b: x vs -, different (cannot calculate x, cannot ask merge tool)
289 b: x vs -, different (cannot calculate x, cannot ask merge tool)
290 c: x vs -, same (cannot calculate x, merge tool is no good)
290 c: x vs -, same (cannot calculate x, merge tool is no good)
291 d: x vs l, different
291 d: x vs l, different
292 e: x vs l, same
292 e: x vs l, same
293 f: - vs l, different
293 f: - vs l, different
294 g: - vs l, same
294 g: - vs l, same
295 h: l vs l, different
295 h: l vs l, different
296 (where same means the filelog entry is shared and there thus is an ancestor!)
296 (where same means the filelog entry is shared and there thus is an ancestor!)
297
297
298 $ hg init test4
298 $ hg init test4
299 $ cd test4
299 $ cd test4
300 $ echo 0 > 0
300 $ echo 0 > 0
301 $ hg ci -Aqm0
301 $ hg ci -Aqm0
302
302
303 $ echo 1 > a
303 $ echo 1 > a
304 $ echo 1 > b
304 $ echo 1 > b
305 $ chmod +x b
305 $ chmod +x b
306 $ echo x > c
306 $ echo x > c
307 $ chmod +x c
307 $ chmod +x c
308 $ echo 1 > d
308 $ echo 1 > d
309 $ chmod +x d
309 $ chmod +x d
310 $ printf x > e
310 $ printf x > e
311 $ chmod +x e
311 $ chmod +x e
312 $ echo 1 > f
312 $ echo 1 > f
313 $ printf x > g
313 $ printf x > g
314 $ ln -s 1 h
314 $ ln -s 1 h
315 $ hg ci -qAm1
315 $ hg ci -qAm1
316
316
317 $ hg up -qr0
317 $ hg up -qr0
318 $ echo 2 > a
318 $ echo 2 > a
319 $ echo 2 > b
319 $ echo 2 > b
320 $ echo x > c
320 $ echo x > c
321 $ ln -s 2 d
321 $ ln -s 2 d
322 $ ln -s x e
322 $ ln -s x e
323 $ ln -s 2 f
323 $ ln -s 2 f
324 $ ln -s x g
324 $ ln -s x g
325 $ ln -s 2 h
325 $ ln -s 2 h
326 $ hg ci -Aqm2
326 $ hg ci -Aqm2
327
327
328 $ hg merge
328 $ hg merge
329 merging a
329 merging a
330 warning: cannot merge flags for b
330 warning: cannot merge flags for b
331 merging b
331 merging b
332 warning: cannot merge flags for c
332 warning: cannot merge flags for c
333 merging d
333 merging d
334 warning: internal :merge cannot merge symlinks for d
334 warning: internal :merge cannot merge symlinks for d
335 warning: conflicts while merging d! (edit, then use 'hg resolve --mark')
335 warning: conflicts while merging d! (edit, then use 'hg resolve --mark')
336 merging f
336 merging f
337 warning: internal :merge cannot merge symlinks for f
337 warning: internal :merge cannot merge symlinks for f
338 warning: conflicts while merging f! (edit, then use 'hg resolve --mark')
338 warning: conflicts while merging f! (edit, then use 'hg resolve --mark')
339 merging h
339 merging h
340 warning: internal :merge cannot merge symlinks for h
340 warning: internal :merge cannot merge symlinks for h
341 warning: conflicts while merging h! (edit, then use 'hg resolve --mark')
341 warning: conflicts while merging h! (edit, then use 'hg resolve --mark')
342 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
342 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
343 warning: conflicts while merging b! (edit, then use 'hg resolve --mark')
343 warning: conflicts while merging b! (edit, then use 'hg resolve --mark')
344 3 files updated, 0 files merged, 0 files removed, 5 files unresolved
344 3 files updated, 0 files merged, 0 files removed, 5 files unresolved
345 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
345 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
346 [1]
346 [1]
347 $ hg resolve -l
347 $ hg resolve -l
348 U a
348 U a
349 U b
349 U b
350 U d
350 U d
351 U f
351 U f
352 U h
352 U h
353 $ tellmeabout a
353 $ tellmeabout a
354 a is a plain file with content:
354 a is a plain file with content:
355 <<<<<<< local: 0139c5610547 - test: 2
355 <<<<<<< local: 0139c5610547 - test: 2
356 2
356 2
357 =======
357 =======
358 1
358 1
359 >>>>>>> other: 97e29675e796 - test: 1
359 >>>>>>> other: 97e29675e796 - test: 1
360 $ tellmeabout b
360 $ tellmeabout b
361 b is a plain file with content:
361 b is a plain file with content:
362 <<<<<<< local: 0139c5610547 - test: 2
362 <<<<<<< local: 0139c5610547 - test: 2
363 2
363 2
364 =======
364 =======
365 1
365 1
366 >>>>>>> other: 97e29675e796 - test: 1
366 >>>>>>> other: 97e29675e796 - test: 1
367 $ tellmeabout c
367 $ tellmeabout c
368 c is a plain file with content:
368 c is a plain file with content:
369 x
369 x
370 $ tellmeabout d
370 $ tellmeabout d
371 d is a symlink:
371 d is a symlink:
372 d -> 2
372 d -> 2
373 $ tellmeabout e
373 $ tellmeabout e
374 e is a symlink:
374 e is a symlink:
375 e -> x
375 e -> x
376 $ tellmeabout f
376 $ tellmeabout f
377 f is a symlink:
377 f is a symlink:
378 f -> 2
378 f -> 2
379 $ tellmeabout g
379 $ tellmeabout g
380 g is a symlink:
380 g is a symlink:
381 g -> x
381 g -> x
382 $ tellmeabout h
382 $ tellmeabout h
383 h is a symlink:
383 h is a symlink:
384 h -> 2
384 h -> 2
385
385
386 $ hg up -Cqr1
386 $ hg up -Cqr1
387 $ hg merge
387 $ hg merge
388 merging a
388 merging a
389 warning: cannot merge flags for b
389 warning: cannot merge flags for b
390 merging b
390 merging b
391 warning: cannot merge flags for c
391 warning: cannot merge flags for c
392 merging d
392 merging d
393 warning: internal :merge cannot merge symlinks for d
393 warning: internal :merge cannot merge symlinks for d
394 warning: conflicts while merging d! (edit, then use 'hg resolve --mark')
394 warning: conflicts while merging d! (edit, then use 'hg resolve --mark')
395 merging f
395 merging f
396 warning: internal :merge cannot merge symlinks for f
396 warning: internal :merge cannot merge symlinks for f
397 warning: conflicts while merging f! (edit, then use 'hg resolve --mark')
397 warning: conflicts while merging f! (edit, then use 'hg resolve --mark')
398 merging h
398 merging h
399 warning: internal :merge cannot merge symlinks for h
399 warning: internal :merge cannot merge symlinks for h
400 warning: conflicts while merging h! (edit, then use 'hg resolve --mark')
400 warning: conflicts while merging h! (edit, then use 'hg resolve --mark')
401 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
401 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
402 warning: conflicts while merging b! (edit, then use 'hg resolve --mark')
402 warning: conflicts while merging b! (edit, then use 'hg resolve --mark')
403 3 files updated, 0 files merged, 0 files removed, 5 files unresolved
403 3 files updated, 0 files merged, 0 files removed, 5 files unresolved
404 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
404 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
405 [1]
405 [1]
406 $ tellmeabout a
406 $ tellmeabout a
407 a is a plain file with content:
407 a is a plain file with content:
408 <<<<<<< local: 97e29675e796 - test: 1
408 <<<<<<< local: 97e29675e796 - test: 1
409 1
409 1
410 =======
410 =======
411 2
411 2
412 >>>>>>> other: 0139c5610547 - test: 2
412 >>>>>>> other: 0139c5610547 - test: 2
413 $ tellmeabout b
413 $ tellmeabout b
414 b is an executable file with content:
414 b is an executable file with content:
415 <<<<<<< local: 97e29675e796 - test: 1
415 <<<<<<< local: 97e29675e796 - test: 1
416 1
416 1
417 =======
417 =======
418 2
418 2
419 >>>>>>> other: 0139c5610547 - test: 2
419 >>>>>>> other: 0139c5610547 - test: 2
420 $ tellmeabout c
420 $ tellmeabout c
421 c is an executable file with content:
421 c is an executable file with content:
422 x
422 x
423 $ tellmeabout d
423 $ tellmeabout d
424 d is an executable file with content:
424 d is an executable file with content:
425 1
425 1
426 $ tellmeabout e
426 $ tellmeabout e
427 e is an executable file with content:
427 e is an executable file with content:
428 x (no-eol)
428 x (no-eol)
429 $ tellmeabout f
429 $ tellmeabout f
430 f is a plain file with content:
430 f is a plain file with content:
431 1
431 1
432 $ tellmeabout g
432 $ tellmeabout g
433 g is a plain file with content:
433 g is a plain file with content:
434 x (no-eol)
434 x (no-eol)
435 $ tellmeabout h
435 $ tellmeabout h
436 h is a symlink:
436 h is a symlink:
437 h -> 1
437 h -> 1
438
438
439 $ cd ..
439 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now