##// END OF EJS Templates
merge: better debug messages before/after invoking external merge tool
Mads Kiilerich -
r24727:5668202c default
parent child Browse files
Show More
@@ -1,476 +1,479
1 # filemerge.py - file-level merge handling for Mercurial
1 # filemerge.py - file-level merge handling for Mercurial
2 #
2 #
3 # Copyright 2006, 2007, 2008 Matt Mackall <mpm@selenic.com>
3 # Copyright 2006, 2007, 2008 Matt Mackall <mpm@selenic.com>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 from node import short
8 from node import short
9 from i18n import _
9 from i18n import _
10 import util, simplemerge, match, error, templater, templatekw
10 import util, simplemerge, match, error, templater, templatekw
11 import os, tempfile, re, filecmp
11 import os, tempfile, re, filecmp
12 import tagmerge
12 import tagmerge
13
13
14 def _toolstr(ui, tool, part, default=""):
14 def _toolstr(ui, tool, part, default=""):
15 return ui.config("merge-tools", tool + "." + part, default)
15 return ui.config("merge-tools", tool + "." + part, default)
16
16
17 def _toolbool(ui, tool, part, default=False):
17 def _toolbool(ui, tool, part, default=False):
18 return ui.configbool("merge-tools", tool + "." + part, default)
18 return ui.configbool("merge-tools", tool + "." + part, default)
19
19
20 def _toollist(ui, tool, part, default=[]):
20 def _toollist(ui, tool, part, default=[]):
21 return ui.configlist("merge-tools", tool + "." + part, default)
21 return ui.configlist("merge-tools", tool + "." + part, default)
22
22
23 internals = {}
23 internals = {}
24 # Merge tools to document.
24 # Merge tools to document.
25 internalsdoc = {}
25 internalsdoc = {}
26
26
27 def internaltool(name, trymerge, onfailure=None):
27 def internaltool(name, trymerge, onfailure=None):
28 '''return a decorator for populating internal merge tool table'''
28 '''return a decorator for populating internal merge tool table'''
29 def decorator(func):
29 def decorator(func):
30 fullname = ':' + name
30 fullname = ':' + name
31 func.__doc__ = "``%s``\n" % fullname + func.__doc__.strip()
31 func.__doc__ = "``%s``\n" % fullname + func.__doc__.strip()
32 internals[fullname] = func
32 internals[fullname] = func
33 internals['internal:' + name] = func
33 internals['internal:' + name] = func
34 internalsdoc[fullname] = func
34 internalsdoc[fullname] = func
35 func.trymerge = trymerge
35 func.trymerge = trymerge
36 func.onfailure = onfailure
36 func.onfailure = onfailure
37 return func
37 return func
38 return decorator
38 return decorator
39
39
40 def _findtool(ui, tool):
40 def _findtool(ui, tool):
41 if tool in internals:
41 if tool in internals:
42 return tool
42 return tool
43 return findexternaltool(ui, tool)
43 return findexternaltool(ui, tool)
44
44
45 def findexternaltool(ui, tool):
45 def findexternaltool(ui, tool):
46 for kn in ("regkey", "regkeyalt"):
46 for kn in ("regkey", "regkeyalt"):
47 k = _toolstr(ui, tool, kn)
47 k = _toolstr(ui, tool, kn)
48 if not k:
48 if not k:
49 continue
49 continue
50 p = util.lookupreg(k, _toolstr(ui, tool, "regname"))
50 p = util.lookupreg(k, _toolstr(ui, tool, "regname"))
51 if p:
51 if p:
52 p = util.findexe(p + _toolstr(ui, tool, "regappend"))
52 p = util.findexe(p + _toolstr(ui, tool, "regappend"))
53 if p:
53 if p:
54 return p
54 return p
55 exe = _toolstr(ui, tool, "executable", tool)
55 exe = _toolstr(ui, tool, "executable", tool)
56 return util.findexe(util.expandpath(exe))
56 return util.findexe(util.expandpath(exe))
57
57
58 def _picktool(repo, ui, path, binary, symlink):
58 def _picktool(repo, ui, path, binary, symlink):
59 def check(tool, pat, symlink, binary):
59 def check(tool, pat, symlink, binary):
60 tmsg = tool
60 tmsg = tool
61 if pat:
61 if pat:
62 tmsg += " specified for " + pat
62 tmsg += " specified for " + pat
63 if not _findtool(ui, tool):
63 if not _findtool(ui, tool):
64 if pat: # explicitly requested tool deserves a warning
64 if pat: # explicitly requested tool deserves a warning
65 ui.warn(_("couldn't find merge tool %s\n") % tmsg)
65 ui.warn(_("couldn't find merge tool %s\n") % tmsg)
66 else: # configured but non-existing tools are more silent
66 else: # configured but non-existing tools are more silent
67 ui.note(_("couldn't find merge tool %s\n") % tmsg)
67 ui.note(_("couldn't find merge tool %s\n") % tmsg)
68 elif symlink and not _toolbool(ui, tool, "symlink"):
68 elif symlink and not _toolbool(ui, tool, "symlink"):
69 ui.warn(_("tool %s can't handle symlinks\n") % tmsg)
69 ui.warn(_("tool %s can't handle symlinks\n") % tmsg)
70 elif binary and not _toolbool(ui, tool, "binary"):
70 elif binary and not _toolbool(ui, tool, "binary"):
71 ui.warn(_("tool %s can't handle binary\n") % tmsg)
71 ui.warn(_("tool %s can't handle binary\n") % tmsg)
72 elif not util.gui() and _toolbool(ui, tool, "gui"):
72 elif not util.gui() and _toolbool(ui, tool, "gui"):
73 ui.warn(_("tool %s requires a GUI\n") % tmsg)
73 ui.warn(_("tool %s requires a GUI\n") % tmsg)
74 else:
74 else:
75 return True
75 return True
76 return False
76 return False
77
77
78 # forcemerge comes from command line arguments, highest priority
78 # forcemerge comes from command line arguments, highest priority
79 force = ui.config('ui', 'forcemerge')
79 force = ui.config('ui', 'forcemerge')
80 if force:
80 if force:
81 toolpath = _findtool(ui, force)
81 toolpath = _findtool(ui, force)
82 if toolpath:
82 if toolpath:
83 return (force, util.shellquote(toolpath))
83 return (force, util.shellquote(toolpath))
84 else:
84 else:
85 # mimic HGMERGE if given tool not found
85 # mimic HGMERGE if given tool not found
86 return (force, force)
86 return (force, force)
87
87
88 # HGMERGE takes next precedence
88 # HGMERGE takes next precedence
89 hgmerge = os.environ.get("HGMERGE")
89 hgmerge = os.environ.get("HGMERGE")
90 if hgmerge:
90 if hgmerge:
91 return (hgmerge, hgmerge)
91 return (hgmerge, hgmerge)
92
92
93 # then patterns
93 # then patterns
94 for pat, tool in ui.configitems("merge-patterns"):
94 for pat, tool in ui.configitems("merge-patterns"):
95 mf = match.match(repo.root, '', [pat])
95 mf = match.match(repo.root, '', [pat])
96 if mf(path) and check(tool, pat, symlink, False):
96 if mf(path) and check(tool, pat, symlink, False):
97 toolpath = _findtool(ui, tool)
97 toolpath = _findtool(ui, tool)
98 return (tool, util.shellquote(toolpath))
98 return (tool, util.shellquote(toolpath))
99
99
100 # then merge tools
100 # then merge tools
101 tools = {}
101 tools = {}
102 for k, v in ui.configitems("merge-tools"):
102 for k, v in ui.configitems("merge-tools"):
103 t = k.split('.')[0]
103 t = k.split('.')[0]
104 if t not in tools:
104 if t not in tools:
105 tools[t] = int(_toolstr(ui, t, "priority", "0"))
105 tools[t] = int(_toolstr(ui, t, "priority", "0"))
106 names = tools.keys()
106 names = tools.keys()
107 tools = sorted([(-p, t) for t, p in tools.items()])
107 tools = sorted([(-p, t) for t, p in tools.items()])
108 uimerge = ui.config("ui", "merge")
108 uimerge = ui.config("ui", "merge")
109 if uimerge:
109 if uimerge:
110 if uimerge not in names:
110 if uimerge not in names:
111 return (uimerge, uimerge)
111 return (uimerge, uimerge)
112 tools.insert(0, (None, uimerge)) # highest priority
112 tools.insert(0, (None, uimerge)) # highest priority
113 tools.append((None, "hgmerge")) # the old default, if found
113 tools.append((None, "hgmerge")) # the old default, if found
114 for p, t in tools:
114 for p, t in tools:
115 if check(t, None, symlink, binary):
115 if check(t, None, symlink, binary):
116 toolpath = _findtool(ui, t)
116 toolpath = _findtool(ui, t)
117 return (t, util.shellquote(toolpath))
117 return (t, util.shellquote(toolpath))
118
118
119 # internal merge or prompt as last resort
119 # internal merge or prompt as last resort
120 if symlink or binary:
120 if symlink or binary:
121 return ":prompt", None
121 return ":prompt", None
122 return ":merge", None
122 return ":merge", None
123
123
124 def _eoltype(data):
124 def _eoltype(data):
125 "Guess the EOL type of a file"
125 "Guess the EOL type of a file"
126 if '\0' in data: # binary
126 if '\0' in data: # binary
127 return None
127 return None
128 if '\r\n' in data: # Windows
128 if '\r\n' in data: # Windows
129 return '\r\n'
129 return '\r\n'
130 if '\r' in data: # Old Mac
130 if '\r' in data: # Old Mac
131 return '\r'
131 return '\r'
132 if '\n' in data: # UNIX
132 if '\n' in data: # UNIX
133 return '\n'
133 return '\n'
134 return None # unknown
134 return None # unknown
135
135
136 def _matcheol(file, origfile):
136 def _matcheol(file, origfile):
137 "Convert EOL markers in a file to match origfile"
137 "Convert EOL markers in a file to match origfile"
138 tostyle = _eoltype(util.readfile(origfile))
138 tostyle = _eoltype(util.readfile(origfile))
139 if tostyle:
139 if tostyle:
140 data = util.readfile(file)
140 data = util.readfile(file)
141 style = _eoltype(data)
141 style = _eoltype(data)
142 if style:
142 if style:
143 newdata = data.replace(style, tostyle)
143 newdata = data.replace(style, tostyle)
144 if newdata != data:
144 if newdata != data:
145 util.writefile(file, newdata)
145 util.writefile(file, newdata)
146
146
147 @internaltool('prompt', False)
147 @internaltool('prompt', False)
148 def _iprompt(repo, mynode, orig, fcd, fco, fca, toolconf):
148 def _iprompt(repo, mynode, orig, fcd, fco, fca, toolconf):
149 """Asks the user which of the local or the other version to keep as
149 """Asks the user which of the local or the other version to keep as
150 the merged version."""
150 the merged version."""
151 ui = repo.ui
151 ui = repo.ui
152 fd = fcd.path()
152 fd = fcd.path()
153
153
154 if ui.promptchoice(_(" no tool found to merge %s\n"
154 if ui.promptchoice(_(" no tool found to merge %s\n"
155 "keep (l)ocal or take (o)ther?"
155 "keep (l)ocal or take (o)ther?"
156 "$$ &Local $$ &Other") % fd, 0):
156 "$$ &Local $$ &Other") % fd, 0):
157 return _iother(repo, mynode, orig, fcd, fco, fca, toolconf)
157 return _iother(repo, mynode, orig, fcd, fco, fca, toolconf)
158 else:
158 else:
159 return _ilocal(repo, mynode, orig, fcd, fco, fca, toolconf)
159 return _ilocal(repo, mynode, orig, fcd, fco, fca, toolconf)
160
160
161 @internaltool('local', False)
161 @internaltool('local', False)
162 def _ilocal(repo, mynode, orig, fcd, fco, fca, toolconf):
162 def _ilocal(repo, mynode, orig, fcd, fco, fca, toolconf):
163 """Uses the local version of files as the merged version."""
163 """Uses the local version of files as the merged version."""
164 return 0
164 return 0
165
165
166 @internaltool('other', False)
166 @internaltool('other', False)
167 def _iother(repo, mynode, orig, fcd, fco, fca, toolconf):
167 def _iother(repo, mynode, orig, fcd, fco, fca, toolconf):
168 """Uses the other version of files as the merged version."""
168 """Uses the other version of files as the merged version."""
169 repo.wwrite(fcd.path(), fco.data(), fco.flags())
169 repo.wwrite(fcd.path(), fco.data(), fco.flags())
170 return 0
170 return 0
171
171
172 @internaltool('fail', False)
172 @internaltool('fail', False)
173 def _ifail(repo, mynode, orig, fcd, fco, fca, toolconf):
173 def _ifail(repo, mynode, orig, fcd, fco, fca, toolconf):
174 """
174 """
175 Rather than attempting to merge files that were modified on both
175 Rather than attempting to merge files that were modified on both
176 branches, it marks them as unresolved. The resolve command must be
176 branches, it marks them as unresolved. The resolve command must be
177 used to resolve these conflicts."""
177 used to resolve these conflicts."""
178 return 1
178 return 1
179
179
180 def _premerge(repo, toolconf, files, labels=None):
180 def _premerge(repo, toolconf, files, labels=None):
181 tool, toolpath, binary, symlink = toolconf
181 tool, toolpath, binary, symlink = toolconf
182 if symlink:
182 if symlink:
183 return 1
183 return 1
184 a, b, c, back = files
184 a, b, c, back = files
185
185
186 ui = repo.ui
186 ui = repo.ui
187
187
188 validkeep = ['keep', 'keep-merge3']
188 validkeep = ['keep', 'keep-merge3']
189
189
190 # do we attempt to simplemerge first?
190 # do we attempt to simplemerge first?
191 try:
191 try:
192 premerge = _toolbool(ui, tool, "premerge", not binary)
192 premerge = _toolbool(ui, tool, "premerge", not binary)
193 except error.ConfigError:
193 except error.ConfigError:
194 premerge = _toolstr(ui, tool, "premerge").lower()
194 premerge = _toolstr(ui, tool, "premerge").lower()
195 if premerge not in validkeep:
195 if premerge not in validkeep:
196 _valid = ', '.join(["'" + v + "'" for v in validkeep])
196 _valid = ', '.join(["'" + v + "'" for v in validkeep])
197 raise error.ConfigError(_("%s.premerge not valid "
197 raise error.ConfigError(_("%s.premerge not valid "
198 "('%s' is neither boolean nor %s)") %
198 "('%s' is neither boolean nor %s)") %
199 (tool, premerge, _valid))
199 (tool, premerge, _valid))
200
200
201 if premerge:
201 if premerge:
202 if premerge == 'keep-merge3':
202 if premerge == 'keep-merge3':
203 if not labels:
203 if not labels:
204 labels = _defaultconflictlabels
204 labels = _defaultconflictlabels
205 if len(labels) < 3:
205 if len(labels) < 3:
206 labels.append('base')
206 labels.append('base')
207 r = simplemerge.simplemerge(ui, a, b, c, quiet=True, label=labels)
207 r = simplemerge.simplemerge(ui, a, b, c, quiet=True, label=labels)
208 if not r:
208 if not r:
209 ui.debug(" premerge successful\n")
209 ui.debug(" premerge successful\n")
210 return 0
210 return 0
211 if premerge not in validkeep:
211 if premerge not in validkeep:
212 util.copyfile(back, a) # restore from backup and try again
212 util.copyfile(back, a) # restore from backup and try again
213 return 1 # continue merging
213 return 1 # continue merging
214
214
215 @internaltool('merge', True,
215 @internaltool('merge', True,
216 _("merging %s incomplete! "
216 _("merging %s incomplete! "
217 "(edit conflicts, then use 'hg resolve --mark')\n"))
217 "(edit conflicts, then use 'hg resolve --mark')\n"))
218 def _imerge(repo, mynode, orig, fcd, fco, fca, toolconf, files, labels=None):
218 def _imerge(repo, mynode, orig, fcd, fco, fca, toolconf, files, labels=None):
219 """
219 """
220 Uses the internal non-interactive simple merge algorithm for merging
220 Uses the internal non-interactive simple merge algorithm for merging
221 files. It will fail if there are any conflicts and leave markers in
221 files. It will fail if there are any conflicts and leave markers in
222 the partially merged file. Markers will have two sections, one for each side
222 the partially merged file. Markers will have two sections, one for each side
223 of merge."""
223 of merge."""
224 tool, toolpath, binary, symlink = toolconf
224 tool, toolpath, binary, symlink = toolconf
225 if symlink:
225 if symlink:
226 repo.ui.warn(_('warning: internal :merge cannot merge symlinks '
226 repo.ui.warn(_('warning: internal :merge cannot merge symlinks '
227 'for %s\n') % fcd.path())
227 'for %s\n') % fcd.path())
228 return False, 1
228 return False, 1
229 r = _premerge(repo, toolconf, files, labels=labels)
229 r = _premerge(repo, toolconf, files, labels=labels)
230 if r:
230 if r:
231 a, b, c, back = files
231 a, b, c, back = files
232
232
233 ui = repo.ui
233 ui = repo.ui
234
234
235 r = simplemerge.simplemerge(ui, a, b, c, label=labels)
235 r = simplemerge.simplemerge(ui, a, b, c, label=labels)
236 return True, r
236 return True, r
237 return False, 0
237 return False, 0
238
238
239 @internaltool('merge3', True,
239 @internaltool('merge3', True,
240 _("merging %s incomplete! "
240 _("merging %s incomplete! "
241 "(edit conflicts, then use 'hg resolve --mark')\n"))
241 "(edit conflicts, then use 'hg resolve --mark')\n"))
242 def _imerge3(repo, mynode, orig, fcd, fco, fca, toolconf, files, labels=None):
242 def _imerge3(repo, mynode, orig, fcd, fco, fca, toolconf, files, labels=None):
243 """
243 """
244 Uses the internal non-interactive simple merge algorithm for merging
244 Uses the internal non-interactive simple merge algorithm for merging
245 files. It will fail if there are any conflicts and leave markers in
245 files. It will fail if there are any conflicts and leave markers in
246 the partially merged file. Marker will have three sections, one from each
246 the partially merged file. Marker will have three sections, one from each
247 side of the merge and one for the base content."""
247 side of the merge and one for the base content."""
248 if not labels:
248 if not labels:
249 labels = _defaultconflictlabels
249 labels = _defaultconflictlabels
250 if len(labels) < 3:
250 if len(labels) < 3:
251 labels.append('base')
251 labels.append('base')
252 return _imerge(repo, mynode, orig, fcd, fco, fca, toolconf, files, labels)
252 return _imerge(repo, mynode, orig, fcd, fco, fca, toolconf, files, labels)
253
253
254 @internaltool('tagmerge', True,
254 @internaltool('tagmerge', True,
255 _("automatic tag merging of %s failed! "
255 _("automatic tag merging of %s failed! "
256 "(use 'hg resolve --tool :merge' or another merge "
256 "(use 'hg resolve --tool :merge' or another merge "
257 "tool of your choice)\n"))
257 "tool of your choice)\n"))
258 def _itagmerge(repo, mynode, orig, fcd, fco, fca, toolconf, files, labels=None):
258 def _itagmerge(repo, mynode, orig, fcd, fco, fca, toolconf, files, labels=None):
259 """
259 """
260 Uses the internal tag merge algorithm (experimental).
260 Uses the internal tag merge algorithm (experimental).
261 """
261 """
262 return tagmerge.merge(repo, fcd, fco, fca)
262 return tagmerge.merge(repo, fcd, fco, fca)
263
263
264 @internaltool('dump', True)
264 @internaltool('dump', True)
265 def _idump(repo, mynode, orig, fcd, fco, fca, toolconf, files, labels=None):
265 def _idump(repo, mynode, orig, fcd, fco, fca, toolconf, files, labels=None):
266 """
266 """
267 Creates three versions of the files to merge, containing the
267 Creates three versions of the files to merge, containing the
268 contents of local, other and base. These files can then be used to
268 contents of local, other and base. These files can then be used to
269 perform a merge manually. If the file to be merged is named
269 perform a merge manually. If the file to be merged is named
270 ``a.txt``, these files will accordingly be named ``a.txt.local``,
270 ``a.txt``, these files will accordingly be named ``a.txt.local``,
271 ``a.txt.other`` and ``a.txt.base`` and they will be placed in the
271 ``a.txt.other`` and ``a.txt.base`` and they will be placed in the
272 same directory as ``a.txt``."""
272 same directory as ``a.txt``."""
273 r = _premerge(repo, toolconf, files, labels=labels)
273 r = _premerge(repo, toolconf, files, labels=labels)
274 if r:
274 if r:
275 a, b, c, back = files
275 a, b, c, back = files
276
276
277 fd = fcd.path()
277 fd = fcd.path()
278
278
279 util.copyfile(a, a + ".local")
279 util.copyfile(a, a + ".local")
280 repo.wwrite(fd + ".other", fco.data(), fco.flags())
280 repo.wwrite(fd + ".other", fco.data(), fco.flags())
281 repo.wwrite(fd + ".base", fca.data(), fca.flags())
281 repo.wwrite(fd + ".base", fca.data(), fca.flags())
282 return False, r
282 return False, r
283
283
284 def _xmerge(repo, mynode, orig, fcd, fco, fca, toolconf, files, labels=None):
284 def _xmerge(repo, mynode, orig, fcd, fco, fca, toolconf, files, labels=None):
285 r = _premerge(repo, toolconf, files, labels=labels)
285 r = _premerge(repo, toolconf, files, labels=labels)
286 if r:
286 if r:
287 tool, toolpath, binary, symlink = toolconf
287 tool, toolpath, binary, symlink = toolconf
288 a, b, c, back = files
288 a, b, c, back = files
289 out = ""
289 out = ""
290 env = {'HG_FILE': fcd.path(),
290 env = {'HG_FILE': fcd.path(),
291 'HG_MY_NODE': short(mynode),
291 'HG_MY_NODE': short(mynode),
292 'HG_OTHER_NODE': str(fco.changectx()),
292 'HG_OTHER_NODE': str(fco.changectx()),
293 'HG_BASE_NODE': str(fca.changectx()),
293 'HG_BASE_NODE': str(fca.changectx()),
294 'HG_MY_ISLINK': 'l' in fcd.flags(),
294 'HG_MY_ISLINK': 'l' in fcd.flags(),
295 'HG_OTHER_ISLINK': 'l' in fco.flags(),
295 'HG_OTHER_ISLINK': 'l' in fco.flags(),
296 'HG_BASE_ISLINK': 'l' in fca.flags(),
296 'HG_BASE_ISLINK': 'l' in fca.flags(),
297 }
297 }
298
298
299 ui = repo.ui
299 ui = repo.ui
300
300
301 args = _toolstr(ui, tool, "args", '$local $base $other')
301 args = _toolstr(ui, tool, "args", '$local $base $other')
302 if "$output" in args:
302 if "$output" in args:
303 out, a = a, back # read input from backup, write to original
303 out, a = a, back # read input from backup, write to original
304 replace = {'local': a, 'base': b, 'other': c, 'output': out}
304 replace = {'local': a, 'base': b, 'other': c, 'output': out}
305 args = util.interpolate(r'\$', replace, args,
305 args = util.interpolate(r'\$', replace, args,
306 lambda s: util.shellquote(util.localpath(s)))
306 lambda s: util.shellquote(util.localpath(s)))
307 r = ui.system(toolpath + ' ' + args, cwd=repo.root, environ=env)
307 cmd = toolpath + ' ' + args
308 repo.ui.debug('launching merge tool: %s\n' % cmd)
309 r = ui.system(cmd, cwd=repo.root, environ=env)
310 repo.ui.debug('merge tool returned: %s\n' % r)
308 return True, r
311 return True, r
309 return False, 0
312 return False, 0
310
313
311 def _formatconflictmarker(repo, ctx, template, label, pad):
314 def _formatconflictmarker(repo, ctx, template, label, pad):
312 """Applies the given template to the ctx, prefixed by the label.
315 """Applies the given template to the ctx, prefixed by the label.
313
316
314 Pad is the minimum width of the label prefix, so that multiple markers
317 Pad is the minimum width of the label prefix, so that multiple markers
315 can have aligned templated parts.
318 can have aligned templated parts.
316 """
319 """
317 if ctx.node() is None:
320 if ctx.node() is None:
318 ctx = ctx.p1()
321 ctx = ctx.p1()
319
322
320 props = templatekw.keywords.copy()
323 props = templatekw.keywords.copy()
321 props['templ'] = template
324 props['templ'] = template
322 props['ctx'] = ctx
325 props['ctx'] = ctx
323 props['repo'] = repo
326 props['repo'] = repo
324 templateresult = template('conflictmarker', **props)
327 templateresult = template('conflictmarker', **props)
325
328
326 label = ('%s:' % label).ljust(pad + 1)
329 label = ('%s:' % label).ljust(pad + 1)
327 mark = '%s %s' % (label, templater.stringify(templateresult))
330 mark = '%s %s' % (label, templater.stringify(templateresult))
328
331
329 if mark:
332 if mark:
330 mark = mark.splitlines()[0] # split for safety
333 mark = mark.splitlines()[0] # split for safety
331
334
332 # 8 for the prefix of conflict marker lines (e.g. '<<<<<<< ')
335 # 8 for the prefix of conflict marker lines (e.g. '<<<<<<< ')
333 return util.ellipsis(mark, 80 - 8)
336 return util.ellipsis(mark, 80 - 8)
334
337
335 _defaultconflictmarker = ('{node|short} ' +
338 _defaultconflictmarker = ('{node|short} ' +
336 '{ifeq(tags, "tip", "", "{tags} ")}' +
339 '{ifeq(tags, "tip", "", "{tags} ")}' +
337 '{if(bookmarks, "{bookmarks} ")}' +
340 '{if(bookmarks, "{bookmarks} ")}' +
338 '{ifeq(branch, "default", "", "{branch} ")}' +
341 '{ifeq(branch, "default", "", "{branch} ")}' +
339 '- {author|user}: {desc|firstline}')
342 '- {author|user}: {desc|firstline}')
340
343
341 _defaultconflictlabels = ['local', 'other']
344 _defaultconflictlabels = ['local', 'other']
342
345
343 def _formatlabels(repo, fcd, fco, fca, labels):
346 def _formatlabels(repo, fcd, fco, fca, labels):
344 """Formats the given labels using the conflict marker template.
347 """Formats the given labels using the conflict marker template.
345
348
346 Returns a list of formatted labels.
349 Returns a list of formatted labels.
347 """
350 """
348 cd = fcd.changectx()
351 cd = fcd.changectx()
349 co = fco.changectx()
352 co = fco.changectx()
350 ca = fca.changectx()
353 ca = fca.changectx()
351
354
352 ui = repo.ui
355 ui = repo.ui
353 template = ui.config('ui', 'mergemarkertemplate', _defaultconflictmarker)
356 template = ui.config('ui', 'mergemarkertemplate', _defaultconflictmarker)
354 template = templater.parsestring(template, quoted=False)
357 template = templater.parsestring(template, quoted=False)
355 tmpl = templater.templater(None, cache={'conflictmarker': template})
358 tmpl = templater.templater(None, cache={'conflictmarker': template})
356
359
357 pad = max(len(l) for l in labels)
360 pad = max(len(l) for l in labels)
358
361
359 newlabels = [_formatconflictmarker(repo, cd, tmpl, labels[0], pad),
362 newlabels = [_formatconflictmarker(repo, cd, tmpl, labels[0], pad),
360 _formatconflictmarker(repo, co, tmpl, labels[1], pad)]
363 _formatconflictmarker(repo, co, tmpl, labels[1], pad)]
361 if len(labels) > 2:
364 if len(labels) > 2:
362 newlabels.append(_formatconflictmarker(repo, ca, tmpl, labels[2], pad))
365 newlabels.append(_formatconflictmarker(repo, ca, tmpl, labels[2], pad))
363 return newlabels
366 return newlabels
364
367
365 def filemerge(repo, mynode, orig, fcd, fco, fca, labels=None):
368 def filemerge(repo, mynode, orig, fcd, fco, fca, labels=None):
366 """perform a 3-way merge in the working directory
369 """perform a 3-way merge in the working directory
367
370
368 mynode = parent node before merge
371 mynode = parent node before merge
369 orig = original local filename before merge
372 orig = original local filename before merge
370 fco = other file context
373 fco = other file context
371 fca = ancestor file context
374 fca = ancestor file context
372 fcd = local file context for current/destination file
375 fcd = local file context for current/destination file
373 """
376 """
374
377
375 def temp(prefix, ctx):
378 def temp(prefix, ctx):
376 pre = "%s~%s." % (os.path.basename(ctx.path()), prefix)
379 pre = "%s~%s." % (os.path.basename(ctx.path()), prefix)
377 (fd, name) = tempfile.mkstemp(prefix=pre)
380 (fd, name) = tempfile.mkstemp(prefix=pre)
378 data = repo.wwritedata(ctx.path(), ctx.data())
381 data = repo.wwritedata(ctx.path(), ctx.data())
379 f = os.fdopen(fd, "wb")
382 f = os.fdopen(fd, "wb")
380 f.write(data)
383 f.write(data)
381 f.close()
384 f.close()
382 return name
385 return name
383
386
384 if not fco.cmp(fcd): # files identical?
387 if not fco.cmp(fcd): # files identical?
385 return None
388 return None
386
389
387 ui = repo.ui
390 ui = repo.ui
388 fd = fcd.path()
391 fd = fcd.path()
389 binary = fcd.isbinary() or fco.isbinary() or fca.isbinary()
392 binary = fcd.isbinary() or fco.isbinary() or fca.isbinary()
390 symlink = 'l' in fcd.flags() + fco.flags()
393 symlink = 'l' in fcd.flags() + fco.flags()
391 tool, toolpath = _picktool(repo, ui, fd, binary, symlink)
394 tool, toolpath = _picktool(repo, ui, fd, binary, symlink)
392 ui.debug("picked tool '%s' for %s (binary %s symlink %s)\n" %
395 ui.debug("picked tool '%s' for %s (binary %s symlink %s)\n" %
393 (tool, fd, binary, symlink))
396 (tool, fd, binary, symlink))
394
397
395 if tool in internals:
398 if tool in internals:
396 func = internals[tool]
399 func = internals[tool]
397 trymerge = func.trymerge
400 trymerge = func.trymerge
398 onfailure = func.onfailure
401 onfailure = func.onfailure
399 else:
402 else:
400 func = _xmerge
403 func = _xmerge
401 trymerge = True
404 trymerge = True
402 onfailure = _("merging %s failed!\n")
405 onfailure = _("merging %s failed!\n")
403
406
404 toolconf = tool, toolpath, binary, symlink
407 toolconf = tool, toolpath, binary, symlink
405
408
406 if not trymerge:
409 if not trymerge:
407 return func(repo, mynode, orig, fcd, fco, fca, toolconf)
410 return func(repo, mynode, orig, fcd, fco, fca, toolconf)
408
411
409 a = repo.wjoin(fd)
412 a = repo.wjoin(fd)
410 b = temp("base", fca)
413 b = temp("base", fca)
411 c = temp("other", fco)
414 c = temp("other", fco)
412 back = a + ".orig"
415 back = a + ".orig"
413 util.copyfile(a, back)
416 util.copyfile(a, back)
414
417
415 if orig != fco.path():
418 if orig != fco.path():
416 ui.status(_("merging %s and %s to %s\n") % (orig, fco.path(), fd))
419 ui.status(_("merging %s and %s to %s\n") % (orig, fco.path(), fd))
417 else:
420 else:
418 ui.status(_("merging %s\n") % fd)
421 ui.status(_("merging %s\n") % fd)
419
422
420 ui.debug("my %s other %s ancestor %s\n" % (fcd, fco, fca))
423 ui.debug("my %s other %s ancestor %s\n" % (fcd, fco, fca))
421
424
422 markerstyle = ui.config('ui', 'mergemarkers', 'basic')
425 markerstyle = ui.config('ui', 'mergemarkers', 'basic')
423 if not labels:
426 if not labels:
424 labels = _defaultconflictlabels
427 labels = _defaultconflictlabels
425 if markerstyle != 'basic':
428 if markerstyle != 'basic':
426 labels = _formatlabels(repo, fcd, fco, fca, labels)
429 labels = _formatlabels(repo, fcd, fco, fca, labels)
427
430
428 needcheck, r = func(repo, mynode, orig, fcd, fco, fca, toolconf,
431 needcheck, r = func(repo, mynode, orig, fcd, fco, fca, toolconf,
429 (a, b, c, back), labels=labels)
432 (a, b, c, back), labels=labels)
430 if not needcheck:
433 if not needcheck:
431 if r:
434 if r:
432 if onfailure:
435 if onfailure:
433 ui.warn(onfailure % fd)
436 ui.warn(onfailure % fd)
434 else:
437 else:
435 util.unlink(back)
438 util.unlink(back)
436
439
437 util.unlink(b)
440 util.unlink(b)
438 util.unlink(c)
441 util.unlink(c)
439 return r
442 return r
440
443
441 if not r and (_toolbool(ui, tool, "checkconflicts") or
444 if not r and (_toolbool(ui, tool, "checkconflicts") or
442 'conflicts' in _toollist(ui, tool, "check")):
445 'conflicts' in _toollist(ui, tool, "check")):
443 if re.search("^(<<<<<<< .*|=======|>>>>>>> .*)$", fcd.data(),
446 if re.search("^(<<<<<<< .*|=======|>>>>>>> .*)$", fcd.data(),
444 re.MULTILINE):
447 re.MULTILINE):
445 r = 1
448 r = 1
446
449
447 checked = False
450 checked = False
448 if 'prompt' in _toollist(ui, tool, "check"):
451 if 'prompt' in _toollist(ui, tool, "check"):
449 checked = True
452 checked = True
450 if ui.promptchoice(_("was merge of '%s' successful (yn)?"
453 if ui.promptchoice(_("was merge of '%s' successful (yn)?"
451 "$$ &Yes $$ &No") % fd, 1):
454 "$$ &Yes $$ &No") % fd, 1):
452 r = 1
455 r = 1
453
456
454 if not r and not checked and (_toolbool(ui, tool, "checkchanged") or
457 if not r and not checked and (_toolbool(ui, tool, "checkchanged") or
455 'changed' in _toollist(ui, tool, "check")):
458 'changed' in _toollist(ui, tool, "check")):
456 if filecmp.cmp(a, back):
459 if filecmp.cmp(a, back):
457 if ui.promptchoice(_(" output file %s appears unchanged\n"
460 if ui.promptchoice(_(" output file %s appears unchanged\n"
458 "was merge successful (yn)?"
461 "was merge successful (yn)?"
459 "$$ &Yes $$ &No") % fd, 1):
462 "$$ &Yes $$ &No") % fd, 1):
460 r = 1
463 r = 1
461
464
462 if _toolbool(ui, tool, "fixeol"):
465 if _toolbool(ui, tool, "fixeol"):
463 _matcheol(a, back)
466 _matcheol(a, back)
464
467
465 if r:
468 if r:
466 if onfailure:
469 if onfailure:
467 ui.warn(onfailure % fd)
470 ui.warn(onfailure % fd)
468 else:
471 else:
469 util.unlink(back)
472 util.unlink(back)
470
473
471 util.unlink(b)
474 util.unlink(b)
472 util.unlink(c)
475 util.unlink(c)
473 return r
476 return r
474
477
475 # tell hggettext to extract docstrings from these functions:
478 # tell hggettext to extract docstrings from these functions:
476 i18nfunctions = internals.values()
479 i18nfunctions = internals.values()
@@ -1,960 +1,1024
1
1
2 $ mkdir -p t
2 $ mkdir -p t
3 $ cd t
3 $ cd t
4 $ cat <<EOF > merge
4 $ cat <<EOF > merge
5 > import sys, os
5 > import sys, os
6 > f = open(sys.argv[1], "wb")
6 > f = open(sys.argv[1], "wb")
7 > f.write("merge %s %s %s" % (sys.argv[1], sys.argv[2], sys.argv[3]))
7 > f.write("merge %s %s %s" % (sys.argv[1], sys.argv[2], sys.argv[3]))
8 > f.close()
8 > f.close()
9 > EOF
9 > EOF
10
10
11 perform a test merge with possible renaming
11 perform a test merge with possible renaming
12 args:
12 args:
13 $1 = action in local branch
13 $1 = action in local branch
14 $2 = action in remote branch
14 $2 = action in remote branch
15 $3 = action in working dir
15 $3 = action in working dir
16 $4 = expected result
16 $4 = expected result
17
17
18 $ tm()
18 $ tm()
19 > {
19 > {
20 > hg init t
20 > hg init t
21 > cd t
21 > cd t
22 > echo "[merge]" >> .hg/hgrc
22 > echo "[merge]" >> .hg/hgrc
23 > echo "followcopies = 1" >> .hg/hgrc
23 > echo "followcopies = 1" >> .hg/hgrc
24 >
24 >
25 > # base
25 > # base
26 > echo base > a
26 > echo base > a
27 > echo base > rev # used to force commits
27 > echo base > rev # used to force commits
28 > hg add a rev
28 > hg add a rev
29 > hg ci -m "base"
29 > hg ci -m "base"
30 >
30 >
31 > # remote
31 > # remote
32 > echo remote > rev
32 > echo remote > rev
33 > if [ "$2" != "" ] ; then $2 ; fi
33 > if [ "$2" != "" ] ; then $2 ; fi
34 > hg ci -m "remote"
34 > hg ci -m "remote"
35 >
35 >
36 > # local
36 > # local
37 > hg co -q 0
37 > hg co -q 0
38 > echo local > rev
38 > echo local > rev
39 > if [ "$1" != "" ] ; then $1 ; fi
39 > if [ "$1" != "" ] ; then $1 ; fi
40 > hg ci -m "local"
40 > hg ci -m "local"
41 >
41 >
42 > # working dir
42 > # working dir
43 > echo local > rev
43 > echo local > rev
44 > if [ "$3" != "" ] ; then $3 ; fi
44 > if [ "$3" != "" ] ; then $3 ; fi
45 >
45 >
46 > # merge
46 > # merge
47 > echo "--------------"
47 > echo "--------------"
48 > echo "test L:$1 R:$2 W:$3 - $4"
48 > echo "test L:$1 R:$2 W:$3 - $4"
49 > echo "--------------"
49 > echo "--------------"
50 > hg merge -y --debug --traceback --tool="python ../merge"
50 > hg merge -y --debug --traceback --tool="python ../merge"
51 >
51 >
52 > echo "--------------"
52 > echo "--------------"
53 > hg status -camC -X rev
53 > hg status -camC -X rev
54 >
54 >
55 > hg ci -m "merge"
55 > hg ci -m "merge"
56 >
56 >
57 > echo "--------------"
57 > echo "--------------"
58 > echo
58 > echo
59 >
59 >
60 > cd ..
60 > cd ..
61 > rm -r t
61 > rm -r t
62 > }
62 > }
63 $ up() {
63 $ up() {
64 > cp rev $1
64 > cp rev $1
65 > hg add $1 2> /dev/null
65 > hg add $1 2> /dev/null
66 > if [ "$2" != "" ] ; then
66 > if [ "$2" != "" ] ; then
67 > cp rev $2
67 > cp rev $2
68 > hg add $2 2> /dev/null
68 > hg add $2 2> /dev/null
69 > fi
69 > fi
70 > }
70 > }
71 $ uc() { up $1; hg cp $1 $2; } # update + copy
71 $ uc() { up $1; hg cp $1 $2; } # update + copy
72 $ um() { up $1; hg mv $1 $2; }
72 $ um() { up $1; hg mv $1 $2; }
73 $ nc() { hg cp $1 $2; } # just copy
73 $ nc() { hg cp $1 $2; } # just copy
74 $ nm() { hg mv $1 $2; } # just move
74 $ nm() { hg mv $1 $2; } # just move
75 $ tm "up a " "nc a b" " " "1 get local a to b"
75 $ tm "up a " "nc a b" " " "1 get local a to b"
76 created new head
76 created new head
77 --------------
77 --------------
78 test L:up a R:nc a b W: - 1 get local a to b
78 test L:up a R:nc a b W: - 1 get local a to b
79 --------------
79 --------------
80 searching for copies back to rev 1
80 searching for copies back to rev 1
81 unmatched files in other:
81 unmatched files in other:
82 b
82 b
83 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
83 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
84 src: 'a' -> dst: 'b' *
84 src: 'a' -> dst: 'b' *
85 checking for directory renames
85 checking for directory renames
86 resolving manifests
86 resolving manifests
87 branchmerge: True, force: False, partial: False
87 branchmerge: True, force: False, partial: False
88 ancestor: 924404dff337, local: e300d1c794ec+, remote: 4ce40f5aca24
88 ancestor: 924404dff337, local: e300d1c794ec+, remote: 4ce40f5aca24
89 preserving a for resolve of b
89 preserving a for resolve of b
90 preserving rev for resolve of rev
90 preserving rev for resolve of rev
91 a: remote unchanged -> k
91 a: remote unchanged -> k
92 b: remote copied from a -> m
92 b: remote copied from a -> m
93 updating: b 1/2 files (50.00%)
93 updating: b 1/2 files (50.00%)
94 picked tool 'python ../merge' for b (binary False symlink False)
94 picked tool 'python ../merge' for b (binary False symlink False)
95 merging a and b to b
95 merging a and b to b
96 my b@e300d1c794ec+ other b@4ce40f5aca24 ancestor a@924404dff337
96 my b@e300d1c794ec+ other b@4ce40f5aca24 ancestor a@924404dff337
97 premerge successful
97 premerge successful
98 rev: versions differ -> m
98 rev: versions differ -> m
99 updating: rev 2/2 files (100.00%)
99 updating: rev 2/2 files (100.00%)
100 picked tool 'python ../merge' for rev (binary False symlink False)
100 picked tool 'python ../merge' for rev (binary False symlink False)
101 merging rev
101 merging rev
102 my rev@e300d1c794ec+ other rev@4ce40f5aca24 ancestor rev@924404dff337
102 my rev@e300d1c794ec+ other rev@4ce40f5aca24 ancestor rev@924404dff337
103 launching merge tool: python ../merge $TESTTMP/t/t/rev '*' '*' (glob)
104 merge tool returned: 0
103 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
105 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
104 (branch merge, don't forget to commit)
106 (branch merge, don't forget to commit)
105 --------------
107 --------------
106 M b
108 M b
107 a
109 a
108 C a
110 C a
109 --------------
111 --------------
110
112
111 $ tm "nc a b" "up a " " " "2 get rem change to a and b"
113 $ tm "nc a b" "up a " " " "2 get rem change to a and b"
112 created new head
114 created new head
113 --------------
115 --------------
114 test L:nc a b R:up a W: - 2 get rem change to a and b
116 test L:nc a b R:up a W: - 2 get rem change to a and b
115 --------------
117 --------------
116 searching for copies back to rev 1
118 searching for copies back to rev 1
117 unmatched files in local:
119 unmatched files in local:
118 b
120 b
119 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
121 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
120 src: 'a' -> dst: 'b' *
122 src: 'a' -> dst: 'b' *
121 checking for directory renames
123 checking for directory renames
122 resolving manifests
124 resolving manifests
123 branchmerge: True, force: False, partial: False
125 branchmerge: True, force: False, partial: False
124 ancestor: 924404dff337, local: 86a2aa42fc76+, remote: f4db7e329e71
126 ancestor: 924404dff337, local: 86a2aa42fc76+, remote: f4db7e329e71
125 preserving b for resolve of b
127 preserving b for resolve of b
126 preserving rev for resolve of rev
128 preserving rev for resolve of rev
127 a: remote is newer -> g
129 a: remote is newer -> g
128 getting a
130 getting a
129 updating: a 1/3 files (33.33%)
131 updating: a 1/3 files (33.33%)
130 b: local copied/moved from a -> m
132 b: local copied/moved from a -> m
131 updating: b 2/3 files (66.67%)
133 updating: b 2/3 files (66.67%)
132 picked tool 'python ../merge' for b (binary False symlink False)
134 picked tool 'python ../merge' for b (binary False symlink False)
133 merging b and a to b
135 merging b and a to b
134 my b@86a2aa42fc76+ other a@f4db7e329e71 ancestor a@924404dff337
136 my b@86a2aa42fc76+ other a@f4db7e329e71 ancestor a@924404dff337
135 premerge successful
137 premerge successful
136 rev: versions differ -> m
138 rev: versions differ -> m
137 updating: rev 3/3 files (100.00%)
139 updating: rev 3/3 files (100.00%)
138 picked tool 'python ../merge' for rev (binary False symlink False)
140 picked tool 'python ../merge' for rev (binary False symlink False)
139 merging rev
141 merging rev
140 my rev@86a2aa42fc76+ other rev@f4db7e329e71 ancestor rev@924404dff337
142 my rev@86a2aa42fc76+ other rev@f4db7e329e71 ancestor rev@924404dff337
143 launching merge tool: python ../merge $TESTTMP/t/t/rev * (glob)
144 merge tool returned: 0
141 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
145 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
142 (branch merge, don't forget to commit)
146 (branch merge, don't forget to commit)
143 --------------
147 --------------
144 M a
148 M a
145 M b
149 M b
146 a
150 a
147 --------------
151 --------------
148
152
149 $ tm "up a " "nm a b" " " "3 get local a change to b, remove a"
153 $ tm "up a " "nm a b" " " "3 get local a change to b, remove a"
150 created new head
154 created new head
151 --------------
155 --------------
152 test L:up a R:nm a b W: - 3 get local a change to b, remove a
156 test L:up a R:nm a b W: - 3 get local a change to b, remove a
153 --------------
157 --------------
154 searching for copies back to rev 1
158 searching for copies back to rev 1
155 unmatched files in other:
159 unmatched files in other:
156 b
160 b
157 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
161 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
158 src: 'a' -> dst: 'b' *
162 src: 'a' -> dst: 'b' *
159 checking for directory renames
163 checking for directory renames
160 resolving manifests
164 resolving manifests
161 branchmerge: True, force: False, partial: False
165 branchmerge: True, force: False, partial: False
162 ancestor: 924404dff337, local: e300d1c794ec+, remote: bdb19105162a
166 ancestor: 924404dff337, local: e300d1c794ec+, remote: bdb19105162a
163 preserving a for resolve of b
167 preserving a for resolve of b
164 preserving rev for resolve of rev
168 preserving rev for resolve of rev
165 removing a
169 removing a
166 b: remote moved from a -> m
170 b: remote moved from a -> m
167 updating: b 1/2 files (50.00%)
171 updating: b 1/2 files (50.00%)
168 picked tool 'python ../merge' for b (binary False symlink False)
172 picked tool 'python ../merge' for b (binary False symlink False)
169 merging a and b to b
173 merging a and b to b
170 my b@e300d1c794ec+ other b@bdb19105162a ancestor a@924404dff337
174 my b@e300d1c794ec+ other b@bdb19105162a ancestor a@924404dff337
171 premerge successful
175 premerge successful
172 rev: versions differ -> m
176 rev: versions differ -> m
173 updating: rev 2/2 files (100.00%)
177 updating: rev 2/2 files (100.00%)
174 picked tool 'python ../merge' for rev (binary False symlink False)
178 picked tool 'python ../merge' for rev (binary False symlink False)
175 merging rev
179 merging rev
176 my rev@e300d1c794ec+ other rev@bdb19105162a ancestor rev@924404dff337
180 my rev@e300d1c794ec+ other rev@bdb19105162a ancestor rev@924404dff337
181 launching merge tool: python ../merge $TESTTMP/t/t/rev * * (glob)
182 merge tool returned: 0
177 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
183 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
178 (branch merge, don't forget to commit)
184 (branch merge, don't forget to commit)
179 --------------
185 --------------
180 M b
186 M b
181 a
187 a
182 --------------
188 --------------
183
189
184 $ tm "nm a b" "up a " " " "4 get remote change to b"
190 $ tm "nm a b" "up a " " " "4 get remote change to b"
185 created new head
191 created new head
186 --------------
192 --------------
187 test L:nm a b R:up a W: - 4 get remote change to b
193 test L:nm a b R:up a W: - 4 get remote change to b
188 --------------
194 --------------
189 searching for copies back to rev 1
195 searching for copies back to rev 1
190 unmatched files in local:
196 unmatched files in local:
191 b
197 b
192 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
198 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
193 src: 'a' -> dst: 'b' *
199 src: 'a' -> dst: 'b' *
194 checking for directory renames
200 checking for directory renames
195 resolving manifests
201 resolving manifests
196 branchmerge: True, force: False, partial: False
202 branchmerge: True, force: False, partial: False
197 ancestor: 924404dff337, local: 02963e448370+, remote: f4db7e329e71
203 ancestor: 924404dff337, local: 02963e448370+, remote: f4db7e329e71
198 preserving b for resolve of b
204 preserving b for resolve of b
199 preserving rev for resolve of rev
205 preserving rev for resolve of rev
200 b: local copied/moved from a -> m
206 b: local copied/moved from a -> m
201 updating: b 1/2 files (50.00%)
207 updating: b 1/2 files (50.00%)
202 picked tool 'python ../merge' for b (binary False symlink False)
208 picked tool 'python ../merge' for b (binary False symlink False)
203 merging b and a to b
209 merging b and a to b
204 my b@02963e448370+ other a@f4db7e329e71 ancestor a@924404dff337
210 my b@02963e448370+ other a@f4db7e329e71 ancestor a@924404dff337
205 premerge successful
211 premerge successful
206 rev: versions differ -> m
212 rev: versions differ -> m
207 updating: rev 2/2 files (100.00%)
213 updating: rev 2/2 files (100.00%)
208 picked tool 'python ../merge' for rev (binary False symlink False)
214 picked tool 'python ../merge' for rev (binary False symlink False)
209 merging rev
215 merging rev
210 my rev@02963e448370+ other rev@f4db7e329e71 ancestor rev@924404dff337
216 my rev@02963e448370+ other rev@f4db7e329e71 ancestor rev@924404dff337
217 launching merge tool: python ../merge $TESTTMP/t/t/rev * * (glob)
218 merge tool returned: 0
211 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
219 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
212 (branch merge, don't forget to commit)
220 (branch merge, don't forget to commit)
213 --------------
221 --------------
214 M b
222 M b
215 a
223 a
216 --------------
224 --------------
217
225
218 $ tm " " "nc a b" " " "5 get b"
226 $ tm " " "nc a b" " " "5 get b"
219 created new head
227 created new head
220 --------------
228 --------------
221 test L: R:nc a b W: - 5 get b
229 test L: R:nc a b W: - 5 get b
222 --------------
230 --------------
223 searching for copies back to rev 1
231 searching for copies back to rev 1
224 unmatched files in other:
232 unmatched files in other:
225 b
233 b
226 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
234 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
227 src: 'a' -> dst: 'b'
235 src: 'a' -> dst: 'b'
228 checking for directory renames
236 checking for directory renames
229 resolving manifests
237 resolving manifests
230 branchmerge: True, force: False, partial: False
238 branchmerge: True, force: False, partial: False
231 ancestor: 924404dff337, local: 94b33a1b7f2d+, remote: 4ce40f5aca24
239 ancestor: 924404dff337, local: 94b33a1b7f2d+, remote: 4ce40f5aca24
232 preserving rev for resolve of rev
240 preserving rev for resolve of rev
233 b: remote created -> g
241 b: remote created -> g
234 getting b
242 getting b
235 updating: b 1/2 files (50.00%)
243 updating: b 1/2 files (50.00%)
236 rev: versions differ -> m
244 rev: versions differ -> m
237 updating: rev 2/2 files (100.00%)
245 updating: rev 2/2 files (100.00%)
238 picked tool 'python ../merge' for rev (binary False symlink False)
246 picked tool 'python ../merge' for rev (binary False symlink False)
239 merging rev
247 merging rev
240 my rev@94b33a1b7f2d+ other rev@4ce40f5aca24 ancestor rev@924404dff337
248 my rev@94b33a1b7f2d+ other rev@4ce40f5aca24 ancestor rev@924404dff337
249 launching merge tool: python ../merge $TESTTMP/t/t/rev * * (glob)
250 merge tool returned: 0
241 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
251 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
242 (branch merge, don't forget to commit)
252 (branch merge, don't forget to commit)
243 --------------
253 --------------
244 M b
254 M b
245 C a
255 C a
246 --------------
256 --------------
247
257
248 $ tm "nc a b" " " " " "6 nothing"
258 $ tm "nc a b" " " " " "6 nothing"
249 created new head
259 created new head
250 --------------
260 --------------
251 test L:nc a b R: W: - 6 nothing
261 test L:nc a b R: W: - 6 nothing
252 --------------
262 --------------
253 searching for copies back to rev 1
263 searching for copies back to rev 1
254 unmatched files in local:
264 unmatched files in local:
255 b
265 b
256 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
266 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
257 src: 'a' -> dst: 'b'
267 src: 'a' -> dst: 'b'
258 checking for directory renames
268 checking for directory renames
259 resolving manifests
269 resolving manifests
260 branchmerge: True, force: False, partial: False
270 branchmerge: True, force: False, partial: False
261 ancestor: 924404dff337, local: 86a2aa42fc76+, remote: 97c705ade336
271 ancestor: 924404dff337, local: 86a2aa42fc76+, remote: 97c705ade336
262 preserving rev for resolve of rev
272 preserving rev for resolve of rev
263 rev: versions differ -> m
273 rev: versions differ -> m
264 updating: rev 1/1 files (100.00%)
274 updating: rev 1/1 files (100.00%)
265 picked tool 'python ../merge' for rev (binary False symlink False)
275 picked tool 'python ../merge' for rev (binary False symlink False)
266 merging rev
276 merging rev
267 my rev@86a2aa42fc76+ other rev@97c705ade336 ancestor rev@924404dff337
277 my rev@86a2aa42fc76+ other rev@97c705ade336 ancestor rev@924404dff337
278 launching merge tool: python ../merge $TESTTMP/t/t/rev * * (glob)
279 merge tool returned: 0
268 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
280 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
269 (branch merge, don't forget to commit)
281 (branch merge, don't forget to commit)
270 --------------
282 --------------
271 C a
283 C a
272 C b
284 C b
273 --------------
285 --------------
274
286
275 $ tm " " "nm a b" " " "7 get b"
287 $ tm " " "nm a b" " " "7 get b"
276 created new head
288 created new head
277 --------------
289 --------------
278 test L: R:nm a b W: - 7 get b
290 test L: R:nm a b W: - 7 get b
279 --------------
291 --------------
280 searching for copies back to rev 1
292 searching for copies back to rev 1
281 unmatched files in other:
293 unmatched files in other:
282 b
294 b
283 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
295 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
284 src: 'a' -> dst: 'b'
296 src: 'a' -> dst: 'b'
285 checking for directory renames
297 checking for directory renames
286 resolving manifests
298 resolving manifests
287 branchmerge: True, force: False, partial: False
299 branchmerge: True, force: False, partial: False
288 ancestor: 924404dff337, local: 94b33a1b7f2d+, remote: bdb19105162a
300 ancestor: 924404dff337, local: 94b33a1b7f2d+, remote: bdb19105162a
289 preserving rev for resolve of rev
301 preserving rev for resolve of rev
290 a: other deleted -> r
302 a: other deleted -> r
291 removing a
303 removing a
292 updating: a 1/3 files (33.33%)
304 updating: a 1/3 files (33.33%)
293 b: remote created -> g
305 b: remote created -> g
294 getting b
306 getting b
295 updating: b 2/3 files (66.67%)
307 updating: b 2/3 files (66.67%)
296 rev: versions differ -> m
308 rev: versions differ -> m
297 updating: rev 3/3 files (100.00%)
309 updating: rev 3/3 files (100.00%)
298 picked tool 'python ../merge' for rev (binary False symlink False)
310 picked tool 'python ../merge' for rev (binary False symlink False)
299 merging rev
311 merging rev
300 my rev@94b33a1b7f2d+ other rev@bdb19105162a ancestor rev@924404dff337
312 my rev@94b33a1b7f2d+ other rev@bdb19105162a ancestor rev@924404dff337
313 launching merge tool: python ../merge $TESTTMP/t/t/rev * * (glob)
314 merge tool returned: 0
301 1 files updated, 1 files merged, 1 files removed, 0 files unresolved
315 1 files updated, 1 files merged, 1 files removed, 0 files unresolved
302 (branch merge, don't forget to commit)
316 (branch merge, don't forget to commit)
303 --------------
317 --------------
304 M b
318 M b
305 --------------
319 --------------
306
320
307 $ tm "nm a b" " " " " "8 nothing"
321 $ tm "nm a b" " " " " "8 nothing"
308 created new head
322 created new head
309 --------------
323 --------------
310 test L:nm a b R: W: - 8 nothing
324 test L:nm a b R: W: - 8 nothing
311 --------------
325 --------------
312 searching for copies back to rev 1
326 searching for copies back to rev 1
313 unmatched files in local:
327 unmatched files in local:
314 b
328 b
315 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
329 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
316 src: 'a' -> dst: 'b'
330 src: 'a' -> dst: 'b'
317 checking for directory renames
331 checking for directory renames
318 resolving manifests
332 resolving manifests
319 branchmerge: True, force: False, partial: False
333 branchmerge: True, force: False, partial: False
320 ancestor: 924404dff337, local: 02963e448370+, remote: 97c705ade336
334 ancestor: 924404dff337, local: 02963e448370+, remote: 97c705ade336
321 preserving rev for resolve of rev
335 preserving rev for resolve of rev
322 rev: versions differ -> m
336 rev: versions differ -> m
323 updating: rev 1/1 files (100.00%)
337 updating: rev 1/1 files (100.00%)
324 picked tool 'python ../merge' for rev (binary False symlink False)
338 picked tool 'python ../merge' for rev (binary False symlink False)
325 merging rev
339 merging rev
326 my rev@02963e448370+ other rev@97c705ade336 ancestor rev@924404dff337
340 my rev@02963e448370+ other rev@97c705ade336 ancestor rev@924404dff337
341 launching merge tool: python ../merge $TESTTMP/t/t/rev * * (glob)
342 merge tool returned: 0
327 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
343 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
328 (branch merge, don't forget to commit)
344 (branch merge, don't forget to commit)
329 --------------
345 --------------
330 C b
346 C b
331 --------------
347 --------------
332
348
333 $ tm "um a b" "um a b" " " "9 do merge with ancestor in a"
349 $ tm "um a b" "um a b" " " "9 do merge with ancestor in a"
334 created new head
350 created new head
335 --------------
351 --------------
336 test L:um a b R:um a b W: - 9 do merge with ancestor in a
352 test L:um a b R:um a b W: - 9 do merge with ancestor in a
337 --------------
353 --------------
338 searching for copies back to rev 1
354 searching for copies back to rev 1
339 unmatched files new in both:
355 unmatched files new in both:
340 b
356 b
341 resolving manifests
357 resolving manifests
342 branchmerge: True, force: False, partial: False
358 branchmerge: True, force: False, partial: False
343 ancestor: 924404dff337, local: 62e7bf090eba+, remote: 49b6d8032493
359 ancestor: 924404dff337, local: 62e7bf090eba+, remote: 49b6d8032493
344 preserving b for resolve of b
360 preserving b for resolve of b
345 preserving rev for resolve of rev
361 preserving rev for resolve of rev
346 b: both renamed from a -> m
362 b: both renamed from a -> m
347 updating: b 1/2 files (50.00%)
363 updating: b 1/2 files (50.00%)
348 picked tool 'python ../merge' for b (binary False symlink False)
364 picked tool 'python ../merge' for b (binary False symlink False)
349 merging b
365 merging b
350 my b@62e7bf090eba+ other b@49b6d8032493 ancestor a@924404dff337
366 my b@62e7bf090eba+ other b@49b6d8032493 ancestor a@924404dff337
367 launching merge tool: python ../merge $TESTTMP/t/t/b * * (glob)
368 merge tool returned: 0
351 rev: versions differ -> m
369 rev: versions differ -> m
352 updating: rev 2/2 files (100.00%)
370 updating: rev 2/2 files (100.00%)
353 picked tool 'python ../merge' for rev (binary False symlink False)
371 picked tool 'python ../merge' for rev (binary False symlink False)
354 merging rev
372 merging rev
355 my rev@62e7bf090eba+ other rev@49b6d8032493 ancestor rev@924404dff337
373 my rev@62e7bf090eba+ other rev@49b6d8032493 ancestor rev@924404dff337
374 launching merge tool: python ../merge $TESTTMP/t/t/rev * * (glob)
375 merge tool returned: 0
356 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
376 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
357 (branch merge, don't forget to commit)
377 (branch merge, don't forget to commit)
358 --------------
378 --------------
359 M b
379 M b
360 --------------
380 --------------
361
381
362
382
363 m "um a c" "um x c" " " "10 do merge with no ancestor"
383 m "um a c" "um x c" " " "10 do merge with no ancestor"
364
384
365 $ tm "nm a b" "nm a c" " " "11 get c, keep b"
385 $ tm "nm a b" "nm a c" " " "11 get c, keep b"
366 created new head
386 created new head
367 --------------
387 --------------
368 test L:nm a b R:nm a c W: - 11 get c, keep b
388 test L:nm a b R:nm a c W: - 11 get c, keep b
369 --------------
389 --------------
370 searching for copies back to rev 1
390 searching for copies back to rev 1
371 unmatched files in local:
391 unmatched files in local:
372 b
392 b
373 unmatched files in other:
393 unmatched files in other:
374 c
394 c
375 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
395 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
376 src: 'a' -> dst: 'b' !
396 src: 'a' -> dst: 'b' !
377 src: 'a' -> dst: 'c' !
397 src: 'a' -> dst: 'c' !
378 checking for directory renames
398 checking for directory renames
379 resolving manifests
399 resolving manifests
380 branchmerge: True, force: False, partial: False
400 branchmerge: True, force: False, partial: False
381 ancestor: 924404dff337, local: 02963e448370+, remote: fe905ef2c33e
401 ancestor: 924404dff337, local: 02963e448370+, remote: fe905ef2c33e
382 preserving rev for resolve of rev
402 preserving rev for resolve of rev
383 c: remote created -> g
403 c: remote created -> g
384 getting c
404 getting c
385 updating: c 1/2 files (50.00%)
405 updating: c 1/2 files (50.00%)
386 rev: versions differ -> m
406 rev: versions differ -> m
387 updating: rev 2/2 files (100.00%)
407 updating: rev 2/2 files (100.00%)
388 picked tool 'python ../merge' for rev (binary False symlink False)
408 picked tool 'python ../merge' for rev (binary False symlink False)
389 merging rev
409 merging rev
390 my rev@02963e448370+ other rev@fe905ef2c33e ancestor rev@924404dff337
410 my rev@02963e448370+ other rev@fe905ef2c33e ancestor rev@924404dff337
411 launching merge tool: python ../merge $TESTTMP/t/t/rev * * (glob)
412 merge tool returned: 0
391 note: possible conflict - a was renamed multiple times to:
413 note: possible conflict - a was renamed multiple times to:
392 b
414 b
393 c
415 c
394 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
416 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
395 (branch merge, don't forget to commit)
417 (branch merge, don't forget to commit)
396 --------------
418 --------------
397 M c
419 M c
398 C b
420 C b
399 --------------
421 --------------
400
422
401 $ tm "nc a b" "up b " " " "12 merge b no ancestor"
423 $ tm "nc a b" "up b " " " "12 merge b no ancestor"
402 created new head
424 created new head
403 --------------
425 --------------
404 test L:nc a b R:up b W: - 12 merge b no ancestor
426 test L:nc a b R:up b W: - 12 merge b no ancestor
405 --------------
427 --------------
406 searching for copies back to rev 1
428 searching for copies back to rev 1
407 unmatched files new in both:
429 unmatched files new in both:
408 b
430 b
409 resolving manifests
431 resolving manifests
410 branchmerge: True, force: False, partial: False
432 branchmerge: True, force: False, partial: False
411 ancestor: 924404dff337, local: 86a2aa42fc76+, remote: af30c7647fc7
433 ancestor: 924404dff337, local: 86a2aa42fc76+, remote: af30c7647fc7
412 preserving b for resolve of b
434 preserving b for resolve of b
413 preserving rev for resolve of rev
435 preserving rev for resolve of rev
414 b: both created -> m
436 b: both created -> m
415 updating: b 1/2 files (50.00%)
437 updating: b 1/2 files (50.00%)
416 picked tool 'python ../merge' for b (binary False symlink False)
438 picked tool 'python ../merge' for b (binary False symlink False)
417 merging b
439 merging b
418 my b@86a2aa42fc76+ other b@af30c7647fc7 ancestor b@000000000000
440 my b@86a2aa42fc76+ other b@af30c7647fc7 ancestor b@000000000000
441 launching merge tool: python ../merge $TESTTMP/t/t/b * * (glob)
442 merge tool returned: 0
419 rev: versions differ -> m
443 rev: versions differ -> m
420 updating: rev 2/2 files (100.00%)
444 updating: rev 2/2 files (100.00%)
421 picked tool 'python ../merge' for rev (binary False symlink False)
445 picked tool 'python ../merge' for rev (binary False symlink False)
422 merging rev
446 merging rev
423 my rev@86a2aa42fc76+ other rev@af30c7647fc7 ancestor rev@924404dff337
447 my rev@86a2aa42fc76+ other rev@af30c7647fc7 ancestor rev@924404dff337
448 launching merge tool: python ../merge $TESTTMP/t/t/rev * * (glob)
449 merge tool returned: 0
424 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
450 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
425 (branch merge, don't forget to commit)
451 (branch merge, don't forget to commit)
426 --------------
452 --------------
427 M b
453 M b
428 C a
454 C a
429 --------------
455 --------------
430
456
431 $ tm "up b " "nm a b" " " "13 merge b no ancestor"
457 $ tm "up b " "nm a b" " " "13 merge b no ancestor"
432 created new head
458 created new head
433 --------------
459 --------------
434 test L:up b R:nm a b W: - 13 merge b no ancestor
460 test L:up b R:nm a b W: - 13 merge b no ancestor
435 --------------
461 --------------
436 searching for copies back to rev 1
462 searching for copies back to rev 1
437 unmatched files new in both:
463 unmatched files new in both:
438 b
464 b
439 resolving manifests
465 resolving manifests
440 branchmerge: True, force: False, partial: False
466 branchmerge: True, force: False, partial: False
441 ancestor: 924404dff337, local: 59318016310c+, remote: bdb19105162a
467 ancestor: 924404dff337, local: 59318016310c+, remote: bdb19105162a
442 preserving b for resolve of b
468 preserving b for resolve of b
443 preserving rev for resolve of rev
469 preserving rev for resolve of rev
444 a: other deleted -> r
470 a: other deleted -> r
445 removing a
471 removing a
446 updating: a 1/3 files (33.33%)
472 updating: a 1/3 files (33.33%)
447 b: both created -> m
473 b: both created -> m
448 updating: b 2/3 files (66.67%)
474 updating: b 2/3 files (66.67%)
449 picked tool 'python ../merge' for b (binary False symlink False)
475 picked tool 'python ../merge' for b (binary False symlink False)
450 merging b
476 merging b
451 my b@59318016310c+ other b@bdb19105162a ancestor b@000000000000
477 my b@59318016310c+ other b@bdb19105162a ancestor b@000000000000
478 launching merge tool: python ../merge $TESTTMP/t/t/b * * (glob)
479 merge tool returned: 0
452 rev: versions differ -> m
480 rev: versions differ -> m
453 updating: rev 3/3 files (100.00%)
481 updating: rev 3/3 files (100.00%)
454 picked tool 'python ../merge' for rev (binary False symlink False)
482 picked tool 'python ../merge' for rev (binary False symlink False)
455 merging rev
483 merging rev
456 my rev@59318016310c+ other rev@bdb19105162a ancestor rev@924404dff337
484 my rev@59318016310c+ other rev@bdb19105162a ancestor rev@924404dff337
485 launching merge tool: python ../merge $TESTTMP/t/t/rev * * (glob)
486 merge tool returned: 0
457 0 files updated, 2 files merged, 1 files removed, 0 files unresolved
487 0 files updated, 2 files merged, 1 files removed, 0 files unresolved
458 (branch merge, don't forget to commit)
488 (branch merge, don't forget to commit)
459 --------------
489 --------------
460 M b
490 M b
461 --------------
491 --------------
462
492
463 $ tm "nc a b" "up a b" " " "14 merge b no ancestor"
493 $ tm "nc a b" "up a b" " " "14 merge b no ancestor"
464 created new head
494 created new head
465 --------------
495 --------------
466 test L:nc a b R:up a b W: - 14 merge b no ancestor
496 test L:nc a b R:up a b W: - 14 merge b no ancestor
467 --------------
497 --------------
468 searching for copies back to rev 1
498 searching for copies back to rev 1
469 unmatched files new in both:
499 unmatched files new in both:
470 b
500 b
471 resolving manifests
501 resolving manifests
472 branchmerge: True, force: False, partial: False
502 branchmerge: True, force: False, partial: False
473 ancestor: 924404dff337, local: 86a2aa42fc76+, remote: 8dbce441892a
503 ancestor: 924404dff337, local: 86a2aa42fc76+, remote: 8dbce441892a
474 preserving b for resolve of b
504 preserving b for resolve of b
475 preserving rev for resolve of rev
505 preserving rev for resolve of rev
476 a: remote is newer -> g
506 a: remote is newer -> g
477 getting a
507 getting a
478 updating: a 1/3 files (33.33%)
508 updating: a 1/3 files (33.33%)
479 b: both created -> m
509 b: both created -> m
480 updating: b 2/3 files (66.67%)
510 updating: b 2/3 files (66.67%)
481 picked tool 'python ../merge' for b (binary False symlink False)
511 picked tool 'python ../merge' for b (binary False symlink False)
482 merging b
512 merging b
483 my b@86a2aa42fc76+ other b@8dbce441892a ancestor b@000000000000
513 my b@86a2aa42fc76+ other b@8dbce441892a ancestor b@000000000000
514 launching merge tool: python ../merge $TESTTMP/t/t/b * * (glob)
515 merge tool returned: 0
484 rev: versions differ -> m
516 rev: versions differ -> m
485 updating: rev 3/3 files (100.00%)
517 updating: rev 3/3 files (100.00%)
486 picked tool 'python ../merge' for rev (binary False symlink False)
518 picked tool 'python ../merge' for rev (binary False symlink False)
487 merging rev
519 merging rev
488 my rev@86a2aa42fc76+ other rev@8dbce441892a ancestor rev@924404dff337
520 my rev@86a2aa42fc76+ other rev@8dbce441892a ancestor rev@924404dff337
521 launching merge tool: python ../merge $TESTTMP/t/t/rev * * (glob)
522 merge tool returned: 0
489 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
523 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
490 (branch merge, don't forget to commit)
524 (branch merge, don't forget to commit)
491 --------------
525 --------------
492 M a
526 M a
493 M b
527 M b
494 --------------
528 --------------
495
529
496 $ tm "up b " "nm a b" " " "15 merge b no ancestor, remove a"
530 $ tm "up b " "nm a b" " " "15 merge b no ancestor, remove a"
497 created new head
531 created new head
498 --------------
532 --------------
499 test L:up b R:nm a b W: - 15 merge b no ancestor, remove a
533 test L:up b R:nm a b W: - 15 merge b no ancestor, remove a
500 --------------
534 --------------
501 searching for copies back to rev 1
535 searching for copies back to rev 1
502 unmatched files new in both:
536 unmatched files new in both:
503 b
537 b
504 resolving manifests
538 resolving manifests
505 branchmerge: True, force: False, partial: False
539 branchmerge: True, force: False, partial: False
506 ancestor: 924404dff337, local: 59318016310c+, remote: bdb19105162a
540 ancestor: 924404dff337, local: 59318016310c+, remote: bdb19105162a
507 preserving b for resolve of b
541 preserving b for resolve of b
508 preserving rev for resolve of rev
542 preserving rev for resolve of rev
509 a: other deleted -> r
543 a: other deleted -> r
510 removing a
544 removing a
511 updating: a 1/3 files (33.33%)
545 updating: a 1/3 files (33.33%)
512 b: both created -> m
546 b: both created -> m
513 updating: b 2/3 files (66.67%)
547 updating: b 2/3 files (66.67%)
514 picked tool 'python ../merge' for b (binary False symlink False)
548 picked tool 'python ../merge' for b (binary False symlink False)
515 merging b
549 merging b
516 my b@59318016310c+ other b@bdb19105162a ancestor b@000000000000
550 my b@59318016310c+ other b@bdb19105162a ancestor b@000000000000
551 launching merge tool: python ../merge $TESTTMP/t/t/b * * (glob)
552 merge tool returned: 0
517 rev: versions differ -> m
553 rev: versions differ -> m
518 updating: rev 3/3 files (100.00%)
554 updating: rev 3/3 files (100.00%)
519 picked tool 'python ../merge' for rev (binary False symlink False)
555 picked tool 'python ../merge' for rev (binary False symlink False)
520 merging rev
556 merging rev
521 my rev@59318016310c+ other rev@bdb19105162a ancestor rev@924404dff337
557 my rev@59318016310c+ other rev@bdb19105162a ancestor rev@924404dff337
558 launching merge tool: python ../merge $TESTTMP/t/t/rev * * (glob)
559 merge tool returned: 0
522 0 files updated, 2 files merged, 1 files removed, 0 files unresolved
560 0 files updated, 2 files merged, 1 files removed, 0 files unresolved
523 (branch merge, don't forget to commit)
561 (branch merge, don't forget to commit)
524 --------------
562 --------------
525 M b
563 M b
526 --------------
564 --------------
527
565
528 $ tm "nc a b" "up a b" " " "16 get a, merge b no ancestor"
566 $ tm "nc a b" "up a b" " " "16 get a, merge b no ancestor"
529 created new head
567 created new head
530 --------------
568 --------------
531 test L:nc a b R:up a b W: - 16 get a, merge b no ancestor
569 test L:nc a b R:up a b W: - 16 get a, merge b no ancestor
532 --------------
570 --------------
533 searching for copies back to rev 1
571 searching for copies back to rev 1
534 unmatched files new in both:
572 unmatched files new in both:
535 b
573 b
536 resolving manifests
574 resolving manifests
537 branchmerge: True, force: False, partial: False
575 branchmerge: True, force: False, partial: False
538 ancestor: 924404dff337, local: 86a2aa42fc76+, remote: 8dbce441892a
576 ancestor: 924404dff337, local: 86a2aa42fc76+, remote: 8dbce441892a
539 preserving b for resolve of b
577 preserving b for resolve of b
540 preserving rev for resolve of rev
578 preserving rev for resolve of rev
541 a: remote is newer -> g
579 a: remote is newer -> g
542 getting a
580 getting a
543 updating: a 1/3 files (33.33%)
581 updating: a 1/3 files (33.33%)
544 b: both created -> m
582 b: both created -> m
545 updating: b 2/3 files (66.67%)
583 updating: b 2/3 files (66.67%)
546 picked tool 'python ../merge' for b (binary False symlink False)
584 picked tool 'python ../merge' for b (binary False symlink False)
547 merging b
585 merging b
548 my b@86a2aa42fc76+ other b@8dbce441892a ancestor b@000000000000
586 my b@86a2aa42fc76+ other b@8dbce441892a ancestor b@000000000000
587 launching merge tool: python ../merge $TESTTMP/t/t/b * * (glob)
588 merge tool returned: 0
549 rev: versions differ -> m
589 rev: versions differ -> m
550 updating: rev 3/3 files (100.00%)
590 updating: rev 3/3 files (100.00%)
551 picked tool 'python ../merge' for rev (binary False symlink False)
591 picked tool 'python ../merge' for rev (binary False symlink False)
552 merging rev
592 merging rev
553 my rev@86a2aa42fc76+ other rev@8dbce441892a ancestor rev@924404dff337
593 my rev@86a2aa42fc76+ other rev@8dbce441892a ancestor rev@924404dff337
594 launching merge tool: python ../merge $TESTTMP/t/t/rev * * (glob)
595 merge tool returned: 0
554 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
596 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
555 (branch merge, don't forget to commit)
597 (branch merge, don't forget to commit)
556 --------------
598 --------------
557 M a
599 M a
558 M b
600 M b
559 --------------
601 --------------
560
602
561 $ tm "up a b" "nc a b" " " "17 keep a, merge b no ancestor"
603 $ tm "up a b" "nc a b" " " "17 keep a, merge b no ancestor"
562 created new head
604 created new head
563 --------------
605 --------------
564 test L:up a b R:nc a b W: - 17 keep a, merge b no ancestor
606 test L:up a b R:nc a b W: - 17 keep a, merge b no ancestor
565 --------------
607 --------------
566 searching for copies back to rev 1
608 searching for copies back to rev 1
567 unmatched files new in both:
609 unmatched files new in both:
568 b
610 b
569 resolving manifests
611 resolving manifests
570 branchmerge: True, force: False, partial: False
612 branchmerge: True, force: False, partial: False
571 ancestor: 924404dff337, local: 0b76e65c8289+, remote: 4ce40f5aca24
613 ancestor: 924404dff337, local: 0b76e65c8289+, remote: 4ce40f5aca24
572 preserving b for resolve of b
614 preserving b for resolve of b
573 preserving rev for resolve of rev
615 preserving rev for resolve of rev
574 a: remote unchanged -> k
616 a: remote unchanged -> k
575 b: both created -> m
617 b: both created -> m
576 updating: b 1/2 files (50.00%)
618 updating: b 1/2 files (50.00%)
577 picked tool 'python ../merge' for b (binary False symlink False)
619 picked tool 'python ../merge' for b (binary False symlink False)
578 merging b
620 merging b
579 my b@0b76e65c8289+ other b@4ce40f5aca24 ancestor b@000000000000
621 my b@0b76e65c8289+ other b@4ce40f5aca24 ancestor b@000000000000
622 launching merge tool: python ../merge $TESTTMP/t/t/b * * (glob)
623 merge tool returned: 0
580 rev: versions differ -> m
624 rev: versions differ -> m
581 updating: rev 2/2 files (100.00%)
625 updating: rev 2/2 files (100.00%)
582 picked tool 'python ../merge' for rev (binary False symlink False)
626 picked tool 'python ../merge' for rev (binary False symlink False)
583 merging rev
627 merging rev
584 my rev@0b76e65c8289+ other rev@4ce40f5aca24 ancestor rev@924404dff337
628 my rev@0b76e65c8289+ other rev@4ce40f5aca24 ancestor rev@924404dff337
629 launching merge tool: python ../merge $TESTTMP/t/t/rev * * (glob)
630 merge tool returned: 0
585 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
631 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
586 (branch merge, don't forget to commit)
632 (branch merge, don't forget to commit)
587 --------------
633 --------------
588 M b
634 M b
589 C a
635 C a
590 --------------
636 --------------
591
637
592 $ tm "nm a b" "up a b" " " "18 merge b no ancestor"
638 $ tm "nm a b" "up a b" " " "18 merge b no ancestor"
593 created new head
639 created new head
594 --------------
640 --------------
595 test L:nm a b R:up a b W: - 18 merge b no ancestor
641 test L:nm a b R:up a b W: - 18 merge b no ancestor
596 --------------
642 --------------
597 searching for copies back to rev 1
643 searching for copies back to rev 1
598 unmatched files new in both:
644 unmatched files new in both:
599 b
645 b
600 resolving manifests
646 resolving manifests
601 branchmerge: True, force: False, partial: False
647 branchmerge: True, force: False, partial: False
602 ancestor: 924404dff337, local: 02963e448370+, remote: 8dbce441892a
648 ancestor: 924404dff337, local: 02963e448370+, remote: 8dbce441892a
603 remote changed a which local deleted
649 remote changed a which local deleted
604 use (c)hanged version or leave (d)eleted? c
650 use (c)hanged version or leave (d)eleted? c
605 preserving b for resolve of b
651 preserving b for resolve of b
606 preserving rev for resolve of rev
652 preserving rev for resolve of rev
607 a: prompt recreating -> g
653 a: prompt recreating -> g
608 getting a
654 getting a
609 updating: a 1/3 files (33.33%)
655 updating: a 1/3 files (33.33%)
610 b: both created -> m
656 b: both created -> m
611 updating: b 2/3 files (66.67%)
657 updating: b 2/3 files (66.67%)
612 picked tool 'python ../merge' for b (binary False symlink False)
658 picked tool 'python ../merge' for b (binary False symlink False)
613 merging b
659 merging b
614 my b@02963e448370+ other b@8dbce441892a ancestor b@000000000000
660 my b@02963e448370+ other b@8dbce441892a ancestor b@000000000000
661 launching merge tool: python ../merge $TESTTMP/t/t/b * * (glob)
662 merge tool returned: 0
615 rev: versions differ -> m
663 rev: versions differ -> m
616 updating: rev 3/3 files (100.00%)
664 updating: rev 3/3 files (100.00%)
617 picked tool 'python ../merge' for rev (binary False symlink False)
665 picked tool 'python ../merge' for rev (binary False symlink False)
618 merging rev
666 merging rev
619 my rev@02963e448370+ other rev@8dbce441892a ancestor rev@924404dff337
667 my rev@02963e448370+ other rev@8dbce441892a ancestor rev@924404dff337
668 launching merge tool: python ../merge $TESTTMP/t/t/rev * * (glob)
669 merge tool returned: 0
620 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
670 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
621 (branch merge, don't forget to commit)
671 (branch merge, don't forget to commit)
622 --------------
672 --------------
623 M a
673 M a
624 M b
674 M b
625 --------------
675 --------------
626
676
627 $ tm "up a b" "nm a b" " " "19 merge b no ancestor, prompt remove a"
677 $ tm "up a b" "nm a b" " " "19 merge b no ancestor, prompt remove a"
628 created new head
678 created new head
629 --------------
679 --------------
630 test L:up a b R:nm a b W: - 19 merge b no ancestor, prompt remove a
680 test L:up a b R:nm a b W: - 19 merge b no ancestor, prompt remove a
631 --------------
681 --------------
632 searching for copies back to rev 1
682 searching for copies back to rev 1
633 unmatched files new in both:
683 unmatched files new in both:
634 b
684 b
635 resolving manifests
685 resolving manifests
636 branchmerge: True, force: False, partial: False
686 branchmerge: True, force: False, partial: False
637 ancestor: 924404dff337, local: 0b76e65c8289+, remote: bdb19105162a
687 ancestor: 924404dff337, local: 0b76e65c8289+, remote: bdb19105162a
638 local changed a which remote deleted
688 local changed a which remote deleted
639 use (c)hanged version or (d)elete? c
689 use (c)hanged version or (d)elete? c
640 preserving b for resolve of b
690 preserving b for resolve of b
641 preserving rev for resolve of rev
691 preserving rev for resolve of rev
642 a: prompt keep -> a
692 a: prompt keep -> a
643 updating: a 1/3 files (33.33%)
693 updating: a 1/3 files (33.33%)
644 b: both created -> m
694 b: both created -> m
645 updating: b 2/3 files (66.67%)
695 updating: b 2/3 files (66.67%)
646 picked tool 'python ../merge' for b (binary False symlink False)
696 picked tool 'python ../merge' for b (binary False symlink False)
647 merging b
697 merging b
648 my b@0b76e65c8289+ other b@bdb19105162a ancestor b@000000000000
698 my b@0b76e65c8289+ other b@bdb19105162a ancestor b@000000000000
699 launching merge tool: python ../merge $TESTTMP/t/t/b * * (glob)
700 merge tool returned: 0
649 rev: versions differ -> m
701 rev: versions differ -> m
650 updating: rev 3/3 files (100.00%)
702 updating: rev 3/3 files (100.00%)
651 picked tool 'python ../merge' for rev (binary False symlink False)
703 picked tool 'python ../merge' for rev (binary False symlink False)
652 merging rev
704 merging rev
653 my rev@0b76e65c8289+ other rev@bdb19105162a ancestor rev@924404dff337
705 my rev@0b76e65c8289+ other rev@bdb19105162a ancestor rev@924404dff337
706 launching merge tool: python ../merge $TESTTMP/t/t/rev * * (glob)
707 merge tool returned: 0
654 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
708 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
655 (branch merge, don't forget to commit)
709 (branch merge, don't forget to commit)
656 --------------
710 --------------
657 M b
711 M b
658 C a
712 C a
659 --------------
713 --------------
660
714
661 $ tm "up a " "um a b" " " "20 merge a and b to b, remove a"
715 $ tm "up a " "um a b" " " "20 merge a and b to b, remove a"
662 created new head
716 created new head
663 --------------
717 --------------
664 test L:up a R:um a b W: - 20 merge a and b to b, remove a
718 test L:up a R:um a b W: - 20 merge a and b to b, remove a
665 --------------
719 --------------
666 searching for copies back to rev 1
720 searching for copies back to rev 1
667 unmatched files in other:
721 unmatched files in other:
668 b
722 b
669 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
723 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
670 src: 'a' -> dst: 'b' *
724 src: 'a' -> dst: 'b' *
671 checking for directory renames
725 checking for directory renames
672 resolving manifests
726 resolving manifests
673 branchmerge: True, force: False, partial: False
727 branchmerge: True, force: False, partial: False
674 ancestor: 924404dff337, local: e300d1c794ec+, remote: 49b6d8032493
728 ancestor: 924404dff337, local: e300d1c794ec+, remote: 49b6d8032493
675 preserving a for resolve of b
729 preserving a for resolve of b
676 preserving rev for resolve of rev
730 preserving rev for resolve of rev
677 removing a
731 removing a
678 b: remote moved from a -> m
732 b: remote moved from a -> m
679 updating: b 1/2 files (50.00%)
733 updating: b 1/2 files (50.00%)
680 picked tool 'python ../merge' for b (binary False symlink False)
734 picked tool 'python ../merge' for b (binary False symlink False)
681 merging a and b to b
735 merging a and b to b
682 my b@e300d1c794ec+ other b@49b6d8032493 ancestor a@924404dff337
736 my b@e300d1c794ec+ other b@49b6d8032493 ancestor a@924404dff337
737 launching merge tool: python ../merge $TESTTMP/t/t/b * * (glob)
738 merge tool returned: 0
683 rev: versions differ -> m
739 rev: versions differ -> m
684 updating: rev 2/2 files (100.00%)
740 updating: rev 2/2 files (100.00%)
685 picked tool 'python ../merge' for rev (binary False symlink False)
741 picked tool 'python ../merge' for rev (binary False symlink False)
686 merging rev
742 merging rev
687 my rev@e300d1c794ec+ other rev@49b6d8032493 ancestor rev@924404dff337
743 my rev@e300d1c794ec+ other rev@49b6d8032493 ancestor rev@924404dff337
744 launching merge tool: python ../merge $TESTTMP/t/t/rev * * (glob)
745 merge tool returned: 0
688 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
746 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
689 (branch merge, don't forget to commit)
747 (branch merge, don't forget to commit)
690 --------------
748 --------------
691 M b
749 M b
692 a
750 a
693 --------------
751 --------------
694
752
695 $ tm "um a b" "up a " " " "21 merge a and b to b"
753 $ tm "um a b" "up a " " " "21 merge a and b to b"
696 created new head
754 created new head
697 --------------
755 --------------
698 test L:um a b R:up a W: - 21 merge a and b to b
756 test L:um a b R:up a W: - 21 merge a and b to b
699 --------------
757 --------------
700 searching for copies back to rev 1
758 searching for copies back to rev 1
701 unmatched files in local:
759 unmatched files in local:
702 b
760 b
703 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
761 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
704 src: 'a' -> dst: 'b' *
762 src: 'a' -> dst: 'b' *
705 checking for directory renames
763 checking for directory renames
706 resolving manifests
764 resolving manifests
707 branchmerge: True, force: False, partial: False
765 branchmerge: True, force: False, partial: False
708 ancestor: 924404dff337, local: 62e7bf090eba+, remote: f4db7e329e71
766 ancestor: 924404dff337, local: 62e7bf090eba+, remote: f4db7e329e71
709 preserving b for resolve of b
767 preserving b for resolve of b
710 preserving rev for resolve of rev
768 preserving rev for resolve of rev
711 b: local copied/moved from a -> m
769 b: local copied/moved from a -> m
712 updating: b 1/2 files (50.00%)
770 updating: b 1/2 files (50.00%)
713 picked tool 'python ../merge' for b (binary False symlink False)
771 picked tool 'python ../merge' for b (binary False symlink False)
714 merging b and a to b
772 merging b and a to b
715 my b@62e7bf090eba+ other a@f4db7e329e71 ancestor a@924404dff337
773 my b@62e7bf090eba+ other a@f4db7e329e71 ancestor a@924404dff337
774 launching merge tool: python ../merge $TESTTMP/t/t/b * * (glob)
775 merge tool returned: 0
716 rev: versions differ -> m
776 rev: versions differ -> m
717 updating: rev 2/2 files (100.00%)
777 updating: rev 2/2 files (100.00%)
718 picked tool 'python ../merge' for rev (binary False symlink False)
778 picked tool 'python ../merge' for rev (binary False symlink False)
719 merging rev
779 merging rev
720 my rev@62e7bf090eba+ other rev@f4db7e329e71 ancestor rev@924404dff337
780 my rev@62e7bf090eba+ other rev@f4db7e329e71 ancestor rev@924404dff337
781 launching merge tool: python ../merge $TESTTMP/t/t/rev * * (glob)
782 merge tool returned: 0
721 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
783 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
722 (branch merge, don't forget to commit)
784 (branch merge, don't forget to commit)
723 --------------
785 --------------
724 M b
786 M b
725 a
787 a
726 --------------
788 --------------
727
789
728
790
729 m "nm a b" "um x a" " " "22 get a, keep b"
791 m "nm a b" "um x a" " " "22 get a, keep b"
730
792
731 $ tm "nm a b" "up a c" " " "23 get c, keep b"
793 $ tm "nm a b" "up a c" " " "23 get c, keep b"
732 created new head
794 created new head
733 --------------
795 --------------
734 test L:nm a b R:up a c W: - 23 get c, keep b
796 test L:nm a b R:up a c W: - 23 get c, keep b
735 --------------
797 --------------
736 searching for copies back to rev 1
798 searching for copies back to rev 1
737 unmatched files in local:
799 unmatched files in local:
738 b
800 b
739 unmatched files in other:
801 unmatched files in other:
740 c
802 c
741 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
803 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
742 src: 'a' -> dst: 'b' *
804 src: 'a' -> dst: 'b' *
743 checking for directory renames
805 checking for directory renames
744 resolving manifests
806 resolving manifests
745 branchmerge: True, force: False, partial: False
807 branchmerge: True, force: False, partial: False
746 ancestor: 924404dff337, local: 02963e448370+, remote: 2b958612230f
808 ancestor: 924404dff337, local: 02963e448370+, remote: 2b958612230f
747 preserving b for resolve of b
809 preserving b for resolve of b
748 preserving rev for resolve of rev
810 preserving rev for resolve of rev
749 c: remote created -> g
811 c: remote created -> g
750 getting c
812 getting c
751 updating: c 1/3 files (33.33%)
813 updating: c 1/3 files (33.33%)
752 b: local copied/moved from a -> m
814 b: local copied/moved from a -> m
753 updating: b 2/3 files (66.67%)
815 updating: b 2/3 files (66.67%)
754 picked tool 'python ../merge' for b (binary False symlink False)
816 picked tool 'python ../merge' for b (binary False symlink False)
755 merging b and a to b
817 merging b and a to b
756 my b@02963e448370+ other a@2b958612230f ancestor a@924404dff337
818 my b@02963e448370+ other a@2b958612230f ancestor a@924404dff337
757 premerge successful
819 premerge successful
758 rev: versions differ -> m
820 rev: versions differ -> m
759 updating: rev 3/3 files (100.00%)
821 updating: rev 3/3 files (100.00%)
760 picked tool 'python ../merge' for rev (binary False symlink False)
822 picked tool 'python ../merge' for rev (binary False symlink False)
761 merging rev
823 merging rev
762 my rev@02963e448370+ other rev@2b958612230f ancestor rev@924404dff337
824 my rev@02963e448370+ other rev@2b958612230f ancestor rev@924404dff337
825 launching merge tool: python ../merge $TESTTMP/t/t/rev * * (glob)
826 merge tool returned: 0
763 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
827 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
764 (branch merge, don't forget to commit)
828 (branch merge, don't forget to commit)
765 --------------
829 --------------
766 M b
830 M b
767 a
831 a
768 M c
832 M c
769 --------------
833 --------------
770
834
771
835
772 $ cd ..
836 $ cd ..
773
837
774
838
775 Systematic and terse testing of merge merges and ancestor calculation:
839 Systematic and terse testing of merge merges and ancestor calculation:
776
840
777 Expected result:
841 Expected result:
778
842
779 \ a m1 m2 dst
843 \ a m1 m2 dst
780 0 - f f f "versions differ"
844 0 - f f f "versions differ"
781 1 f g g g "versions differ"
845 1 f g g g "versions differ"
782 2 f f f f "versions differ"
846 2 f f f f "versions differ"
783 3 f f g f+g "remote copied to " + f
847 3 f f g f+g "remote copied to " + f
784 4 f f g g "remote moved to " + f
848 4 f f g g "remote moved to " + f
785 5 f g f f+g "local copied to " + f2
849 5 f g f f+g "local copied to " + f2
786 6 f g f g "local moved to " + f2
850 6 f g f g "local moved to " + f2
787 7 - (f) f f "remote differs from untracked local"
851 7 - (f) f f "remote differs from untracked local"
788 8 f (f) f f "remote differs from untracked local"
852 8 f (f) f f "remote differs from untracked local"
789
853
790 $ hg init ancestortest
854 $ hg init ancestortest
791 $ cd ancestortest
855 $ cd ancestortest
792 $ for x in 1 2 3 4 5 6 8; do mkdir $x; echo a > $x/f; done
856 $ for x in 1 2 3 4 5 6 8; do mkdir $x; echo a > $x/f; done
793 $ hg ci -Aqm "a"
857 $ hg ci -Aqm "a"
794 $ mkdir 0
858 $ mkdir 0
795 $ touch 0/f
859 $ touch 0/f
796 $ hg mv 1/f 1/g
860 $ hg mv 1/f 1/g
797 $ hg cp 5/f 5/g
861 $ hg cp 5/f 5/g
798 $ hg mv 6/f 6/g
862 $ hg mv 6/f 6/g
799 $ hg rm 8/f
863 $ hg rm 8/f
800 $ for x in */*; do echo m1 > $x; done
864 $ for x in */*; do echo m1 > $x; done
801 $ hg ci -Aqm "m1"
865 $ hg ci -Aqm "m1"
802 $ hg up -qr0
866 $ hg up -qr0
803 $ mkdir 0 7
867 $ mkdir 0 7
804 $ touch 0/f 7/f
868 $ touch 0/f 7/f
805 $ hg mv 1/f 1/g
869 $ hg mv 1/f 1/g
806 $ hg cp 3/f 3/g
870 $ hg cp 3/f 3/g
807 $ hg mv 4/f 4/g
871 $ hg mv 4/f 4/g
808 $ for x in */*; do echo m2 > $x; done
872 $ for x in */*; do echo m2 > $x; done
809 $ hg ci -Aqm "m2"
873 $ hg ci -Aqm "m2"
810 $ hg up -qr1
874 $ hg up -qr1
811 $ mkdir 7 8
875 $ mkdir 7 8
812 $ echo m > 7/f
876 $ echo m > 7/f
813 $ echo m > 8/f
877 $ echo m > 8/f
814 $ hg merge -f --tool internal:dump -v --debug -r2 | sed '/^updating:/,$d' 2> /dev/null
878 $ hg merge -f --tool internal:dump -v --debug -r2 | sed '/^updating:/,$d' 2> /dev/null
815 searching for copies back to rev 1
879 searching for copies back to rev 1
816 unmatched files in local:
880 unmatched files in local:
817 5/g
881 5/g
818 6/g
882 6/g
819 unmatched files in other:
883 unmatched files in other:
820 3/g
884 3/g
821 4/g
885 4/g
822 7/f
886 7/f
823 unmatched files new in both:
887 unmatched files new in both:
824 0/f
888 0/f
825 1/g
889 1/g
826 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
890 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
827 src: '3/f' -> dst: '3/g' *
891 src: '3/f' -> dst: '3/g' *
828 src: '4/f' -> dst: '4/g' *
892 src: '4/f' -> dst: '4/g' *
829 src: '5/f' -> dst: '5/g' *
893 src: '5/f' -> dst: '5/g' *
830 src: '6/f' -> dst: '6/g' *
894 src: '6/f' -> dst: '6/g' *
831 checking for directory renames
895 checking for directory renames
832 resolving manifests
896 resolving manifests
833 branchmerge: True, force: True, partial: False
897 branchmerge: True, force: True, partial: False
834 ancestor: e6cb3cf11019, local: ec44bf929ab5+, remote: c62e34d0b898
898 ancestor: e6cb3cf11019, local: ec44bf929ab5+, remote: c62e34d0b898
835 remote changed 8/f which local deleted
899 remote changed 8/f which local deleted
836 use (c)hanged version or leave (d)eleted? c
900 use (c)hanged version or leave (d)eleted? c
837 preserving 0/f for resolve of 0/f
901 preserving 0/f for resolve of 0/f
838 preserving 1/g for resolve of 1/g
902 preserving 1/g for resolve of 1/g
839 preserving 2/f for resolve of 2/f
903 preserving 2/f for resolve of 2/f
840 preserving 3/f for resolve of 3/f
904 preserving 3/f for resolve of 3/f
841 preserving 3/f for resolve of 3/g
905 preserving 3/f for resolve of 3/g
842 preserving 4/f for resolve of 4/g
906 preserving 4/f for resolve of 4/g
843 preserving 5/f for resolve of 5/f
907 preserving 5/f for resolve of 5/f
844 preserving 5/g for resolve of 5/g
908 preserving 5/g for resolve of 5/g
845 preserving 6/g for resolve of 6/g
909 preserving 6/g for resolve of 6/g
846 preserving 7/f for resolve of 7/f
910 preserving 7/f for resolve of 7/f
847 removing 4/f
911 removing 4/f
848 8/f: prompt recreating -> g
912 8/f: prompt recreating -> g
849 getting 8/f
913 getting 8/f
850 $ hg mani
914 $ hg mani
851 0/f
915 0/f
852 1/g
916 1/g
853 2/f
917 2/f
854 3/f
918 3/f
855 4/f
919 4/f
856 5/f
920 5/f
857 5/g
921 5/g
858 6/g
922 6/g
859 $ for f in */*; do echo $f:; cat $f; done
923 $ for f in */*; do echo $f:; cat $f; done
860 0/f:
924 0/f:
861 m1
925 m1
862 0/f.base:
926 0/f.base:
863 0/f.local:
927 0/f.local:
864 m1
928 m1
865 0/f.orig:
929 0/f.orig:
866 m1
930 m1
867 0/f.other:
931 0/f.other:
868 m2
932 m2
869 1/g:
933 1/g:
870 m1
934 m1
871 1/g.base:
935 1/g.base:
872 a
936 a
873 1/g.local:
937 1/g.local:
874 m1
938 m1
875 1/g.orig:
939 1/g.orig:
876 m1
940 m1
877 1/g.other:
941 1/g.other:
878 m2
942 m2
879 2/f:
943 2/f:
880 m1
944 m1
881 2/f.base:
945 2/f.base:
882 a
946 a
883 2/f.local:
947 2/f.local:
884 m1
948 m1
885 2/f.orig:
949 2/f.orig:
886 m1
950 m1
887 2/f.other:
951 2/f.other:
888 m2
952 m2
889 3/f:
953 3/f:
890 m1
954 m1
891 3/f.base:
955 3/f.base:
892 a
956 a
893 3/f.local:
957 3/f.local:
894 m1
958 m1
895 3/f.orig:
959 3/f.orig:
896 m1
960 m1
897 3/f.other:
961 3/f.other:
898 m2
962 m2
899 3/g:
963 3/g:
900 m1
964 m1
901 3/g.base:
965 3/g.base:
902 a
966 a
903 3/g.local:
967 3/g.local:
904 m1
968 m1
905 3/g.orig:
969 3/g.orig:
906 m1
970 m1
907 3/g.other:
971 3/g.other:
908 m2
972 m2
909 4/g:
973 4/g:
910 m1
974 m1
911 4/g.base:
975 4/g.base:
912 a
976 a
913 4/g.local:
977 4/g.local:
914 m1
978 m1
915 4/g.orig:
979 4/g.orig:
916 m1
980 m1
917 4/g.other:
981 4/g.other:
918 m2
982 m2
919 5/f:
983 5/f:
920 m1
984 m1
921 5/f.base:
985 5/f.base:
922 a
986 a
923 5/f.local:
987 5/f.local:
924 m1
988 m1
925 5/f.orig:
989 5/f.orig:
926 m1
990 m1
927 5/f.other:
991 5/f.other:
928 m2
992 m2
929 5/g:
993 5/g:
930 m1
994 m1
931 5/g.base:
995 5/g.base:
932 a
996 a
933 5/g.local:
997 5/g.local:
934 m1
998 m1
935 5/g.orig:
999 5/g.orig:
936 m1
1000 m1
937 5/g.other:
1001 5/g.other:
938 m2
1002 m2
939 6/g:
1003 6/g:
940 m1
1004 m1
941 6/g.base:
1005 6/g.base:
942 a
1006 a
943 6/g.local:
1007 6/g.local:
944 m1
1008 m1
945 6/g.orig:
1009 6/g.orig:
946 m1
1010 m1
947 6/g.other:
1011 6/g.other:
948 m2
1012 m2
949 7/f:
1013 7/f:
950 m
1014 m
951 7/f.base:
1015 7/f.base:
952 7/f.local:
1016 7/f.local:
953 m
1017 m
954 7/f.orig:
1018 7/f.orig:
955 m
1019 m
956 7/f.other:
1020 7/f.other:
957 m2
1021 m2
958 8/f:
1022 8/f:
959 m2
1023 m2
960 $ cd ..
1024 $ cd ..
@@ -1,222 +1,228
1 $ HGMERGE=true; export HGMERGE
1 $ HGMERGE=true; export HGMERGE
2
2
3 $ hg init r1
3 $ hg init r1
4 $ cd r1
4 $ cd r1
5 $ echo a > a
5 $ echo a > a
6 $ hg addremove
6 $ hg addremove
7 adding a
7 adding a
8 $ hg commit -m "1"
8 $ hg commit -m "1"
9
9
10 $ hg clone . ../r2
10 $ hg clone . ../r2
11 updating to branch default
11 updating to branch default
12 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
12 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
13 $ cd ../r2
13 $ cd ../r2
14 $ hg up
14 $ hg up
15 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
15 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
16 $ echo abc > a
16 $ echo abc > a
17 $ hg diff --nodates
17 $ hg diff --nodates
18 diff -r c19d34741b0a a
18 diff -r c19d34741b0a a
19 --- a/a
19 --- a/a
20 +++ b/a
20 +++ b/a
21 @@ -1,1 +1,1 @@
21 @@ -1,1 +1,1 @@
22 -a
22 -a
23 +abc
23 +abc
24
24
25 $ cd ../r1
25 $ cd ../r1
26 $ echo b > b
26 $ echo b > b
27 $ echo a2 > a
27 $ echo a2 > a
28 $ hg addremove
28 $ hg addremove
29 adding b
29 adding b
30 $ hg commit -m "2"
30 $ hg commit -m "2"
31
31
32 $ cd ../r2
32 $ cd ../r2
33 $ hg -q pull ../r1
33 $ hg -q pull ../r1
34 $ hg status
34 $ hg status
35 M a
35 M a
36 $ hg parents
36 $ hg parents
37 changeset: 0:c19d34741b0a
37 changeset: 0:c19d34741b0a
38 user: test
38 user: test
39 date: Thu Jan 01 00:00:00 1970 +0000
39 date: Thu Jan 01 00:00:00 1970 +0000
40 summary: 1
40 summary: 1
41
41
42 $ hg --debug up
42 $ hg --debug up
43 searching for copies back to rev 1
43 searching for copies back to rev 1
44 unmatched files in other:
44 unmatched files in other:
45 b
45 b
46 resolving manifests
46 resolving manifests
47 branchmerge: False, force: False, partial: False
47 branchmerge: False, force: False, partial: False
48 ancestor: c19d34741b0a, local: c19d34741b0a+, remote: 1e71731e6fbb
48 ancestor: c19d34741b0a, local: c19d34741b0a+, remote: 1e71731e6fbb
49 preserving a for resolve of a
49 preserving a for resolve of a
50 b: remote created -> g
50 b: remote created -> g
51 getting b
51 getting b
52 updating: b 1/2 files (50.00%)
52 updating: b 1/2 files (50.00%)
53 a: versions differ -> m
53 a: versions differ -> m
54 updating: a 2/2 files (100.00%)
54 updating: a 2/2 files (100.00%)
55 picked tool 'true' for a (binary False symlink False)
55 picked tool 'true' for a (binary False symlink False)
56 merging a
56 merging a
57 my a@c19d34741b0a+ other a@1e71731e6fbb ancestor a@c19d34741b0a
57 my a@c19d34741b0a+ other a@1e71731e6fbb ancestor a@c19d34741b0a
58 launching merge tool: true $TESTTMP/r2/a * (glob)
59 merge tool returned: 0
58 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
60 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
59 $ hg parents
61 $ hg parents
60 changeset: 1:1e71731e6fbb
62 changeset: 1:1e71731e6fbb
61 tag: tip
63 tag: tip
62 user: test
64 user: test
63 date: Thu Jan 01 00:00:00 1970 +0000
65 date: Thu Jan 01 00:00:00 1970 +0000
64 summary: 2
66 summary: 2
65
67
66 $ hg --debug up 0
68 $ hg --debug up 0
67 resolving manifests
69 resolving manifests
68 branchmerge: False, force: False, partial: False
70 branchmerge: False, force: False, partial: False
69 ancestor: 1e71731e6fbb, local: 1e71731e6fbb+, remote: c19d34741b0a
71 ancestor: 1e71731e6fbb, local: 1e71731e6fbb+, remote: c19d34741b0a
70 preserving a for resolve of a
72 preserving a for resolve of a
71 b: other deleted -> r
73 b: other deleted -> r
72 removing b
74 removing b
73 updating: b 1/2 files (50.00%)
75 updating: b 1/2 files (50.00%)
74 a: versions differ -> m
76 a: versions differ -> m
75 updating: a 2/2 files (100.00%)
77 updating: a 2/2 files (100.00%)
76 picked tool 'true' for a (binary False symlink False)
78 picked tool 'true' for a (binary False symlink False)
77 merging a
79 merging a
78 my a@1e71731e6fbb+ other a@c19d34741b0a ancestor a@1e71731e6fbb
80 my a@1e71731e6fbb+ other a@c19d34741b0a ancestor a@1e71731e6fbb
81 launching merge tool: true $TESTTMP/r2/a * (glob)
82 merge tool returned: 0
79 0 files updated, 1 files merged, 1 files removed, 0 files unresolved
83 0 files updated, 1 files merged, 1 files removed, 0 files unresolved
80 $ hg parents
84 $ hg parents
81 changeset: 0:c19d34741b0a
85 changeset: 0:c19d34741b0a
82 user: test
86 user: test
83 date: Thu Jan 01 00:00:00 1970 +0000
87 date: Thu Jan 01 00:00:00 1970 +0000
84 summary: 1
88 summary: 1
85
89
86 $ hg parents
90 $ hg parents
87 changeset: 0:c19d34741b0a
91 changeset: 0:c19d34741b0a
88 user: test
92 user: test
89 date: Thu Jan 01 00:00:00 1970 +0000
93 date: Thu Jan 01 00:00:00 1970 +0000
90 summary: 1
94 summary: 1
91
95
92 $ hg --debug up
96 $ hg --debug up
93 searching for copies back to rev 1
97 searching for copies back to rev 1
94 unmatched files in other:
98 unmatched files in other:
95 b
99 b
96 resolving manifests
100 resolving manifests
97 branchmerge: False, force: False, partial: False
101 branchmerge: False, force: False, partial: False
98 ancestor: c19d34741b0a, local: c19d34741b0a+, remote: 1e71731e6fbb
102 ancestor: c19d34741b0a, local: c19d34741b0a+, remote: 1e71731e6fbb
99 preserving a for resolve of a
103 preserving a for resolve of a
100 b: remote created -> g
104 b: remote created -> g
101 getting b
105 getting b
102 updating: b 1/2 files (50.00%)
106 updating: b 1/2 files (50.00%)
103 a: versions differ -> m
107 a: versions differ -> m
104 updating: a 2/2 files (100.00%)
108 updating: a 2/2 files (100.00%)
105 picked tool 'true' for a (binary False symlink False)
109 picked tool 'true' for a (binary False symlink False)
106 merging a
110 merging a
107 my a@c19d34741b0a+ other a@1e71731e6fbb ancestor a@c19d34741b0a
111 my a@c19d34741b0a+ other a@1e71731e6fbb ancestor a@c19d34741b0a
112 launching merge tool: true $TESTTMP/r2/a * (glob)
113 merge tool returned: 0
108 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
114 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
109 $ hg parents
115 $ hg parents
110 changeset: 1:1e71731e6fbb
116 changeset: 1:1e71731e6fbb
111 tag: tip
117 tag: tip
112 user: test
118 user: test
113 date: Thu Jan 01 00:00:00 1970 +0000
119 date: Thu Jan 01 00:00:00 1970 +0000
114 summary: 2
120 summary: 2
115
121
116 $ hg -v history
122 $ hg -v history
117 changeset: 1:1e71731e6fbb
123 changeset: 1:1e71731e6fbb
118 tag: tip
124 tag: tip
119 user: test
125 user: test
120 date: Thu Jan 01 00:00:00 1970 +0000
126 date: Thu Jan 01 00:00:00 1970 +0000
121 files: a b
127 files: a b
122 description:
128 description:
123 2
129 2
124
130
125
131
126 changeset: 0:c19d34741b0a
132 changeset: 0:c19d34741b0a
127 user: test
133 user: test
128 date: Thu Jan 01 00:00:00 1970 +0000
134 date: Thu Jan 01 00:00:00 1970 +0000
129 files: a
135 files: a
130 description:
136 description:
131 1
137 1
132
138
133
139
134 $ hg diff --nodates
140 $ hg diff --nodates
135 diff -r 1e71731e6fbb a
141 diff -r 1e71731e6fbb a
136 --- a/a
142 --- a/a
137 +++ b/a
143 +++ b/a
138 @@ -1,1 +1,1 @@
144 @@ -1,1 +1,1 @@
139 -a2
145 -a2
140 +abc
146 +abc
141
147
142
148
143 create a second head
149 create a second head
144
150
145 $ cd ../r1
151 $ cd ../r1
146 $ hg up 0
152 $ hg up 0
147 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
153 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
148 $ echo b2 > b
154 $ echo b2 > b
149 $ echo a3 > a
155 $ echo a3 > a
150 $ hg addremove
156 $ hg addremove
151 adding b
157 adding b
152 $ hg commit -m "3"
158 $ hg commit -m "3"
153 created new head
159 created new head
154
160
155 $ cd ../r2
161 $ cd ../r2
156 $ hg -q pull ../r1
162 $ hg -q pull ../r1
157 $ hg status
163 $ hg status
158 M a
164 M a
159 $ hg parents
165 $ hg parents
160 changeset: 1:1e71731e6fbb
166 changeset: 1:1e71731e6fbb
161 user: test
167 user: test
162 date: Thu Jan 01 00:00:00 1970 +0000
168 date: Thu Jan 01 00:00:00 1970 +0000
163 summary: 2
169 summary: 2
164
170
165 $ hg --debug up
171 $ hg --debug up
166 abort: uncommitted changes
172 abort: uncommitted changes
167 (commit and merge, or update --clean to discard changes)
173 (commit and merge, or update --clean to discard changes)
168 [255]
174 [255]
169
175
170 test conflicting untracked files
176 test conflicting untracked files
171
177
172 $ hg up -qC 0
178 $ hg up -qC 0
173 $ echo untracked > b
179 $ echo untracked > b
174 $ hg st
180 $ hg st
175 ? b
181 ? b
176 $ hg up 1
182 $ hg up 1
177 b: untracked file differs
183 b: untracked file differs
178 abort: untracked files in working directory differ from files in requested revision
184 abort: untracked files in working directory differ from files in requested revision
179 [255]
185 [255]
180 $ rm b
186 $ rm b
181
187
182 test conflicting untracked ignored file
188 test conflicting untracked ignored file
183
189
184 $ hg up -qC 0
190 $ hg up -qC 0
185 $ echo ignored > .hgignore
191 $ echo ignored > .hgignore
186 $ hg add .hgignore
192 $ hg add .hgignore
187 $ hg ci -m 'add .hgignore'
193 $ hg ci -m 'add .hgignore'
188 created new head
194 created new head
189 $ echo ignored > ignored
195 $ echo ignored > ignored
190 $ hg add ignored
196 $ hg add ignored
191 $ hg ci -m 'add ignored file'
197 $ hg ci -m 'add ignored file'
192
198
193 $ hg up -q 'desc("add .hgignore")'
199 $ hg up -q 'desc("add .hgignore")'
194 $ echo untracked > ignored
200 $ echo untracked > ignored
195 $ hg st
201 $ hg st
196 $ hg up 'desc("add ignored file")'
202 $ hg up 'desc("add ignored file")'
197 ignored: untracked file differs
203 ignored: untracked file differs
198 abort: untracked files in working directory differ from files in requested revision
204 abort: untracked files in working directory differ from files in requested revision
199 [255]
205 [255]
200
206
201 test a local add
207 test a local add
202
208
203 $ cd ..
209 $ cd ..
204 $ hg init a
210 $ hg init a
205 $ hg init b
211 $ hg init b
206 $ echo a > a/a
212 $ echo a > a/a
207 $ echo a > b/a
213 $ echo a > b/a
208 $ hg --cwd a commit -A -m a
214 $ hg --cwd a commit -A -m a
209 adding a
215 adding a
210 $ cd b
216 $ cd b
211 $ hg add a
217 $ hg add a
212 $ hg pull -u ../a
218 $ hg pull -u ../a
213 pulling from ../a
219 pulling from ../a
214 requesting all changes
220 requesting all changes
215 adding changesets
221 adding changesets
216 adding manifests
222 adding manifests
217 adding file changes
223 adding file changes
218 added 1 changesets with 1 changes to 1 files
224 added 1 changesets with 1 changes to 1 files
219 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
225 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
220 $ hg st
226 $ hg st
221
227
222 $ cd ..
228 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now