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