##// END OF EJS Templates
ui: log non-interactive default response to stdout when verbose...
Peter Arrenbrecht -
r7320:8dca507e default
parent child Browse files
Show More
@@ -1,484 +1,486 b''
1 # ui.py - user interface bits for mercurial
1 # ui.py - user interface bits for mercurial
2 #
2 #
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
4 #
4 #
5 # This software may be used and distributed according to the terms
5 # This software may be used and distributed according to the terms
6 # of the GNU General Public License, incorporated herein by reference.
6 # of the GNU General Public License, incorporated herein by reference.
7
7
8 from i18n import _
8 from i18n import _
9 import errno, getpass, os, re, socket, sys, tempfile
9 import errno, getpass, os, re, socket, sys, tempfile
10 import ConfigParser, traceback, util
10 import ConfigParser, traceback, util
11
11
12 def dupconfig(orig):
12 def dupconfig(orig):
13 new = util.configparser(orig.defaults())
13 new = util.configparser(orig.defaults())
14 updateconfig(orig, new)
14 updateconfig(orig, new)
15 return new
15 return new
16
16
17 def updateconfig(source, dest, sections=None):
17 def updateconfig(source, dest, sections=None):
18 if not sections:
18 if not sections:
19 sections = source.sections()
19 sections = source.sections()
20 for section in sections:
20 for section in sections:
21 if not dest.has_section(section):
21 if not dest.has_section(section):
22 dest.add_section(section)
22 dest.add_section(section)
23 for name, value in source.items(section, raw=True):
23 for name, value in source.items(section, raw=True):
24 dest.set(section, name, value)
24 dest.set(section, name, value)
25
25
26 class ui(object):
26 class ui(object):
27 _isatty = None
27 _isatty = None
28
28
29 def __init__(self, verbose=False, debug=False, quiet=False,
29 def __init__(self, verbose=False, debug=False, quiet=False,
30 interactive=True, traceback=False, report_untrusted=True,
30 interactive=True, traceback=False, report_untrusted=True,
31 parentui=None):
31 parentui=None):
32 self.overlay = None
32 self.overlay = None
33 self.buffers = []
33 self.buffers = []
34 if parentui is None:
34 if parentui is None:
35 # this is the parent of all ui children
35 # this is the parent of all ui children
36 self.parentui = None
36 self.parentui = None
37 self.quiet = quiet
37 self.quiet = quiet
38 self.verbose = verbose
38 self.verbose = verbose
39 self.debugflag = debug
39 self.debugflag = debug
40 self.interactive = interactive
40 self.interactive = interactive
41 self.traceback = traceback
41 self.traceback = traceback
42 self.report_untrusted = report_untrusted
42 self.report_untrusted = report_untrusted
43 self.trusted_users = {}
43 self.trusted_users = {}
44 self.trusted_groups = {}
44 self.trusted_groups = {}
45 # if ucdata is not None, its keys must be a superset of cdata's
45 # if ucdata is not None, its keys must be a superset of cdata's
46 self.cdata = util.configparser()
46 self.cdata = util.configparser()
47 self.ucdata = None
47 self.ucdata = None
48 # we always trust global config files
48 # we always trust global config files
49 self.check_trusted = False
49 self.check_trusted = False
50 self.readconfig(util.rcpath())
50 self.readconfig(util.rcpath())
51 self.check_trusted = True
51 self.check_trusted = True
52 self.updateopts(verbose, debug, quiet, interactive)
52 self.updateopts(verbose, debug, quiet, interactive)
53 else:
53 else:
54 # parentui may point to an ui object which is already a child
54 # parentui may point to an ui object which is already a child
55 self.parentui = parentui.parentui or parentui
55 self.parentui = parentui.parentui or parentui
56 self.trusted_users = parentui.trusted_users.copy()
56 self.trusted_users = parentui.trusted_users.copy()
57 self.trusted_groups = parentui.trusted_groups.copy()
57 self.trusted_groups = parentui.trusted_groups.copy()
58 self.cdata = dupconfig(self.parentui.cdata)
58 self.cdata = dupconfig(self.parentui.cdata)
59 if self.parentui.ucdata:
59 if self.parentui.ucdata:
60 self.ucdata = dupconfig(self.parentui.ucdata)
60 self.ucdata = dupconfig(self.parentui.ucdata)
61 if self.parentui.overlay:
61 if self.parentui.overlay:
62 self.overlay = dupconfig(self.parentui.overlay)
62 self.overlay = dupconfig(self.parentui.overlay)
63 if self.parentui is not parentui and parentui.overlay is not None:
63 if self.parentui is not parentui and parentui.overlay is not None:
64 if self.overlay is None:
64 if self.overlay is None:
65 self.overlay = util.configparser()
65 self.overlay = util.configparser()
66 updateconfig(parentui.overlay, self.overlay)
66 updateconfig(parentui.overlay, self.overlay)
67 self.buffers = parentui.buffers
67 self.buffers = parentui.buffers
68
68
69 def __getattr__(self, key):
69 def __getattr__(self, key):
70 return getattr(self.parentui, key)
70 return getattr(self.parentui, key)
71
71
72 def isatty(self):
72 def isatty(self):
73 if ui._isatty is None:
73 if ui._isatty is None:
74 ui._isatty = sys.stdin.isatty()
74 ui._isatty = sys.stdin.isatty()
75 return ui._isatty
75 return ui._isatty
76
76
77 def updateopts(self, verbose=False, debug=False, quiet=False,
77 def updateopts(self, verbose=False, debug=False, quiet=False,
78 interactive=True, traceback=False, config=[]):
78 interactive=True, traceback=False, config=[]):
79 for section, name, value in config:
79 for section, name, value in config:
80 self.setconfig(section, name, value)
80 self.setconfig(section, name, value)
81
81
82 if quiet or verbose or debug:
82 if quiet or verbose or debug:
83 self.setconfig('ui', 'quiet', str(bool(quiet)))
83 self.setconfig('ui', 'quiet', str(bool(quiet)))
84 self.setconfig('ui', 'verbose', str(bool(verbose)))
84 self.setconfig('ui', 'verbose', str(bool(verbose)))
85 self.setconfig('ui', 'debug', str(bool(debug)))
85 self.setconfig('ui', 'debug', str(bool(debug)))
86
86
87 self.verbosity_constraints()
87 self.verbosity_constraints()
88
88
89 if not interactive:
89 if not interactive:
90 self.setconfig('ui', 'interactive', 'False')
90 self.setconfig('ui', 'interactive', 'False')
91 self.interactive = False
91 self.interactive = False
92
92
93 self.traceback = self.traceback or traceback
93 self.traceback = self.traceback or traceback
94
94
95 def verbosity_constraints(self):
95 def verbosity_constraints(self):
96 self.quiet = self.configbool('ui', 'quiet')
96 self.quiet = self.configbool('ui', 'quiet')
97 self.verbose = self.configbool('ui', 'verbose')
97 self.verbose = self.configbool('ui', 'verbose')
98 self.debugflag = self.configbool('ui', 'debug')
98 self.debugflag = self.configbool('ui', 'debug')
99
99
100 if self.debugflag:
100 if self.debugflag:
101 self.verbose = True
101 self.verbose = True
102 self.quiet = False
102 self.quiet = False
103 elif self.verbose and self.quiet:
103 elif self.verbose and self.quiet:
104 self.quiet = self.verbose = False
104 self.quiet = self.verbose = False
105
105
106 def _is_trusted(self, fp, f, warn=True):
106 def _is_trusted(self, fp, f, warn=True):
107 if not self.check_trusted:
107 if not self.check_trusted:
108 return True
108 return True
109 st = util.fstat(fp)
109 st = util.fstat(fp)
110 if util.isowner(fp, st):
110 if util.isowner(fp, st):
111 return True
111 return True
112 tusers = self.trusted_users
112 tusers = self.trusted_users
113 tgroups = self.trusted_groups
113 tgroups = self.trusted_groups
114 if not tusers:
114 if not tusers:
115 user = util.username()
115 user = util.username()
116 if user is not None:
116 if user is not None:
117 self.trusted_users[user] = 1
117 self.trusted_users[user] = 1
118 self.fixconfig(section='trusted')
118 self.fixconfig(section='trusted')
119 if (tusers or tgroups) and '*' not in tusers and '*' not in tgroups:
119 if (tusers or tgroups) and '*' not in tusers and '*' not in tgroups:
120 user = util.username(st.st_uid)
120 user = util.username(st.st_uid)
121 group = util.groupname(st.st_gid)
121 group = util.groupname(st.st_gid)
122 if user not in tusers and group not in tgroups:
122 if user not in tusers and group not in tgroups:
123 if warn and self.report_untrusted:
123 if warn and self.report_untrusted:
124 self.warn(_('Not trusting file %s from untrusted '
124 self.warn(_('Not trusting file %s from untrusted '
125 'user %s, group %s\n') % (f, user, group))
125 'user %s, group %s\n') % (f, user, group))
126 return False
126 return False
127 return True
127 return True
128
128
129 def readconfig(self, fn, root=None):
129 def readconfig(self, fn, root=None):
130 if isinstance(fn, basestring):
130 if isinstance(fn, basestring):
131 fn = [fn]
131 fn = [fn]
132 for f in fn:
132 for f in fn:
133 try:
133 try:
134 fp = open(f)
134 fp = open(f)
135 except IOError:
135 except IOError:
136 continue
136 continue
137 cdata = self.cdata
137 cdata = self.cdata
138 trusted = self._is_trusted(fp, f)
138 trusted = self._is_trusted(fp, f)
139 if not trusted:
139 if not trusted:
140 if self.ucdata is None:
140 if self.ucdata is None:
141 self.ucdata = dupconfig(self.cdata)
141 self.ucdata = dupconfig(self.cdata)
142 cdata = self.ucdata
142 cdata = self.ucdata
143 elif self.ucdata is not None:
143 elif self.ucdata is not None:
144 # use a separate configparser, so that we don't accidentally
144 # use a separate configparser, so that we don't accidentally
145 # override ucdata settings later on.
145 # override ucdata settings later on.
146 cdata = util.configparser()
146 cdata = util.configparser()
147
147
148 try:
148 try:
149 cdata.readfp(fp, f)
149 cdata.readfp(fp, f)
150 except ConfigParser.ParsingError, inst:
150 except ConfigParser.ParsingError, inst:
151 msg = _("Failed to parse %s\n%s") % (f, inst)
151 msg = _("Failed to parse %s\n%s") % (f, inst)
152 if trusted:
152 if trusted:
153 raise util.Abort(msg)
153 raise util.Abort(msg)
154 self.warn(_("Ignored: %s\n") % msg)
154 self.warn(_("Ignored: %s\n") % msg)
155
155
156 if trusted:
156 if trusted:
157 if cdata != self.cdata:
157 if cdata != self.cdata:
158 updateconfig(cdata, self.cdata)
158 updateconfig(cdata, self.cdata)
159 if self.ucdata is not None:
159 if self.ucdata is not None:
160 updateconfig(cdata, self.ucdata)
160 updateconfig(cdata, self.ucdata)
161 # override data from config files with data set with ui.setconfig
161 # override data from config files with data set with ui.setconfig
162 if self.overlay:
162 if self.overlay:
163 updateconfig(self.overlay, self.cdata)
163 updateconfig(self.overlay, self.cdata)
164 if root is None:
164 if root is None:
165 root = os.path.expanduser('~')
165 root = os.path.expanduser('~')
166 self.fixconfig(root=root)
166 self.fixconfig(root=root)
167
167
168 def readsections(self, filename, *sections):
168 def readsections(self, filename, *sections):
169 """Read filename and add only the specified sections to the config data
169 """Read filename and add only the specified sections to the config data
170
170
171 The settings are added to the trusted config data.
171 The settings are added to the trusted config data.
172 """
172 """
173 if not sections:
173 if not sections:
174 return
174 return
175
175
176 cdata = util.configparser()
176 cdata = util.configparser()
177 try:
177 try:
178 try:
178 try:
179 fp = open(filename)
179 fp = open(filename)
180 except IOError, inst:
180 except IOError, inst:
181 raise util.Abort(_("unable to open %s: %s") %
181 raise util.Abort(_("unable to open %s: %s") %
182 (filename, getattr(inst, "strerror", inst)))
182 (filename, getattr(inst, "strerror", inst)))
183 try:
183 try:
184 cdata.readfp(fp, filename)
184 cdata.readfp(fp, filename)
185 finally:
185 finally:
186 fp.close()
186 fp.close()
187 except ConfigParser.ParsingError, inst:
187 except ConfigParser.ParsingError, inst:
188 raise util.Abort(_("failed to parse %s\n%s") % (filename, inst))
188 raise util.Abort(_("failed to parse %s\n%s") % (filename, inst))
189
189
190 for section in sections:
190 for section in sections:
191 if not cdata.has_section(section):
191 if not cdata.has_section(section):
192 cdata.add_section(section)
192 cdata.add_section(section)
193
193
194 updateconfig(cdata, self.cdata, sections)
194 updateconfig(cdata, self.cdata, sections)
195 if self.ucdata:
195 if self.ucdata:
196 updateconfig(cdata, self.ucdata, sections)
196 updateconfig(cdata, self.ucdata, sections)
197
197
198 def fixconfig(self, section=None, name=None, value=None, root=None):
198 def fixconfig(self, section=None, name=None, value=None, root=None):
199 # translate paths relative to root (or home) into absolute paths
199 # translate paths relative to root (or home) into absolute paths
200 if section is None or section == 'paths':
200 if section is None or section == 'paths':
201 if root is None:
201 if root is None:
202 root = os.getcwd()
202 root = os.getcwd()
203 items = section and [(name, value)] or []
203 items = section and [(name, value)] or []
204 for cdata in self.cdata, self.ucdata, self.overlay:
204 for cdata in self.cdata, self.ucdata, self.overlay:
205 if not cdata: continue
205 if not cdata: continue
206 if not items and cdata.has_section('paths'):
206 if not items and cdata.has_section('paths'):
207 pathsitems = cdata.items('paths')
207 pathsitems = cdata.items('paths')
208 else:
208 else:
209 pathsitems = items
209 pathsitems = items
210 for n, path in pathsitems:
210 for n, path in pathsitems:
211 if path and "://" not in path and not os.path.isabs(path):
211 if path and "://" not in path and not os.path.isabs(path):
212 cdata.set("paths", n,
212 cdata.set("paths", n,
213 os.path.normpath(os.path.join(root, path)))
213 os.path.normpath(os.path.join(root, path)))
214
214
215 # update verbosity/interactive/report_untrusted settings
215 # update verbosity/interactive/report_untrusted settings
216 if section is None or section == 'ui':
216 if section is None or section == 'ui':
217 if name is None or name in ('quiet', 'verbose', 'debug'):
217 if name is None or name in ('quiet', 'verbose', 'debug'):
218 self.verbosity_constraints()
218 self.verbosity_constraints()
219 if name is None or name == 'interactive':
219 if name is None or name == 'interactive':
220 interactive = self.configbool("ui", "interactive", None)
220 interactive = self.configbool("ui", "interactive", None)
221 if interactive is None and self.interactive:
221 if interactive is None and self.interactive:
222 self.interactive = self.isatty()
222 self.interactive = self.isatty()
223 else:
223 else:
224 self.interactive = interactive
224 self.interactive = interactive
225 if name is None or name == 'report_untrusted':
225 if name is None or name == 'report_untrusted':
226 self.report_untrusted = (
226 self.report_untrusted = (
227 self.configbool("ui", "report_untrusted", True))
227 self.configbool("ui", "report_untrusted", True))
228
228
229 # update trust information
229 # update trust information
230 if (section is None or section == 'trusted') and self.trusted_users:
230 if (section is None or section == 'trusted') and self.trusted_users:
231 for user in self.configlist('trusted', 'users'):
231 for user in self.configlist('trusted', 'users'):
232 self.trusted_users[user] = 1
232 self.trusted_users[user] = 1
233 for group in self.configlist('trusted', 'groups'):
233 for group in self.configlist('trusted', 'groups'):
234 self.trusted_groups[group] = 1
234 self.trusted_groups[group] = 1
235
235
236 def setconfig(self, section, name, value):
236 def setconfig(self, section, name, value):
237 if not self.overlay:
237 if not self.overlay:
238 self.overlay = util.configparser()
238 self.overlay = util.configparser()
239 for cdata in (self.overlay, self.cdata, self.ucdata):
239 for cdata in (self.overlay, self.cdata, self.ucdata):
240 if not cdata: continue
240 if not cdata: continue
241 if not cdata.has_section(section):
241 if not cdata.has_section(section):
242 cdata.add_section(section)
242 cdata.add_section(section)
243 cdata.set(section, name, value)
243 cdata.set(section, name, value)
244 self.fixconfig(section, name, value)
244 self.fixconfig(section, name, value)
245
245
246 def _get_cdata(self, untrusted):
246 def _get_cdata(self, untrusted):
247 if untrusted and self.ucdata:
247 if untrusted and self.ucdata:
248 return self.ucdata
248 return self.ucdata
249 return self.cdata
249 return self.cdata
250
250
251 def _config(self, section, name, default, funcname, untrusted, abort):
251 def _config(self, section, name, default, funcname, untrusted, abort):
252 cdata = self._get_cdata(untrusted)
252 cdata = self._get_cdata(untrusted)
253 if cdata.has_option(section, name):
253 if cdata.has_option(section, name):
254 try:
254 try:
255 func = getattr(cdata, funcname)
255 func = getattr(cdata, funcname)
256 return func(section, name)
256 return func(section, name)
257 except (ConfigParser.InterpolationError, ValueError), inst:
257 except (ConfigParser.InterpolationError, ValueError), inst:
258 msg = _("Error in configuration section [%s] "
258 msg = _("Error in configuration section [%s] "
259 "parameter '%s':\n%s") % (section, name, inst)
259 "parameter '%s':\n%s") % (section, name, inst)
260 if abort:
260 if abort:
261 raise util.Abort(msg)
261 raise util.Abort(msg)
262 self.warn(_("Ignored: %s\n") % msg)
262 self.warn(_("Ignored: %s\n") % msg)
263 return default
263 return default
264
264
265 def _configcommon(self, section, name, default, funcname, untrusted):
265 def _configcommon(self, section, name, default, funcname, untrusted):
266 value = self._config(section, name, default, funcname,
266 value = self._config(section, name, default, funcname,
267 untrusted, abort=True)
267 untrusted, abort=True)
268 if self.debugflag and not untrusted and self.ucdata:
268 if self.debugflag and not untrusted and self.ucdata:
269 uvalue = self._config(section, name, None, funcname,
269 uvalue = self._config(section, name, None, funcname,
270 untrusted=True, abort=False)
270 untrusted=True, abort=False)
271 if uvalue is not None and uvalue != value:
271 if uvalue is not None and uvalue != value:
272 self.warn(_("Ignoring untrusted configuration option "
272 self.warn(_("Ignoring untrusted configuration option "
273 "%s.%s = %s\n") % (section, name, uvalue))
273 "%s.%s = %s\n") % (section, name, uvalue))
274 return value
274 return value
275
275
276 def config(self, section, name, default=None, untrusted=False):
276 def config(self, section, name, default=None, untrusted=False):
277 return self._configcommon(section, name, default, 'get', untrusted)
277 return self._configcommon(section, name, default, 'get', untrusted)
278
278
279 def configbool(self, section, name, default=False, untrusted=False):
279 def configbool(self, section, name, default=False, untrusted=False):
280 return self._configcommon(section, name, default, 'getboolean',
280 return self._configcommon(section, name, default, 'getboolean',
281 untrusted)
281 untrusted)
282
282
283 def configlist(self, section, name, default=None, untrusted=False):
283 def configlist(self, section, name, default=None, untrusted=False):
284 """Return a list of comma/space separated strings"""
284 """Return a list of comma/space separated strings"""
285 result = self.config(section, name, untrusted=untrusted)
285 result = self.config(section, name, untrusted=untrusted)
286 if result is None:
286 if result is None:
287 result = default or []
287 result = default or []
288 if isinstance(result, basestring):
288 if isinstance(result, basestring):
289 result = result.replace(",", " ").split()
289 result = result.replace(",", " ").split()
290 return result
290 return result
291
291
292 def has_section(self, section, untrusted=False):
292 def has_section(self, section, untrusted=False):
293 '''tell whether section exists in config.'''
293 '''tell whether section exists in config.'''
294 cdata = self._get_cdata(untrusted)
294 cdata = self._get_cdata(untrusted)
295 return cdata.has_section(section)
295 return cdata.has_section(section)
296
296
297 def _configitems(self, section, untrusted, abort):
297 def _configitems(self, section, untrusted, abort):
298 items = {}
298 items = {}
299 cdata = self._get_cdata(untrusted)
299 cdata = self._get_cdata(untrusted)
300 if cdata.has_section(section):
300 if cdata.has_section(section):
301 try:
301 try:
302 items.update(dict(cdata.items(section)))
302 items.update(dict(cdata.items(section)))
303 except ConfigParser.InterpolationError, inst:
303 except ConfigParser.InterpolationError, inst:
304 msg = _("Error in configuration section [%s]:\n"
304 msg = _("Error in configuration section [%s]:\n"
305 "%s") % (section, inst)
305 "%s") % (section, inst)
306 if abort:
306 if abort:
307 raise util.Abort(msg)
307 raise util.Abort(msg)
308 self.warn(_("Ignored: %s\n") % msg)
308 self.warn(_("Ignored: %s\n") % msg)
309 return items
309 return items
310
310
311 def configitems(self, section, untrusted=False):
311 def configitems(self, section, untrusted=False):
312 items = self._configitems(section, untrusted=untrusted, abort=True)
312 items = self._configitems(section, untrusted=untrusted, abort=True)
313 if self.debugflag and not untrusted and self.ucdata:
313 if self.debugflag and not untrusted and self.ucdata:
314 uitems = self._configitems(section, untrusted=True, abort=False)
314 uitems = self._configitems(section, untrusted=True, abort=False)
315 for k in util.sort(uitems):
315 for k in util.sort(uitems):
316 if uitems[k] != items.get(k):
316 if uitems[k] != items.get(k):
317 self.warn(_("Ignoring untrusted configuration option "
317 self.warn(_("Ignoring untrusted configuration option "
318 "%s.%s = %s\n") % (section, k, uitems[k]))
318 "%s.%s = %s\n") % (section, k, uitems[k]))
319 return util.sort(items.items())
319 return util.sort(items.items())
320
320
321 def walkconfig(self, untrusted=False):
321 def walkconfig(self, untrusted=False):
322 cdata = self._get_cdata(untrusted)
322 cdata = self._get_cdata(untrusted)
323 sections = cdata.sections()
323 sections = cdata.sections()
324 sections.sort()
324 sections.sort()
325 for section in sections:
325 for section in sections:
326 for name, value in self.configitems(section, untrusted):
326 for name, value in self.configitems(section, untrusted):
327 yield section, name, str(value).replace('\n', '\\n')
327 yield section, name, str(value).replace('\n', '\\n')
328
328
329 def username(self):
329 def username(self):
330 """Return default username to be used in commits.
330 """Return default username to be used in commits.
331
331
332 Searched in this order: $HGUSER, [ui] section of hgrcs, $EMAIL
332 Searched in this order: $HGUSER, [ui] section of hgrcs, $EMAIL
333 and stop searching if one of these is set.
333 and stop searching if one of these is set.
334 If not found and ui.askusername is True, ask the user, else use
334 If not found and ui.askusername is True, ask the user, else use
335 ($LOGNAME or $USER or $LNAME or $USERNAME) + "@full.hostname".
335 ($LOGNAME or $USER or $LNAME or $USERNAME) + "@full.hostname".
336 """
336 """
337 user = os.environ.get("HGUSER")
337 user = os.environ.get("HGUSER")
338 if user is None:
338 if user is None:
339 user = self.config("ui", "username")
339 user = self.config("ui", "username")
340 if user is None:
340 if user is None:
341 user = os.environ.get("EMAIL")
341 user = os.environ.get("EMAIL")
342 if user is None and self.configbool("ui", "askusername"):
342 if user is None and self.configbool("ui", "askusername"):
343 user = self.prompt(_("Enter a commit username:"), default=None)
343 user = self.prompt(_("Enter a commit username:"), default=None)
344 if user is None:
344 if user is None:
345 try:
345 try:
346 user = '%s@%s' % (util.getuser(), socket.getfqdn())
346 user = '%s@%s' % (util.getuser(), socket.getfqdn())
347 self.warn(_("No username found, using '%s' instead\n") % user)
347 self.warn(_("No username found, using '%s' instead\n") % user)
348 except KeyError:
348 except KeyError:
349 pass
349 pass
350 if not user:
350 if not user:
351 raise util.Abort(_("Please specify a username."))
351 raise util.Abort(_("Please specify a username."))
352 if "\n" in user:
352 if "\n" in user:
353 raise util.Abort(_("username %s contains a newline\n") % `user`)
353 raise util.Abort(_("username %s contains a newline\n") % `user`)
354 return user
354 return user
355
355
356 def shortuser(self, user):
356 def shortuser(self, user):
357 """Return a short representation of a user name or email address."""
357 """Return a short representation of a user name or email address."""
358 if not self.verbose: user = util.shortuser(user)
358 if not self.verbose: user = util.shortuser(user)
359 return user
359 return user
360
360
361 def expandpath(self, loc, default=None):
361 def expandpath(self, loc, default=None):
362 """Return repository location relative to cwd or from [paths]"""
362 """Return repository location relative to cwd or from [paths]"""
363 if "://" in loc or os.path.isdir(os.path.join(loc, '.hg')):
363 if "://" in loc or os.path.isdir(os.path.join(loc, '.hg')):
364 return loc
364 return loc
365
365
366 path = self.config("paths", loc)
366 path = self.config("paths", loc)
367 if not path and default is not None:
367 if not path and default is not None:
368 path = self.config("paths", default)
368 path = self.config("paths", default)
369 return path or loc
369 return path or loc
370
370
371 def pushbuffer(self):
371 def pushbuffer(self):
372 self.buffers.append([])
372 self.buffers.append([])
373
373
374 def popbuffer(self):
374 def popbuffer(self):
375 return "".join(self.buffers.pop())
375 return "".join(self.buffers.pop())
376
376
377 def write(self, *args):
377 def write(self, *args):
378 if self.buffers:
378 if self.buffers:
379 self.buffers[-1].extend([str(a) for a in args])
379 self.buffers[-1].extend([str(a) for a in args])
380 else:
380 else:
381 for a in args:
381 for a in args:
382 sys.stdout.write(str(a))
382 sys.stdout.write(str(a))
383
383
384 def write_err(self, *args):
384 def write_err(self, *args):
385 try:
385 try:
386 if not sys.stdout.closed: sys.stdout.flush()
386 if not sys.stdout.closed: sys.stdout.flush()
387 for a in args:
387 for a in args:
388 sys.stderr.write(str(a))
388 sys.stderr.write(str(a))
389 # stderr may be buffered under win32 when redirected to files,
389 # stderr may be buffered under win32 when redirected to files,
390 # including stdout.
390 # including stdout.
391 if not sys.stderr.closed: sys.stderr.flush()
391 if not sys.stderr.closed: sys.stderr.flush()
392 except IOError, inst:
392 except IOError, inst:
393 if inst.errno != errno.EPIPE:
393 if inst.errno != errno.EPIPE:
394 raise
394 raise
395
395
396 def flush(self):
396 def flush(self):
397 try: sys.stdout.flush()
397 try: sys.stdout.flush()
398 except: pass
398 except: pass
399 try: sys.stderr.flush()
399 try: sys.stderr.flush()
400 except: pass
400 except: pass
401
401
402 def _readline(self, prompt=''):
402 def _readline(self, prompt=''):
403 if self.isatty():
403 if self.isatty():
404 try:
404 try:
405 # magically add command line editing support, where
405 # magically add command line editing support, where
406 # available
406 # available
407 import readline
407 import readline
408 # force demandimport to really load the module
408 # force demandimport to really load the module
409 readline.read_history_file
409 readline.read_history_file
410 except ImportError:
410 except ImportError:
411 pass
411 pass
412 line = raw_input(prompt)
412 line = raw_input(prompt)
413 # When stdin is in binary mode on Windows, it can cause
413 # When stdin is in binary mode on Windows, it can cause
414 # raw_input() to emit an extra trailing carriage return
414 # raw_input() to emit an extra trailing carriage return
415 if os.linesep == '\r\n' and line and line[-1] == '\r':
415 if os.linesep == '\r\n' and line and line[-1] == '\r':
416 line = line[:-1]
416 line = line[:-1]
417 return line
417 return line
418
418
419 def prompt(self, msg, pat=None, default="y"):
419 def prompt(self, msg, pat=None, default="y"):
420 """Prompt user with msg, read response, and ensure it matches pat
420 """Prompt user with msg, read response, and ensure it matches pat
421
421
422 If not interactive -- the default is returned
422 If not interactive -- the default is returned
423 """
423 """
424 if not self.interactive: return default
424 if not self.interactive:
425 self.note(msg, ' ', default, "\n")
426 return default
425 while True:
427 while True:
426 try:
428 try:
427 r = self._readline(msg + ' ')
429 r = self._readline(msg + ' ')
428 if not r:
430 if not r:
429 return default
431 return default
430 if not pat or re.match(pat, r):
432 if not pat or re.match(pat, r):
431 return r
433 return r
432 else:
434 else:
433 self.write(_("unrecognized response\n"))
435 self.write(_("unrecognized response\n"))
434 except EOFError:
436 except EOFError:
435 raise util.Abort(_('response expected'))
437 raise util.Abort(_('response expected'))
436
438
437 def getpass(self, prompt=None, default=None):
439 def getpass(self, prompt=None, default=None):
438 if not self.interactive: return default
440 if not self.interactive: return default
439 return getpass.getpass(prompt or _('password: '))
441 return getpass.getpass(prompt or _('password: '))
440 def status(self, *msg):
442 def status(self, *msg):
441 if not self.quiet: self.write(*msg)
443 if not self.quiet: self.write(*msg)
442 def warn(self, *msg):
444 def warn(self, *msg):
443 self.write_err(*msg)
445 self.write_err(*msg)
444 def note(self, *msg):
446 def note(self, *msg):
445 if self.verbose: self.write(*msg)
447 if self.verbose: self.write(*msg)
446 def debug(self, *msg):
448 def debug(self, *msg):
447 if self.debugflag: self.write(*msg)
449 if self.debugflag: self.write(*msg)
448 def edit(self, text, user):
450 def edit(self, text, user):
449 (fd, name) = tempfile.mkstemp(prefix="hg-editor-", suffix=".txt",
451 (fd, name) = tempfile.mkstemp(prefix="hg-editor-", suffix=".txt",
450 text=True)
452 text=True)
451 try:
453 try:
452 f = os.fdopen(fd, "w")
454 f = os.fdopen(fd, "w")
453 f.write(text)
455 f.write(text)
454 f.close()
456 f.close()
455
457
456 editor = self.geteditor()
458 editor = self.geteditor()
457
459
458 util.system("%s \"%s\"" % (editor, name),
460 util.system("%s \"%s\"" % (editor, name),
459 environ={'HGUSER': user},
461 environ={'HGUSER': user},
460 onerr=util.Abort, errprefix=_("edit failed"))
462 onerr=util.Abort, errprefix=_("edit failed"))
461
463
462 f = open(name)
464 f = open(name)
463 t = f.read()
465 t = f.read()
464 f.close()
466 f.close()
465 t = re.sub("(?m)^HG:.*\n", "", t)
467 t = re.sub("(?m)^HG:.*\n", "", t)
466 finally:
468 finally:
467 os.unlink(name)
469 os.unlink(name)
468
470
469 return t
471 return t
470
472
471 def print_exc(self):
473 def print_exc(self):
472 '''print exception traceback if traceback printing enabled.
474 '''print exception traceback if traceback printing enabled.
473 only to call in exception handler. returns true if traceback
475 only to call in exception handler. returns true if traceback
474 printed.'''
476 printed.'''
475 if self.traceback:
477 if self.traceback:
476 traceback.print_exc()
478 traceback.print_exc()
477 return self.traceback
479 return self.traceback
478
480
479 def geteditor(self):
481 def geteditor(self):
480 '''return editor to use'''
482 '''return editor to use'''
481 return (os.environ.get("HGEDITOR") or
483 return (os.environ.get("HGEDITOR") or
482 self.config("ui", "editor") or
484 self.config("ui", "editor") or
483 os.environ.get("VISUAL") or
485 os.environ.get("VISUAL") or
484 os.environ.get("EDITOR", "vi"))
486 os.environ.get("EDITOR", "vi"))
@@ -1,23 +1,27 b''
1 adding a
1 adding a
2 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
2 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
3 created new head
3 created new head
4 resolving manifests
4 resolving manifests
5 overwrite None partial False
5 overwrite None partial False
6 ancestor c334dc3be0da local 521a1e40188f+ remote 3574f3e69b1c
6 ancestor c334dc3be0da local 521a1e40188f+ remote 3574f3e69b1c
7 searching for copies back to rev 1
7 searching for copies back to rev 1
8 conflicting flags for a
9 (n)one, e(x)ec or sym(l)ink? n
8 a: update permissions -> e
10 a: update permissions -> e
9 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
11 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
10 (branch merge, don't forget to commit)
12 (branch merge, don't forget to commit)
11 % symlink is local parent, executable is other
13 % symlink is local parent, executable is other
12 a has no flags (default for conflicts)
14 a has no flags (default for conflicts)
13 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
15 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
14 resolving manifests
16 resolving manifests
15 overwrite None partial False
17 overwrite None partial False
16 ancestor c334dc3be0da local 3574f3e69b1c+ remote 521a1e40188f
18 ancestor c334dc3be0da local 3574f3e69b1c+ remote 521a1e40188f
17 searching for copies back to rev 1
19 searching for copies back to rev 1
20 conflicting flags for a
21 (n)one, e(x)ec or sym(l)ink? n
18 a: remote is newer -> g
22 a: remote is newer -> g
19 getting a
23 getting a
20 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
24 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
21 (branch merge, don't forget to commit)
25 (branch merge, don't forget to commit)
22 % symlink is other parent, executable is local
26 % symlink is other parent, executable is local
23 a has no flags (default for conflicts)
27 a has no flags (default for conflicts)
@@ -1,596 +1,600 b''
1 created new head
1 created new head
2 --------------
2 --------------
3 test L:up a R:nc a b W: - 1 get local a to b
3 test L:up a R:nc a b W: - 1 get local a to b
4 --------------
4 --------------
5 resolving manifests
5 resolving manifests
6 overwrite None partial False
6 overwrite None partial False
7 ancestor 924404dff337 local e300d1c794ec+ remote 735846fee2d7
7 ancestor 924404dff337 local e300d1c794ec+ remote 735846fee2d7
8 searching for copies back to rev 1
8 searching for copies back to rev 1
9 unmatched files in other:
9 unmatched files in other:
10 b
10 b
11 all copies found (* = to merge, ! = divergent):
11 all copies found (* = to merge, ! = divergent):
12 b -> a *
12 b -> a *
13 checking for directory renames
13 checking for directory renames
14 rev: versions differ -> m
14 rev: versions differ -> m
15 a: remote copied to b -> m
15 a: remote copied to b -> m
16 preserving a for resolve of b
16 preserving a for resolve of b
17 preserving rev for resolve of rev
17 preserving rev for resolve of rev
18 picked tool 'python ../merge' for b (binary False symlink False)
18 picked tool 'python ../merge' for b (binary False symlink False)
19 merging a and b to b
19 merging a and b to b
20 my b@e300d1c794ec+ other b@735846fee2d7 ancestor a@924404dff337
20 my b@e300d1c794ec+ other b@735846fee2d7 ancestor a@924404dff337
21 premerge successful
21 premerge successful
22 picked tool 'python ../merge' for rev (binary False symlink False)
22 picked tool 'python ../merge' for rev (binary False symlink False)
23 merging rev
23 merging rev
24 my rev@e300d1c794ec+ other rev@735846fee2d7 ancestor rev@924404dff337
24 my rev@e300d1c794ec+ other rev@735846fee2d7 ancestor rev@924404dff337
25 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
25 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
26 (branch merge, don't forget to commit)
26 (branch merge, don't forget to commit)
27 --------------
27 --------------
28 M b
28 M b
29 a
29 a
30 C a
30 C a
31 --------------
31 --------------
32
32
33 created new head
33 created new head
34 --------------
34 --------------
35 test L:nc a b R:up a W: - 2 get rem change to a and b
35 test L:nc a b R:up a W: - 2 get rem change to a and b
36 --------------
36 --------------
37 resolving manifests
37 resolving manifests
38 overwrite None partial False
38 overwrite None partial False
39 ancestor 924404dff337 local ac809aeed39a+ remote f4db7e329e71
39 ancestor 924404dff337 local ac809aeed39a+ remote f4db7e329e71
40 searching for copies back to rev 1
40 searching for copies back to rev 1
41 unmatched files in local:
41 unmatched files in local:
42 b
42 b
43 all copies found (* = to merge, ! = divergent):
43 all copies found (* = to merge, ! = divergent):
44 b -> a *
44 b -> a *
45 checking for directory renames
45 checking for directory renames
46 a: remote is newer -> g
46 a: remote is newer -> g
47 b: local copied to a -> m
47 b: local copied to a -> m
48 rev: versions differ -> m
48 rev: versions differ -> m
49 preserving b for resolve of b
49 preserving b for resolve of b
50 preserving rev for resolve of rev
50 preserving rev for resolve of rev
51 getting a
51 getting a
52 picked tool 'python ../merge' for b (binary False symlink False)
52 picked tool 'python ../merge' for b (binary False symlink False)
53 merging b and a to b
53 merging b and a to b
54 my b@ac809aeed39a+ other a@f4db7e329e71 ancestor a@924404dff337
54 my b@ac809aeed39a+ other a@f4db7e329e71 ancestor a@924404dff337
55 premerge successful
55 premerge successful
56 picked tool 'python ../merge' for rev (binary False symlink False)
56 picked tool 'python ../merge' for rev (binary False symlink False)
57 merging rev
57 merging rev
58 my rev@ac809aeed39a+ other rev@f4db7e329e71 ancestor rev@924404dff337
58 my rev@ac809aeed39a+ other rev@f4db7e329e71 ancestor rev@924404dff337
59 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
59 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
60 (branch merge, don't forget to commit)
60 (branch merge, don't forget to commit)
61 --------------
61 --------------
62 M a
62 M a
63 M b
63 M b
64 a
64 a
65 --------------
65 --------------
66
66
67 created new head
67 created new head
68 --------------
68 --------------
69 test L:up a R:nm a b W: - 3 get local a change to b, remove a
69 test L:up a R:nm a b W: - 3 get local a change to b, remove a
70 --------------
70 --------------
71 resolving manifests
71 resolving manifests
72 overwrite None partial False
72 overwrite None partial False
73 ancestor 924404dff337 local e300d1c794ec+ remote e03727d2d66b
73 ancestor 924404dff337 local e300d1c794ec+ remote e03727d2d66b
74 searching for copies back to rev 1
74 searching for copies back to rev 1
75 unmatched files in other:
75 unmatched files in other:
76 b
76 b
77 all copies found (* = to merge, ! = divergent):
77 all copies found (* = to merge, ! = divergent):
78 b -> a *
78 b -> a *
79 checking for directory renames
79 checking for directory renames
80 rev: versions differ -> m
80 rev: versions differ -> m
81 a: remote moved to b -> m
81 a: remote moved to b -> m
82 preserving a for resolve of b
82 preserving a for resolve of b
83 preserving rev for resolve of rev
83 preserving rev for resolve of rev
84 removing a
84 removing a
85 picked tool 'python ../merge' for b (binary False symlink False)
85 picked tool 'python ../merge' for b (binary False symlink False)
86 merging a and b to b
86 merging a and b to b
87 my b@e300d1c794ec+ other b@e03727d2d66b ancestor a@924404dff337
87 my b@e300d1c794ec+ other b@e03727d2d66b ancestor a@924404dff337
88 premerge successful
88 premerge successful
89 picked tool 'python ../merge' for rev (binary False symlink False)
89 picked tool 'python ../merge' for rev (binary False symlink False)
90 merging rev
90 merging rev
91 my rev@e300d1c794ec+ other rev@e03727d2d66b ancestor rev@924404dff337
91 my rev@e300d1c794ec+ other rev@e03727d2d66b ancestor rev@924404dff337
92 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
92 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
93 (branch merge, don't forget to commit)
93 (branch merge, don't forget to commit)
94 --------------
94 --------------
95 M b
95 M b
96 a
96 a
97 --------------
97 --------------
98
98
99 created new head
99 created new head
100 --------------
100 --------------
101 test L:nm a b R:up a W: - 4 get remote change to b
101 test L:nm a b R:up a W: - 4 get remote change to b
102 --------------
102 --------------
103 resolving manifests
103 resolving manifests
104 overwrite None partial False
104 overwrite None partial False
105 ancestor 924404dff337 local ecf3cb2a4219+ remote f4db7e329e71
105 ancestor 924404dff337 local ecf3cb2a4219+ remote f4db7e329e71
106 searching for copies back to rev 1
106 searching for copies back to rev 1
107 unmatched files in local:
107 unmatched files in local:
108 b
108 b
109 all copies found (* = to merge, ! = divergent):
109 all copies found (* = to merge, ! = divergent):
110 b -> a *
110 b -> a *
111 checking for directory renames
111 checking for directory renames
112 b: local moved to a -> m
112 b: local moved to a -> m
113 rev: versions differ -> m
113 rev: versions differ -> m
114 preserving b for resolve of b
114 preserving b for resolve of b
115 preserving rev for resolve of rev
115 preserving rev for resolve of rev
116 picked tool 'python ../merge' for b (binary False symlink False)
116 picked tool 'python ../merge' for b (binary False symlink False)
117 merging b and a to b
117 merging b and a to b
118 my b@ecf3cb2a4219+ other a@f4db7e329e71 ancestor a@924404dff337
118 my b@ecf3cb2a4219+ other a@f4db7e329e71 ancestor a@924404dff337
119 premerge successful
119 premerge successful
120 picked tool 'python ../merge' for rev (binary False symlink False)
120 picked tool 'python ../merge' for rev (binary False symlink False)
121 merging rev
121 merging rev
122 my rev@ecf3cb2a4219+ other rev@f4db7e329e71 ancestor rev@924404dff337
122 my rev@ecf3cb2a4219+ other rev@f4db7e329e71 ancestor rev@924404dff337
123 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
123 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
124 (branch merge, don't forget to commit)
124 (branch merge, don't forget to commit)
125 --------------
125 --------------
126 M b
126 M b
127 a
127 a
128 --------------
128 --------------
129
129
130 created new head
130 created new head
131 --------------
131 --------------
132 test L: R:nc a b W: - 5 get b
132 test L: R:nc a b W: - 5 get b
133 --------------
133 --------------
134 resolving manifests
134 resolving manifests
135 overwrite None partial False
135 overwrite None partial False
136 ancestor 924404dff337 local 94b33a1b7f2d+ remote 735846fee2d7
136 ancestor 924404dff337 local 94b33a1b7f2d+ remote 735846fee2d7
137 searching for copies back to rev 1
137 searching for copies back to rev 1
138 unmatched files in other:
138 unmatched files in other:
139 b
139 b
140 all copies found (* = to merge, ! = divergent):
140 all copies found (* = to merge, ! = divergent):
141 b -> a
141 b -> a
142 checking for directory renames
142 checking for directory renames
143 rev: versions differ -> m
143 rev: versions differ -> m
144 b: remote created -> g
144 b: remote created -> g
145 preserving rev for resolve of rev
145 preserving rev for resolve of rev
146 getting b
146 getting b
147 picked tool 'python ../merge' for rev (binary False symlink False)
147 picked tool 'python ../merge' for rev (binary False symlink False)
148 merging rev
148 merging rev
149 my rev@94b33a1b7f2d+ other rev@735846fee2d7 ancestor rev@924404dff337
149 my rev@94b33a1b7f2d+ other rev@735846fee2d7 ancestor rev@924404dff337
150 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
150 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
151 (branch merge, don't forget to commit)
151 (branch merge, don't forget to commit)
152 --------------
152 --------------
153 M b
153 M b
154 C a
154 C a
155 --------------
155 --------------
156
156
157 created new head
157 created new head
158 --------------
158 --------------
159 test L:nc a b R: W: - 6 nothing
159 test L:nc a b R: W: - 6 nothing
160 --------------
160 --------------
161 resolving manifests
161 resolving manifests
162 overwrite None partial False
162 overwrite None partial False
163 ancestor 924404dff337 local ac809aeed39a+ remote 97c705ade336
163 ancestor 924404dff337 local ac809aeed39a+ remote 97c705ade336
164 searching for copies back to rev 1
164 searching for copies back to rev 1
165 unmatched files in local:
165 unmatched files in local:
166 b
166 b
167 all copies found (* = to merge, ! = divergent):
167 all copies found (* = to merge, ! = divergent):
168 b -> a
168 b -> a
169 checking for directory renames
169 checking for directory renames
170 rev: versions differ -> m
170 rev: versions differ -> m
171 preserving rev for resolve of rev
171 preserving rev for resolve of rev
172 picked tool 'python ../merge' for rev (binary False symlink False)
172 picked tool 'python ../merge' for rev (binary False symlink False)
173 merging rev
173 merging rev
174 my rev@ac809aeed39a+ other rev@97c705ade336 ancestor rev@924404dff337
174 my rev@ac809aeed39a+ other rev@97c705ade336 ancestor rev@924404dff337
175 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
175 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
176 (branch merge, don't forget to commit)
176 (branch merge, don't forget to commit)
177 --------------
177 --------------
178 C a
178 C a
179 C b
179 C b
180 --------------
180 --------------
181
181
182 created new head
182 created new head
183 --------------
183 --------------
184 test L: R:nm a b W: - 7 get b
184 test L: R:nm a b W: - 7 get b
185 --------------
185 --------------
186 resolving manifests
186 resolving manifests
187 overwrite None partial False
187 overwrite None partial False
188 ancestor 924404dff337 local 94b33a1b7f2d+ remote e03727d2d66b
188 ancestor 924404dff337 local 94b33a1b7f2d+ remote e03727d2d66b
189 searching for copies back to rev 1
189 searching for copies back to rev 1
190 unmatched files in other:
190 unmatched files in other:
191 b
191 b
192 all copies found (* = to merge, ! = divergent):
192 all copies found (* = to merge, ! = divergent):
193 b -> a
193 b -> a
194 checking for directory renames
194 checking for directory renames
195 a: other deleted -> r
195 a: other deleted -> r
196 rev: versions differ -> m
196 rev: versions differ -> m
197 b: remote created -> g
197 b: remote created -> g
198 preserving rev for resolve of rev
198 preserving rev for resolve of rev
199 removing a
199 removing a
200 getting b
200 getting b
201 picked tool 'python ../merge' for rev (binary False symlink False)
201 picked tool 'python ../merge' for rev (binary False symlink False)
202 merging rev
202 merging rev
203 my rev@94b33a1b7f2d+ other rev@e03727d2d66b ancestor rev@924404dff337
203 my rev@94b33a1b7f2d+ other rev@e03727d2d66b ancestor rev@924404dff337
204 1 files updated, 1 files merged, 1 files removed, 0 files unresolved
204 1 files updated, 1 files merged, 1 files removed, 0 files unresolved
205 (branch merge, don't forget to commit)
205 (branch merge, don't forget to commit)
206 --------------
206 --------------
207 M b
207 M b
208 --------------
208 --------------
209
209
210 created new head
210 created new head
211 --------------
211 --------------
212 test L:nm a b R: W: - 8 nothing
212 test L:nm a b R: W: - 8 nothing
213 --------------
213 --------------
214 resolving manifests
214 resolving manifests
215 overwrite None partial False
215 overwrite None partial False
216 ancestor 924404dff337 local ecf3cb2a4219+ remote 97c705ade336
216 ancestor 924404dff337 local ecf3cb2a4219+ remote 97c705ade336
217 searching for copies back to rev 1
217 searching for copies back to rev 1
218 unmatched files in local:
218 unmatched files in local:
219 b
219 b
220 all copies found (* = to merge, ! = divergent):
220 all copies found (* = to merge, ! = divergent):
221 b -> a
221 b -> a
222 checking for directory renames
222 checking for directory renames
223 rev: versions differ -> m
223 rev: versions differ -> m
224 preserving rev for resolve of rev
224 preserving rev for resolve of rev
225 picked tool 'python ../merge' for rev (binary False symlink False)
225 picked tool 'python ../merge' for rev (binary False symlink False)
226 merging rev
226 merging rev
227 my rev@ecf3cb2a4219+ other rev@97c705ade336 ancestor rev@924404dff337
227 my rev@ecf3cb2a4219+ other rev@97c705ade336 ancestor rev@924404dff337
228 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
228 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
229 (branch merge, don't forget to commit)
229 (branch merge, don't forget to commit)
230 --------------
230 --------------
231 C b
231 C b
232 --------------
232 --------------
233
233
234 created new head
234 created new head
235 --------------
235 --------------
236 test L:um a b R:um a b W: - 9 do merge with ancestor in a
236 test L:um a b R:um a b W: - 9 do merge with ancestor in a
237 --------------
237 --------------
238 resolving manifests
238 resolving manifests
239 overwrite None partial False
239 overwrite None partial False
240 ancestor 924404dff337 local ec03c2ca8642+ remote 79cc6877a3b7
240 ancestor 924404dff337 local ec03c2ca8642+ remote 79cc6877a3b7
241 searching for copies back to rev 1
241 searching for copies back to rev 1
242 b: versions differ -> m
242 b: versions differ -> m
243 rev: versions differ -> m
243 rev: versions differ -> m
244 preserving b for resolve of b
244 preserving b for resolve of b
245 preserving rev for resolve of rev
245 preserving rev for resolve of rev
246 picked tool 'python ../merge' for b (binary False symlink False)
246 picked tool 'python ../merge' for b (binary False symlink False)
247 merging b
247 merging b
248 my b@ec03c2ca8642+ other b@79cc6877a3b7 ancestor a@924404dff337
248 my b@ec03c2ca8642+ other b@79cc6877a3b7 ancestor a@924404dff337
249 picked tool 'python ../merge' for rev (binary False symlink False)
249 picked tool 'python ../merge' for rev (binary False symlink False)
250 merging rev
250 merging rev
251 my rev@ec03c2ca8642+ other rev@79cc6877a3b7 ancestor rev@924404dff337
251 my rev@ec03c2ca8642+ other rev@79cc6877a3b7 ancestor rev@924404dff337
252 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
252 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
253 (branch merge, don't forget to commit)
253 (branch merge, don't forget to commit)
254 --------------
254 --------------
255 M b
255 M b
256 --------------
256 --------------
257
257
258 created new head
258 created new head
259 --------------
259 --------------
260 test L:nm a b R:nm a c W: - 11 get c, keep b
260 test L:nm a b R:nm a c W: - 11 get c, keep b
261 --------------
261 --------------
262 resolving manifests
262 resolving manifests
263 overwrite None partial False
263 overwrite None partial False
264 ancestor 924404dff337 local ecf3cb2a4219+ remote e6abcc1a30c2
264 ancestor 924404dff337 local ecf3cb2a4219+ remote e6abcc1a30c2
265 searching for copies back to rev 1
265 searching for copies back to rev 1
266 unmatched files in local:
266 unmatched files in local:
267 b
267 b
268 unmatched files in other:
268 unmatched files in other:
269 c
269 c
270 all copies found (* = to merge, ! = divergent):
270 all copies found (* = to merge, ! = divergent):
271 c -> a !
271 c -> a !
272 b -> a !
272 b -> a !
273 checking for directory renames
273 checking for directory renames
274 a: divergent renames -> dr
274 a: divergent renames -> dr
275 rev: versions differ -> m
275 rev: versions differ -> m
276 c: remote created -> g
276 c: remote created -> g
277 preserving rev for resolve of rev
277 preserving rev for resolve of rev
278 warning: detected divergent renames of a to:
278 warning: detected divergent renames of a to:
279 b
279 b
280 c
280 c
281 getting c
281 getting c
282 picked tool 'python ../merge' for rev (binary False symlink False)
282 picked tool 'python ../merge' for rev (binary False symlink False)
283 merging rev
283 merging rev
284 my rev@ecf3cb2a4219+ other rev@e6abcc1a30c2 ancestor rev@924404dff337
284 my rev@ecf3cb2a4219+ other rev@e6abcc1a30c2 ancestor rev@924404dff337
285 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
285 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
286 (branch merge, don't forget to commit)
286 (branch merge, don't forget to commit)
287 --------------
287 --------------
288 M c
288 M c
289 C b
289 C b
290 --------------
290 --------------
291
291
292 created new head
292 created new head
293 --------------
293 --------------
294 test L:nc a b R:up b W: - 12 merge b no ancestor
294 test L:nc a b R:up b W: - 12 merge b no ancestor
295 --------------
295 --------------
296 resolving manifests
296 resolving manifests
297 overwrite None partial False
297 overwrite None partial False
298 ancestor 924404dff337 local ac809aeed39a+ remote af30c7647fc7
298 ancestor 924404dff337 local ac809aeed39a+ remote af30c7647fc7
299 searching for copies back to rev 1
299 searching for copies back to rev 1
300 b: versions differ -> m
300 b: versions differ -> m
301 rev: versions differ -> m
301 rev: versions differ -> m
302 preserving b for resolve of b
302 preserving b for resolve of b
303 preserving rev for resolve of rev
303 preserving rev for resolve of rev
304 picked tool 'python ../merge' for b (binary False symlink False)
304 picked tool 'python ../merge' for b (binary False symlink False)
305 merging b
305 merging b
306 my b@ac809aeed39a+ other b@af30c7647fc7 ancestor b@000000000000
306 my b@ac809aeed39a+ other b@af30c7647fc7 ancestor b@000000000000
307 picked tool 'python ../merge' for rev (binary False symlink False)
307 picked tool 'python ../merge' for rev (binary False symlink False)
308 merging rev
308 merging rev
309 my rev@ac809aeed39a+ other rev@af30c7647fc7 ancestor rev@924404dff337
309 my rev@ac809aeed39a+ other rev@af30c7647fc7 ancestor rev@924404dff337
310 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
310 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
311 (branch merge, don't forget to commit)
311 (branch merge, don't forget to commit)
312 --------------
312 --------------
313 M b
313 M b
314 C a
314 C a
315 --------------
315 --------------
316
316
317 created new head
317 created new head
318 --------------
318 --------------
319 test L:up b R:nm a b W: - 13 merge b no ancestor
319 test L:up b R:nm a b W: - 13 merge b no ancestor
320 --------------
320 --------------
321 resolving manifests
321 resolving manifests
322 overwrite None partial False
322 overwrite None partial False
323 ancestor 924404dff337 local 59318016310c+ remote e03727d2d66b
323 ancestor 924404dff337 local 59318016310c+ remote e03727d2d66b
324 searching for copies back to rev 1
324 searching for copies back to rev 1
325 a: other deleted -> r
325 a: other deleted -> r
326 b: versions differ -> m
326 b: versions differ -> m
327 rev: versions differ -> m
327 rev: versions differ -> m
328 preserving b for resolve of b
328 preserving b for resolve of b
329 preserving rev for resolve of rev
329 preserving rev for resolve of rev
330 removing a
330 removing a
331 picked tool 'python ../merge' for b (binary False symlink False)
331 picked tool 'python ../merge' for b (binary False symlink False)
332 merging b
332 merging b
333 my b@59318016310c+ other b@e03727d2d66b ancestor b@000000000000
333 my b@59318016310c+ other b@e03727d2d66b ancestor b@000000000000
334 picked tool 'python ../merge' for rev (binary False symlink False)
334 picked tool 'python ../merge' for rev (binary False symlink False)
335 merging rev
335 merging rev
336 my rev@59318016310c+ other rev@e03727d2d66b ancestor rev@924404dff337
336 my rev@59318016310c+ other rev@e03727d2d66b ancestor rev@924404dff337
337 0 files updated, 2 files merged, 1 files removed, 0 files unresolved
337 0 files updated, 2 files merged, 1 files removed, 0 files unresolved
338 (branch merge, don't forget to commit)
338 (branch merge, don't forget to commit)
339 --------------
339 --------------
340 M b
340 M b
341 --------------
341 --------------
342
342
343 created new head
343 created new head
344 --------------
344 --------------
345 test L:nc a b R:up a b W: - 14 merge b no ancestor
345 test L:nc a b R:up a b W: - 14 merge b no ancestor
346 --------------
346 --------------
347 resolving manifests
347 resolving manifests
348 overwrite None partial False
348 overwrite None partial False
349 ancestor 924404dff337 local ac809aeed39a+ remote 8dbce441892a
349 ancestor 924404dff337 local ac809aeed39a+ remote 8dbce441892a
350 searching for copies back to rev 1
350 searching for copies back to rev 1
351 a: remote is newer -> g
351 a: remote is newer -> g
352 b: versions differ -> m
352 b: versions differ -> m
353 rev: versions differ -> m
353 rev: versions differ -> m
354 preserving b for resolve of b
354 preserving b for resolve of b
355 preserving rev for resolve of rev
355 preserving rev for resolve of rev
356 getting a
356 getting a
357 picked tool 'python ../merge' for b (binary False symlink False)
357 picked tool 'python ../merge' for b (binary False symlink False)
358 merging b
358 merging b
359 my b@ac809aeed39a+ other b@8dbce441892a ancestor b@000000000000
359 my b@ac809aeed39a+ other b@8dbce441892a ancestor b@000000000000
360 picked tool 'python ../merge' for rev (binary False symlink False)
360 picked tool 'python ../merge' for rev (binary False symlink False)
361 merging rev
361 merging rev
362 my rev@ac809aeed39a+ other rev@8dbce441892a ancestor rev@924404dff337
362 my rev@ac809aeed39a+ other rev@8dbce441892a ancestor rev@924404dff337
363 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
363 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
364 (branch merge, don't forget to commit)
364 (branch merge, don't forget to commit)
365 --------------
365 --------------
366 M a
366 M a
367 M b
367 M b
368 --------------
368 --------------
369
369
370 created new head
370 created new head
371 --------------
371 --------------
372 test L:up b R:nm a b W: - 15 merge b no ancestor, remove a
372 test L:up b R:nm a b W: - 15 merge b no ancestor, remove a
373 --------------
373 --------------
374 resolving manifests
374 resolving manifests
375 overwrite None partial False
375 overwrite None partial False
376 ancestor 924404dff337 local 59318016310c+ remote e03727d2d66b
376 ancestor 924404dff337 local 59318016310c+ remote e03727d2d66b
377 searching for copies back to rev 1
377 searching for copies back to rev 1
378 a: other deleted -> r
378 a: other deleted -> r
379 b: versions differ -> m
379 b: versions differ -> m
380 rev: versions differ -> m
380 rev: versions differ -> m
381 preserving b for resolve of b
381 preserving b for resolve of b
382 preserving rev for resolve of rev
382 preserving rev for resolve of rev
383 removing a
383 removing a
384 picked tool 'python ../merge' for b (binary False symlink False)
384 picked tool 'python ../merge' for b (binary False symlink False)
385 merging b
385 merging b
386 my b@59318016310c+ other b@e03727d2d66b ancestor b@000000000000
386 my b@59318016310c+ other b@e03727d2d66b ancestor b@000000000000
387 picked tool 'python ../merge' for rev (binary False symlink False)
387 picked tool 'python ../merge' for rev (binary False symlink False)
388 merging rev
388 merging rev
389 my rev@59318016310c+ other rev@e03727d2d66b ancestor rev@924404dff337
389 my rev@59318016310c+ other rev@e03727d2d66b ancestor rev@924404dff337
390 0 files updated, 2 files merged, 1 files removed, 0 files unresolved
390 0 files updated, 2 files merged, 1 files removed, 0 files unresolved
391 (branch merge, don't forget to commit)
391 (branch merge, don't forget to commit)
392 --------------
392 --------------
393 M b
393 M b
394 --------------
394 --------------
395
395
396 created new head
396 created new head
397 --------------
397 --------------
398 test L:nc a b R:up a b W: - 16 get a, merge b no ancestor
398 test L:nc a b R:up a b W: - 16 get a, merge b no ancestor
399 --------------
399 --------------
400 resolving manifests
400 resolving manifests
401 overwrite None partial False
401 overwrite None partial False
402 ancestor 924404dff337 local ac809aeed39a+ remote 8dbce441892a
402 ancestor 924404dff337 local ac809aeed39a+ remote 8dbce441892a
403 searching for copies back to rev 1
403 searching for copies back to rev 1
404 a: remote is newer -> g
404 a: remote is newer -> g
405 b: versions differ -> m
405 b: versions differ -> m
406 rev: versions differ -> m
406 rev: versions differ -> m
407 preserving b for resolve of b
407 preserving b for resolve of b
408 preserving rev for resolve of rev
408 preserving rev for resolve of rev
409 getting a
409 getting a
410 picked tool 'python ../merge' for b (binary False symlink False)
410 picked tool 'python ../merge' for b (binary False symlink False)
411 merging b
411 merging b
412 my b@ac809aeed39a+ other b@8dbce441892a ancestor b@000000000000
412 my b@ac809aeed39a+ other b@8dbce441892a ancestor b@000000000000
413 picked tool 'python ../merge' for rev (binary False symlink False)
413 picked tool 'python ../merge' for rev (binary False symlink False)
414 merging rev
414 merging rev
415 my rev@ac809aeed39a+ other rev@8dbce441892a ancestor rev@924404dff337
415 my rev@ac809aeed39a+ other rev@8dbce441892a ancestor rev@924404dff337
416 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
416 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
417 (branch merge, don't forget to commit)
417 (branch merge, don't forget to commit)
418 --------------
418 --------------
419 M a
419 M a
420 M b
420 M b
421 --------------
421 --------------
422
422
423 created new head
423 created new head
424 --------------
424 --------------
425 test L:up a b R:nc a b W: - 17 keep a, merge b no ancestor
425 test L:up a b R:nc a b W: - 17 keep a, merge b no ancestor
426 --------------
426 --------------
427 resolving manifests
427 resolving manifests
428 overwrite None partial False
428 overwrite None partial False
429 ancestor 924404dff337 local 0b76e65c8289+ remote 735846fee2d7
429 ancestor 924404dff337 local 0b76e65c8289+ remote 735846fee2d7
430 searching for copies back to rev 1
430 searching for copies back to rev 1
431 b: versions differ -> m
431 b: versions differ -> m
432 rev: versions differ -> m
432 rev: versions differ -> m
433 preserving b for resolve of b
433 preserving b for resolve of b
434 preserving rev for resolve of rev
434 preserving rev for resolve of rev
435 picked tool 'python ../merge' for b (binary False symlink False)
435 picked tool 'python ../merge' for b (binary False symlink False)
436 merging b
436 merging b
437 my b@0b76e65c8289+ other b@735846fee2d7 ancestor b@000000000000
437 my b@0b76e65c8289+ other b@735846fee2d7 ancestor b@000000000000
438 picked tool 'python ../merge' for rev (binary False symlink False)
438 picked tool 'python ../merge' for rev (binary False symlink False)
439 merging rev
439 merging rev
440 my rev@0b76e65c8289+ other rev@735846fee2d7 ancestor rev@924404dff337
440 my rev@0b76e65c8289+ other rev@735846fee2d7 ancestor rev@924404dff337
441 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
441 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
442 (branch merge, don't forget to commit)
442 (branch merge, don't forget to commit)
443 --------------
443 --------------
444 M b
444 M b
445 C a
445 C a
446 --------------
446 --------------
447
447
448 created new head
448 created new head
449 --------------
449 --------------
450 test L:nm a b R:up a b W: - 18 merge b no ancestor
450 test L:nm a b R:up a b W: - 18 merge b no ancestor
451 --------------
451 --------------
452 resolving manifests
452 resolving manifests
453 overwrite None partial False
453 overwrite None partial False
454 ancestor 924404dff337 local ecf3cb2a4219+ remote 8dbce441892a
454 ancestor 924404dff337 local ecf3cb2a4219+ remote 8dbce441892a
455 searching for copies back to rev 1
455 searching for copies back to rev 1
456 b: versions differ -> m
456 b: versions differ -> m
457 rev: versions differ -> m
457 rev: versions differ -> m
458 remote changed a which local deleted
459 use (c)hanged version or leave (d)eleted? c
458 a: prompt recreating -> g
460 a: prompt recreating -> g
459 preserving b for resolve of b
461 preserving b for resolve of b
460 preserving rev for resolve of rev
462 preserving rev for resolve of rev
461 getting a
463 getting a
462 picked tool 'python ../merge' for b (binary False symlink False)
464 picked tool 'python ../merge' for b (binary False symlink False)
463 merging b
465 merging b
464 my b@ecf3cb2a4219+ other b@8dbce441892a ancestor b@000000000000
466 my b@ecf3cb2a4219+ other b@8dbce441892a ancestor b@000000000000
465 picked tool 'python ../merge' for rev (binary False symlink False)
467 picked tool 'python ../merge' for rev (binary False symlink False)
466 merging rev
468 merging rev
467 my rev@ecf3cb2a4219+ other rev@8dbce441892a ancestor rev@924404dff337
469 my rev@ecf3cb2a4219+ other rev@8dbce441892a ancestor rev@924404dff337
468 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
470 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
469 (branch merge, don't forget to commit)
471 (branch merge, don't forget to commit)
470 --------------
472 --------------
471 M a
473 M a
472 M b
474 M b
473 --------------
475 --------------
474
476
475 created new head
477 created new head
476 --------------
478 --------------
477 test L:up a b R:nm a b W: - 19 merge b no ancestor, prompt remove a
479 test L:up a b R:nm a b W: - 19 merge b no ancestor, prompt remove a
478 --------------
480 --------------
479 resolving manifests
481 resolving manifests
480 overwrite None partial False
482 overwrite None partial False
481 ancestor 924404dff337 local 0b76e65c8289+ remote e03727d2d66b
483 ancestor 924404dff337 local 0b76e65c8289+ remote e03727d2d66b
482 searching for copies back to rev 1
484 searching for copies back to rev 1
485 local changed a which remote deleted
486 use (c)hanged version or (d)elete? c
483 b: versions differ -> m
487 b: versions differ -> m
484 rev: versions differ -> m
488 rev: versions differ -> m
485 preserving b for resolve of b
489 preserving b for resolve of b
486 preserving rev for resolve of rev
490 preserving rev for resolve of rev
487 picked tool 'python ../merge' for b (binary False symlink False)
491 picked tool 'python ../merge' for b (binary False symlink False)
488 merging b
492 merging b
489 my b@0b76e65c8289+ other b@e03727d2d66b ancestor b@000000000000
493 my b@0b76e65c8289+ other b@e03727d2d66b ancestor b@000000000000
490 picked tool 'python ../merge' for rev (binary False symlink False)
494 picked tool 'python ../merge' for rev (binary False symlink False)
491 merging rev
495 merging rev
492 my rev@0b76e65c8289+ other rev@e03727d2d66b ancestor rev@924404dff337
496 my rev@0b76e65c8289+ other rev@e03727d2d66b ancestor rev@924404dff337
493 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
497 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
494 (branch merge, don't forget to commit)
498 (branch merge, don't forget to commit)
495 --------------
499 --------------
496 M b
500 M b
497 C a
501 C a
498 --------------
502 --------------
499
503
500 created new head
504 created new head
501 --------------
505 --------------
502 test L:up a R:um a b W: - 20 merge a and b to b, remove a
506 test L:up a R:um a b W: - 20 merge a and b to b, remove a
503 --------------
507 --------------
504 resolving manifests
508 resolving manifests
505 overwrite None partial False
509 overwrite None partial False
506 ancestor 924404dff337 local e300d1c794ec+ remote 79cc6877a3b7
510 ancestor 924404dff337 local e300d1c794ec+ remote 79cc6877a3b7
507 searching for copies back to rev 1
511 searching for copies back to rev 1
508 unmatched files in other:
512 unmatched files in other:
509 b
513 b
510 all copies found (* = to merge, ! = divergent):
514 all copies found (* = to merge, ! = divergent):
511 b -> a *
515 b -> a *
512 checking for directory renames
516 checking for directory renames
513 rev: versions differ -> m
517 rev: versions differ -> m
514 a: remote moved to b -> m
518 a: remote moved to b -> m
515 preserving a for resolve of b
519 preserving a for resolve of b
516 preserving rev for resolve of rev
520 preserving rev for resolve of rev
517 removing a
521 removing a
518 picked tool 'python ../merge' for b (binary False symlink False)
522 picked tool 'python ../merge' for b (binary False symlink False)
519 merging a and b to b
523 merging a and b to b
520 my b@e300d1c794ec+ other b@79cc6877a3b7 ancestor a@924404dff337
524 my b@e300d1c794ec+ other b@79cc6877a3b7 ancestor a@924404dff337
521 picked tool 'python ../merge' for rev (binary False symlink False)
525 picked tool 'python ../merge' for rev (binary False symlink False)
522 merging rev
526 merging rev
523 my rev@e300d1c794ec+ other rev@79cc6877a3b7 ancestor rev@924404dff337
527 my rev@e300d1c794ec+ other rev@79cc6877a3b7 ancestor rev@924404dff337
524 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
528 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
525 (branch merge, don't forget to commit)
529 (branch merge, don't forget to commit)
526 --------------
530 --------------
527 M b
531 M b
528 a
532 a
529 --------------
533 --------------
530
534
531 created new head
535 created new head
532 --------------
536 --------------
533 test L:um a b R:up a W: - 21 merge a and b to b
537 test L:um a b R:up a W: - 21 merge a and b to b
534 --------------
538 --------------
535 resolving manifests
539 resolving manifests
536 overwrite None partial False
540 overwrite None partial False
537 ancestor 924404dff337 local ec03c2ca8642+ remote f4db7e329e71
541 ancestor 924404dff337 local ec03c2ca8642+ remote f4db7e329e71
538 searching for copies back to rev 1
542 searching for copies back to rev 1
539 unmatched files in local:
543 unmatched files in local:
540 b
544 b
541 all copies found (* = to merge, ! = divergent):
545 all copies found (* = to merge, ! = divergent):
542 b -> a *
546 b -> a *
543 checking for directory renames
547 checking for directory renames
544 b: local moved to a -> m
548 b: local moved to a -> m
545 rev: versions differ -> m
549 rev: versions differ -> m
546 preserving b for resolve of b
550 preserving b for resolve of b
547 preserving rev for resolve of rev
551 preserving rev for resolve of rev
548 picked tool 'python ../merge' for b (binary False symlink False)
552 picked tool 'python ../merge' for b (binary False symlink False)
549 merging b and a to b
553 merging b and a to b
550 my b@ec03c2ca8642+ other a@f4db7e329e71 ancestor a@924404dff337
554 my b@ec03c2ca8642+ other a@f4db7e329e71 ancestor a@924404dff337
551 picked tool 'python ../merge' for rev (binary False symlink False)
555 picked tool 'python ../merge' for rev (binary False symlink False)
552 merging rev
556 merging rev
553 my rev@ec03c2ca8642+ other rev@f4db7e329e71 ancestor rev@924404dff337
557 my rev@ec03c2ca8642+ other rev@f4db7e329e71 ancestor rev@924404dff337
554 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
558 0 files updated, 2 files merged, 0 files removed, 0 files unresolved
555 (branch merge, don't forget to commit)
559 (branch merge, don't forget to commit)
556 --------------
560 --------------
557 M b
561 M b
558 a
562 a
559 --------------
563 --------------
560
564
561 created new head
565 created new head
562 --------------
566 --------------
563 test L:nm a b R:up a c W: - 23 get c, keep b
567 test L:nm a b R:up a c W: - 23 get c, keep b
564 --------------
568 --------------
565 resolving manifests
569 resolving manifests
566 overwrite None partial False
570 overwrite None partial False
567 ancestor 924404dff337 local ecf3cb2a4219+ remote 2b958612230f
571 ancestor 924404dff337 local ecf3cb2a4219+ remote 2b958612230f
568 searching for copies back to rev 1
572 searching for copies back to rev 1
569 unmatched files in local:
573 unmatched files in local:
570 b
574 b
571 unmatched files in other:
575 unmatched files in other:
572 c
576 c
573 all copies found (* = to merge, ! = divergent):
577 all copies found (* = to merge, ! = divergent):
574 b -> a *
578 b -> a *
575 checking for directory renames
579 checking for directory renames
576 b: local moved to a -> m
580 b: local moved to a -> m
577 rev: versions differ -> m
581 rev: versions differ -> m
578 c: remote created -> g
582 c: remote created -> g
579 preserving b for resolve of b
583 preserving b for resolve of b
580 preserving rev for resolve of rev
584 preserving rev for resolve of rev
581 picked tool 'python ../merge' for b (binary False symlink False)
585 picked tool 'python ../merge' for b (binary False symlink False)
582 merging b and a to b
586 merging b and a to b
583 my b@ecf3cb2a4219+ other a@2b958612230f ancestor a@924404dff337
587 my b@ecf3cb2a4219+ other a@2b958612230f ancestor a@924404dff337
584 premerge successful
588 premerge successful
585 getting c
589 getting c
586 picked tool 'python ../merge' for rev (binary False symlink False)
590 picked tool 'python ../merge' for rev (binary False symlink False)
587 merging rev
591 merging rev
588 my rev@ecf3cb2a4219+ other rev@2b958612230f ancestor rev@924404dff337
592 my rev@ecf3cb2a4219+ other rev@2b958612230f ancestor rev@924404dff337
589 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
593 1 files updated, 2 files merged, 0 files removed, 0 files unresolved
590 (branch merge, don't forget to commit)
594 (branch merge, don't forget to commit)
591 --------------
595 --------------
592 M b
596 M b
593 a
597 a
594 M c
598 M c
595 --------------
599 --------------
596
600
General Comments 0
You need to be logged in to leave comments. Login now