##// END OF EJS Templates
ui: fix extra space in username abort
Matt Mackall -
r20580:b75a23ee default
parent child Browse files
Show More
@@ -1,829 +1,829 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 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 i18n import _
8 from i18n import _
9 import errno, getpass, os, socket, sys, tempfile, traceback
9 import errno, getpass, os, socket, sys, tempfile, traceback
10 import config, scmutil, util, error, formatter
10 import config, scmutil, util, error, formatter
11
11
12 class ui(object):
12 class ui(object):
13 def __init__(self, src=None):
13 def __init__(self, src=None):
14 self._buffers = []
14 self._buffers = []
15 self.quiet = self.verbose = self.debugflag = self.tracebackflag = False
15 self.quiet = self.verbose = self.debugflag = self.tracebackflag = False
16 self._reportuntrusted = True
16 self._reportuntrusted = True
17 self._ocfg = config.config() # overlay
17 self._ocfg = config.config() # overlay
18 self._tcfg = config.config() # trusted
18 self._tcfg = config.config() # trusted
19 self._ucfg = config.config() # untrusted
19 self._ucfg = config.config() # untrusted
20 self._trustusers = set()
20 self._trustusers = set()
21 self._trustgroups = set()
21 self._trustgroups = set()
22 self.callhooks = True
22 self.callhooks = True
23
23
24 if src:
24 if src:
25 self.fout = src.fout
25 self.fout = src.fout
26 self.ferr = src.ferr
26 self.ferr = src.ferr
27 self.fin = src.fin
27 self.fin = src.fin
28
28
29 self._tcfg = src._tcfg.copy()
29 self._tcfg = src._tcfg.copy()
30 self._ucfg = src._ucfg.copy()
30 self._ucfg = src._ucfg.copy()
31 self._ocfg = src._ocfg.copy()
31 self._ocfg = src._ocfg.copy()
32 self._trustusers = src._trustusers.copy()
32 self._trustusers = src._trustusers.copy()
33 self._trustgroups = src._trustgroups.copy()
33 self._trustgroups = src._trustgroups.copy()
34 self.environ = src.environ
34 self.environ = src.environ
35 self.callhooks = src.callhooks
35 self.callhooks = src.callhooks
36 self.fixconfig()
36 self.fixconfig()
37 else:
37 else:
38 self.fout = sys.stdout
38 self.fout = sys.stdout
39 self.ferr = sys.stderr
39 self.ferr = sys.stderr
40 self.fin = sys.stdin
40 self.fin = sys.stdin
41
41
42 # shared read-only environment
42 # shared read-only environment
43 self.environ = os.environ
43 self.environ = os.environ
44 # we always trust global config files
44 # we always trust global config files
45 for f in scmutil.rcpath():
45 for f in scmutil.rcpath():
46 self.readconfig(f, trust=True)
46 self.readconfig(f, trust=True)
47
47
48 def copy(self):
48 def copy(self):
49 return self.__class__(self)
49 return self.__class__(self)
50
50
51 def formatter(self, topic, opts):
51 def formatter(self, topic, opts):
52 return formatter.formatter(self, topic, opts)
52 return formatter.formatter(self, topic, opts)
53
53
54 def _trusted(self, fp, f):
54 def _trusted(self, fp, f):
55 st = util.fstat(fp)
55 st = util.fstat(fp)
56 if util.isowner(st):
56 if util.isowner(st):
57 return True
57 return True
58
58
59 tusers, tgroups = self._trustusers, self._trustgroups
59 tusers, tgroups = self._trustusers, self._trustgroups
60 if '*' in tusers or '*' in tgroups:
60 if '*' in tusers or '*' in tgroups:
61 return True
61 return True
62
62
63 user = util.username(st.st_uid)
63 user = util.username(st.st_uid)
64 group = util.groupname(st.st_gid)
64 group = util.groupname(st.st_gid)
65 if user in tusers or group in tgroups or user == util.username():
65 if user in tusers or group in tgroups or user == util.username():
66 return True
66 return True
67
67
68 if self._reportuntrusted:
68 if self._reportuntrusted:
69 self.warn(_('not trusting file %s from untrusted '
69 self.warn(_('not trusting file %s from untrusted '
70 'user %s, group %s\n') % (f, user, group))
70 'user %s, group %s\n') % (f, user, group))
71 return False
71 return False
72
72
73 def readconfig(self, filename, root=None, trust=False,
73 def readconfig(self, filename, root=None, trust=False,
74 sections=None, remap=None):
74 sections=None, remap=None):
75 try:
75 try:
76 fp = open(filename)
76 fp = open(filename)
77 except IOError:
77 except IOError:
78 if not sections: # ignore unless we were looking for something
78 if not sections: # ignore unless we were looking for something
79 return
79 return
80 raise
80 raise
81
81
82 cfg = config.config()
82 cfg = config.config()
83 trusted = sections or trust or self._trusted(fp, filename)
83 trusted = sections or trust or self._trusted(fp, filename)
84
84
85 try:
85 try:
86 cfg.read(filename, fp, sections=sections, remap=remap)
86 cfg.read(filename, fp, sections=sections, remap=remap)
87 fp.close()
87 fp.close()
88 except error.ConfigError, inst:
88 except error.ConfigError, inst:
89 if trusted:
89 if trusted:
90 raise
90 raise
91 self.warn(_("ignored: %s\n") % str(inst))
91 self.warn(_("ignored: %s\n") % str(inst))
92
92
93 if self.plain():
93 if self.plain():
94 for k in ('debug', 'fallbackencoding', 'quiet', 'slash',
94 for k in ('debug', 'fallbackencoding', 'quiet', 'slash',
95 'logtemplate', 'style',
95 'logtemplate', 'style',
96 'traceback', 'verbose'):
96 'traceback', 'verbose'):
97 if k in cfg['ui']:
97 if k in cfg['ui']:
98 del cfg['ui'][k]
98 del cfg['ui'][k]
99 for k, v in cfg.items('defaults'):
99 for k, v in cfg.items('defaults'):
100 del cfg['defaults'][k]
100 del cfg['defaults'][k]
101 # Don't remove aliases from the configuration if in the exceptionlist
101 # Don't remove aliases from the configuration if in the exceptionlist
102 if self.plain('alias'):
102 if self.plain('alias'):
103 for k, v in cfg.items('alias'):
103 for k, v in cfg.items('alias'):
104 del cfg['alias'][k]
104 del cfg['alias'][k]
105
105
106 if trusted:
106 if trusted:
107 self._tcfg.update(cfg)
107 self._tcfg.update(cfg)
108 self._tcfg.update(self._ocfg)
108 self._tcfg.update(self._ocfg)
109 self._ucfg.update(cfg)
109 self._ucfg.update(cfg)
110 self._ucfg.update(self._ocfg)
110 self._ucfg.update(self._ocfg)
111
111
112 if root is None:
112 if root is None:
113 root = os.path.expanduser('~')
113 root = os.path.expanduser('~')
114 self.fixconfig(root=root)
114 self.fixconfig(root=root)
115
115
116 def fixconfig(self, root=None, section=None):
116 def fixconfig(self, root=None, section=None):
117 if section in (None, 'paths'):
117 if section in (None, 'paths'):
118 # expand vars and ~
118 # expand vars and ~
119 # translate paths relative to root (or home) into absolute paths
119 # translate paths relative to root (or home) into absolute paths
120 root = root or os.getcwd()
120 root = root or os.getcwd()
121 for c in self._tcfg, self._ucfg, self._ocfg:
121 for c in self._tcfg, self._ucfg, self._ocfg:
122 for n, p in c.items('paths'):
122 for n, p in c.items('paths'):
123 if not p:
123 if not p:
124 continue
124 continue
125 if '%%' in p:
125 if '%%' in p:
126 self.warn(_("(deprecated '%%' in path %s=%s from %s)\n")
126 self.warn(_("(deprecated '%%' in path %s=%s from %s)\n")
127 % (n, p, self.configsource('paths', n)))
127 % (n, p, self.configsource('paths', n)))
128 p = p.replace('%%', '%')
128 p = p.replace('%%', '%')
129 p = util.expandpath(p)
129 p = util.expandpath(p)
130 if not util.hasscheme(p) and not os.path.isabs(p):
130 if not util.hasscheme(p) and not os.path.isabs(p):
131 p = os.path.normpath(os.path.join(root, p))
131 p = os.path.normpath(os.path.join(root, p))
132 c.set("paths", n, p)
132 c.set("paths", n, p)
133
133
134 if section in (None, 'ui'):
134 if section in (None, 'ui'):
135 # update ui options
135 # update ui options
136 self.debugflag = self.configbool('ui', 'debug')
136 self.debugflag = self.configbool('ui', 'debug')
137 self.verbose = self.debugflag or self.configbool('ui', 'verbose')
137 self.verbose = self.debugflag or self.configbool('ui', 'verbose')
138 self.quiet = not self.debugflag and self.configbool('ui', 'quiet')
138 self.quiet = not self.debugflag and self.configbool('ui', 'quiet')
139 if self.verbose and self.quiet:
139 if self.verbose and self.quiet:
140 self.quiet = self.verbose = False
140 self.quiet = self.verbose = False
141 self._reportuntrusted = self.debugflag or self.configbool("ui",
141 self._reportuntrusted = self.debugflag or self.configbool("ui",
142 "report_untrusted", True)
142 "report_untrusted", True)
143 self.tracebackflag = self.configbool('ui', 'traceback', False)
143 self.tracebackflag = self.configbool('ui', 'traceback', False)
144
144
145 if section in (None, 'trusted'):
145 if section in (None, 'trusted'):
146 # update trust information
146 # update trust information
147 self._trustusers.update(self.configlist('trusted', 'users'))
147 self._trustusers.update(self.configlist('trusted', 'users'))
148 self._trustgroups.update(self.configlist('trusted', 'groups'))
148 self._trustgroups.update(self.configlist('trusted', 'groups'))
149
149
150 def backupconfig(self, section, item):
150 def backupconfig(self, section, item):
151 return (self._ocfg.backup(section, item),
151 return (self._ocfg.backup(section, item),
152 self._tcfg.backup(section, item),
152 self._tcfg.backup(section, item),
153 self._ucfg.backup(section, item),)
153 self._ucfg.backup(section, item),)
154 def restoreconfig(self, data):
154 def restoreconfig(self, data):
155 self._ocfg.restore(data[0])
155 self._ocfg.restore(data[0])
156 self._tcfg.restore(data[1])
156 self._tcfg.restore(data[1])
157 self._ucfg.restore(data[2])
157 self._ucfg.restore(data[2])
158
158
159 def setconfig(self, section, name, value, overlay=True):
159 def setconfig(self, section, name, value, overlay=True):
160 if overlay:
160 if overlay:
161 self._ocfg.set(section, name, value)
161 self._ocfg.set(section, name, value)
162 self._tcfg.set(section, name, value)
162 self._tcfg.set(section, name, value)
163 self._ucfg.set(section, name, value)
163 self._ucfg.set(section, name, value)
164 self.fixconfig(section=section)
164 self.fixconfig(section=section)
165
165
166 def _data(self, untrusted):
166 def _data(self, untrusted):
167 return untrusted and self._ucfg or self._tcfg
167 return untrusted and self._ucfg or self._tcfg
168
168
169 def configsource(self, section, name, untrusted=False):
169 def configsource(self, section, name, untrusted=False):
170 return self._data(untrusted).source(section, name) or 'none'
170 return self._data(untrusted).source(section, name) or 'none'
171
171
172 def config(self, section, name, default=None, untrusted=False):
172 def config(self, section, name, default=None, untrusted=False):
173 if isinstance(name, list):
173 if isinstance(name, list):
174 alternates = name
174 alternates = name
175 else:
175 else:
176 alternates = [name]
176 alternates = [name]
177
177
178 for n in alternates:
178 for n in alternates:
179 value = self._data(untrusted).get(section, n, None)
179 value = self._data(untrusted).get(section, n, None)
180 if value is not None:
180 if value is not None:
181 name = n
181 name = n
182 break
182 break
183 else:
183 else:
184 value = default
184 value = default
185
185
186 if self.debugflag and not untrusted and self._reportuntrusted:
186 if self.debugflag and not untrusted and self._reportuntrusted:
187 for n in alternates:
187 for n in alternates:
188 uvalue = self._ucfg.get(section, n)
188 uvalue = self._ucfg.get(section, n)
189 if uvalue is not None and uvalue != value:
189 if uvalue is not None and uvalue != value:
190 self.debug("ignoring untrusted configuration option "
190 self.debug("ignoring untrusted configuration option "
191 "%s.%s = %s\n" % (section, n, uvalue))
191 "%s.%s = %s\n" % (section, n, uvalue))
192 return value
192 return value
193
193
194 def configpath(self, section, name, default=None, untrusted=False):
194 def configpath(self, section, name, default=None, untrusted=False):
195 'get a path config item, expanded relative to repo root or config file'
195 'get a path config item, expanded relative to repo root or config file'
196 v = self.config(section, name, default, untrusted)
196 v = self.config(section, name, default, untrusted)
197 if v is None:
197 if v is None:
198 return None
198 return None
199 if not os.path.isabs(v) or "://" not in v:
199 if not os.path.isabs(v) or "://" not in v:
200 src = self.configsource(section, name, untrusted)
200 src = self.configsource(section, name, untrusted)
201 if ':' in src:
201 if ':' in src:
202 base = os.path.dirname(src.rsplit(':')[0])
202 base = os.path.dirname(src.rsplit(':')[0])
203 v = os.path.join(base, os.path.expanduser(v))
203 v = os.path.join(base, os.path.expanduser(v))
204 return v
204 return v
205
205
206 def configbool(self, section, name, default=False, untrusted=False):
206 def configbool(self, section, name, default=False, untrusted=False):
207 """parse a configuration element as a boolean
207 """parse a configuration element as a boolean
208
208
209 >>> u = ui(); s = 'foo'
209 >>> u = ui(); s = 'foo'
210 >>> u.setconfig(s, 'true', 'yes')
210 >>> u.setconfig(s, 'true', 'yes')
211 >>> u.configbool(s, 'true')
211 >>> u.configbool(s, 'true')
212 True
212 True
213 >>> u.setconfig(s, 'false', 'no')
213 >>> u.setconfig(s, 'false', 'no')
214 >>> u.configbool(s, 'false')
214 >>> u.configbool(s, 'false')
215 False
215 False
216 >>> u.configbool(s, 'unknown')
216 >>> u.configbool(s, 'unknown')
217 False
217 False
218 >>> u.configbool(s, 'unknown', True)
218 >>> u.configbool(s, 'unknown', True)
219 True
219 True
220 >>> u.setconfig(s, 'invalid', 'somevalue')
220 >>> u.setconfig(s, 'invalid', 'somevalue')
221 >>> u.configbool(s, 'invalid')
221 >>> u.configbool(s, 'invalid')
222 Traceback (most recent call last):
222 Traceback (most recent call last):
223 ...
223 ...
224 ConfigError: foo.invalid is not a boolean ('somevalue')
224 ConfigError: foo.invalid is not a boolean ('somevalue')
225 """
225 """
226
226
227 v = self.config(section, name, None, untrusted)
227 v = self.config(section, name, None, untrusted)
228 if v is None:
228 if v is None:
229 return default
229 return default
230 if isinstance(v, bool):
230 if isinstance(v, bool):
231 return v
231 return v
232 b = util.parsebool(v)
232 b = util.parsebool(v)
233 if b is None:
233 if b is None:
234 raise error.ConfigError(_("%s.%s is not a boolean ('%s')")
234 raise error.ConfigError(_("%s.%s is not a boolean ('%s')")
235 % (section, name, v))
235 % (section, name, v))
236 return b
236 return b
237
237
238 def configint(self, section, name, default=None, untrusted=False):
238 def configint(self, section, name, default=None, untrusted=False):
239 """parse a configuration element as an integer
239 """parse a configuration element as an integer
240
240
241 >>> u = ui(); s = 'foo'
241 >>> u = ui(); s = 'foo'
242 >>> u.setconfig(s, 'int1', '42')
242 >>> u.setconfig(s, 'int1', '42')
243 >>> u.configint(s, 'int1')
243 >>> u.configint(s, 'int1')
244 42
244 42
245 >>> u.setconfig(s, 'int2', '-42')
245 >>> u.setconfig(s, 'int2', '-42')
246 >>> u.configint(s, 'int2')
246 >>> u.configint(s, 'int2')
247 -42
247 -42
248 >>> u.configint(s, 'unknown', 7)
248 >>> u.configint(s, 'unknown', 7)
249 7
249 7
250 >>> u.setconfig(s, 'invalid', 'somevalue')
250 >>> u.setconfig(s, 'invalid', 'somevalue')
251 >>> u.configint(s, 'invalid')
251 >>> u.configint(s, 'invalid')
252 Traceback (most recent call last):
252 Traceback (most recent call last):
253 ...
253 ...
254 ConfigError: foo.invalid is not an integer ('somevalue')
254 ConfigError: foo.invalid is not an integer ('somevalue')
255 """
255 """
256
256
257 v = self.config(section, name, None, untrusted)
257 v = self.config(section, name, None, untrusted)
258 if v is None:
258 if v is None:
259 return default
259 return default
260 try:
260 try:
261 return int(v)
261 return int(v)
262 except ValueError:
262 except ValueError:
263 raise error.ConfigError(_("%s.%s is not an integer ('%s')")
263 raise error.ConfigError(_("%s.%s is not an integer ('%s')")
264 % (section, name, v))
264 % (section, name, v))
265
265
266 def configbytes(self, section, name, default=0, untrusted=False):
266 def configbytes(self, section, name, default=0, untrusted=False):
267 """parse a configuration element as a quantity in bytes
267 """parse a configuration element as a quantity in bytes
268
268
269 Units can be specified as b (bytes), k or kb (kilobytes), m or
269 Units can be specified as b (bytes), k or kb (kilobytes), m or
270 mb (megabytes), g or gb (gigabytes).
270 mb (megabytes), g or gb (gigabytes).
271
271
272 >>> u = ui(); s = 'foo'
272 >>> u = ui(); s = 'foo'
273 >>> u.setconfig(s, 'val1', '42')
273 >>> u.setconfig(s, 'val1', '42')
274 >>> u.configbytes(s, 'val1')
274 >>> u.configbytes(s, 'val1')
275 42
275 42
276 >>> u.setconfig(s, 'val2', '42.5 kb')
276 >>> u.setconfig(s, 'val2', '42.5 kb')
277 >>> u.configbytes(s, 'val2')
277 >>> u.configbytes(s, 'val2')
278 43520
278 43520
279 >>> u.configbytes(s, 'unknown', '7 MB')
279 >>> u.configbytes(s, 'unknown', '7 MB')
280 7340032
280 7340032
281 >>> u.setconfig(s, 'invalid', 'somevalue')
281 >>> u.setconfig(s, 'invalid', 'somevalue')
282 >>> u.configbytes(s, 'invalid')
282 >>> u.configbytes(s, 'invalid')
283 Traceback (most recent call last):
283 Traceback (most recent call last):
284 ...
284 ...
285 ConfigError: foo.invalid is not a byte quantity ('somevalue')
285 ConfigError: foo.invalid is not a byte quantity ('somevalue')
286 """
286 """
287
287
288 value = self.config(section, name)
288 value = self.config(section, name)
289 if value is None:
289 if value is None:
290 if not isinstance(default, str):
290 if not isinstance(default, str):
291 return default
291 return default
292 value = default
292 value = default
293 try:
293 try:
294 return util.sizetoint(value)
294 return util.sizetoint(value)
295 except error.ParseError:
295 except error.ParseError:
296 raise error.ConfigError(_("%s.%s is not a byte quantity ('%s')")
296 raise error.ConfigError(_("%s.%s is not a byte quantity ('%s')")
297 % (section, name, value))
297 % (section, name, value))
298
298
299 def configlist(self, section, name, default=None, untrusted=False):
299 def configlist(self, section, name, default=None, untrusted=False):
300 """parse a configuration element as a list of comma/space separated
300 """parse a configuration element as a list of comma/space separated
301 strings
301 strings
302
302
303 >>> u = ui(); s = 'foo'
303 >>> u = ui(); s = 'foo'
304 >>> u.setconfig(s, 'list1', 'this,is "a small" ,test')
304 >>> u.setconfig(s, 'list1', 'this,is "a small" ,test')
305 >>> u.configlist(s, 'list1')
305 >>> u.configlist(s, 'list1')
306 ['this', 'is', 'a small', 'test']
306 ['this', 'is', 'a small', 'test']
307 """
307 """
308
308
309 def _parse_plain(parts, s, offset):
309 def _parse_plain(parts, s, offset):
310 whitespace = False
310 whitespace = False
311 while offset < len(s) and (s[offset].isspace() or s[offset] == ','):
311 while offset < len(s) and (s[offset].isspace() or s[offset] == ','):
312 whitespace = True
312 whitespace = True
313 offset += 1
313 offset += 1
314 if offset >= len(s):
314 if offset >= len(s):
315 return None, parts, offset
315 return None, parts, offset
316 if whitespace:
316 if whitespace:
317 parts.append('')
317 parts.append('')
318 if s[offset] == '"' and not parts[-1]:
318 if s[offset] == '"' and not parts[-1]:
319 return _parse_quote, parts, offset + 1
319 return _parse_quote, parts, offset + 1
320 elif s[offset] == '"' and parts[-1][-1] == '\\':
320 elif s[offset] == '"' and parts[-1][-1] == '\\':
321 parts[-1] = parts[-1][:-1] + s[offset]
321 parts[-1] = parts[-1][:-1] + s[offset]
322 return _parse_plain, parts, offset + 1
322 return _parse_plain, parts, offset + 1
323 parts[-1] += s[offset]
323 parts[-1] += s[offset]
324 return _parse_plain, parts, offset + 1
324 return _parse_plain, parts, offset + 1
325
325
326 def _parse_quote(parts, s, offset):
326 def _parse_quote(parts, s, offset):
327 if offset < len(s) and s[offset] == '"': # ""
327 if offset < len(s) and s[offset] == '"': # ""
328 parts.append('')
328 parts.append('')
329 offset += 1
329 offset += 1
330 while offset < len(s) and (s[offset].isspace() or
330 while offset < len(s) and (s[offset].isspace() or
331 s[offset] == ','):
331 s[offset] == ','):
332 offset += 1
332 offset += 1
333 return _parse_plain, parts, offset
333 return _parse_plain, parts, offset
334
334
335 while offset < len(s) and s[offset] != '"':
335 while offset < len(s) and s[offset] != '"':
336 if (s[offset] == '\\' and offset + 1 < len(s)
336 if (s[offset] == '\\' and offset + 1 < len(s)
337 and s[offset + 1] == '"'):
337 and s[offset + 1] == '"'):
338 offset += 1
338 offset += 1
339 parts[-1] += '"'
339 parts[-1] += '"'
340 else:
340 else:
341 parts[-1] += s[offset]
341 parts[-1] += s[offset]
342 offset += 1
342 offset += 1
343
343
344 if offset >= len(s):
344 if offset >= len(s):
345 real_parts = _configlist(parts[-1])
345 real_parts = _configlist(parts[-1])
346 if not real_parts:
346 if not real_parts:
347 parts[-1] = '"'
347 parts[-1] = '"'
348 else:
348 else:
349 real_parts[0] = '"' + real_parts[0]
349 real_parts[0] = '"' + real_parts[0]
350 parts = parts[:-1]
350 parts = parts[:-1]
351 parts.extend(real_parts)
351 parts.extend(real_parts)
352 return None, parts, offset
352 return None, parts, offset
353
353
354 offset += 1
354 offset += 1
355 while offset < len(s) and s[offset] in [' ', ',']:
355 while offset < len(s) and s[offset] in [' ', ',']:
356 offset += 1
356 offset += 1
357
357
358 if offset < len(s):
358 if offset < len(s):
359 if offset + 1 == len(s) and s[offset] == '"':
359 if offset + 1 == len(s) and s[offset] == '"':
360 parts[-1] += '"'
360 parts[-1] += '"'
361 offset += 1
361 offset += 1
362 else:
362 else:
363 parts.append('')
363 parts.append('')
364 else:
364 else:
365 return None, parts, offset
365 return None, parts, offset
366
366
367 return _parse_plain, parts, offset
367 return _parse_plain, parts, offset
368
368
369 def _configlist(s):
369 def _configlist(s):
370 s = s.rstrip(' ,')
370 s = s.rstrip(' ,')
371 if not s:
371 if not s:
372 return []
372 return []
373 parser, parts, offset = _parse_plain, [''], 0
373 parser, parts, offset = _parse_plain, [''], 0
374 while parser:
374 while parser:
375 parser, parts, offset = parser(parts, s, offset)
375 parser, parts, offset = parser(parts, s, offset)
376 return parts
376 return parts
377
377
378 result = self.config(section, name, untrusted=untrusted)
378 result = self.config(section, name, untrusted=untrusted)
379 if result is None:
379 if result is None:
380 result = default or []
380 result = default or []
381 if isinstance(result, basestring):
381 if isinstance(result, basestring):
382 result = _configlist(result.lstrip(' ,\n'))
382 result = _configlist(result.lstrip(' ,\n'))
383 if result is None:
383 if result is None:
384 result = default or []
384 result = default or []
385 return result
385 return result
386
386
387 def has_section(self, section, untrusted=False):
387 def has_section(self, section, untrusted=False):
388 '''tell whether section exists in config.'''
388 '''tell whether section exists in config.'''
389 return section in self._data(untrusted)
389 return section in self._data(untrusted)
390
390
391 def configitems(self, section, untrusted=False):
391 def configitems(self, section, untrusted=False):
392 items = self._data(untrusted).items(section)
392 items = self._data(untrusted).items(section)
393 if self.debugflag and not untrusted and self._reportuntrusted:
393 if self.debugflag and not untrusted and self._reportuntrusted:
394 for k, v in self._ucfg.items(section):
394 for k, v in self._ucfg.items(section):
395 if self._tcfg.get(section, k) != v:
395 if self._tcfg.get(section, k) != v:
396 self.debug("ignoring untrusted configuration option "
396 self.debug("ignoring untrusted configuration option "
397 "%s.%s = %s\n" % (section, k, v))
397 "%s.%s = %s\n" % (section, k, v))
398 return items
398 return items
399
399
400 def walkconfig(self, untrusted=False):
400 def walkconfig(self, untrusted=False):
401 cfg = self._data(untrusted)
401 cfg = self._data(untrusted)
402 for section in cfg.sections():
402 for section in cfg.sections():
403 for name, value in self.configitems(section, untrusted):
403 for name, value in self.configitems(section, untrusted):
404 yield section, name, value
404 yield section, name, value
405
405
406 def plain(self, feature=None):
406 def plain(self, feature=None):
407 '''is plain mode active?
407 '''is plain mode active?
408
408
409 Plain mode means that all configuration variables which affect
409 Plain mode means that all configuration variables which affect
410 the behavior and output of Mercurial should be
410 the behavior and output of Mercurial should be
411 ignored. Additionally, the output should be stable,
411 ignored. Additionally, the output should be stable,
412 reproducible and suitable for use in scripts or applications.
412 reproducible and suitable for use in scripts or applications.
413
413
414 The only way to trigger plain mode is by setting either the
414 The only way to trigger plain mode is by setting either the
415 `HGPLAIN' or `HGPLAINEXCEPT' environment variables.
415 `HGPLAIN' or `HGPLAINEXCEPT' environment variables.
416
416
417 The return value can either be
417 The return value can either be
418 - False if HGPLAIN is not set, or feature is in HGPLAINEXCEPT
418 - False if HGPLAIN is not set, or feature is in HGPLAINEXCEPT
419 - True otherwise
419 - True otherwise
420 '''
420 '''
421 if 'HGPLAIN' not in os.environ and 'HGPLAINEXCEPT' not in os.environ:
421 if 'HGPLAIN' not in os.environ and 'HGPLAINEXCEPT' not in os.environ:
422 return False
422 return False
423 exceptions = os.environ.get('HGPLAINEXCEPT', '').strip().split(',')
423 exceptions = os.environ.get('HGPLAINEXCEPT', '').strip().split(',')
424 if feature and exceptions:
424 if feature and exceptions:
425 return feature not in exceptions
425 return feature not in exceptions
426 return True
426 return True
427
427
428 def username(self):
428 def username(self):
429 """Return default username to be used in commits.
429 """Return default username to be used in commits.
430
430
431 Searched in this order: $HGUSER, [ui] section of hgrcs, $EMAIL
431 Searched in this order: $HGUSER, [ui] section of hgrcs, $EMAIL
432 and stop searching if one of these is set.
432 and stop searching if one of these is set.
433 If not found and ui.askusername is True, ask the user, else use
433 If not found and ui.askusername is True, ask the user, else use
434 ($LOGNAME or $USER or $LNAME or $USERNAME) + "@full.hostname".
434 ($LOGNAME or $USER or $LNAME or $USERNAME) + "@full.hostname".
435 """
435 """
436 user = os.environ.get("HGUSER")
436 user = os.environ.get("HGUSER")
437 if user is None:
437 if user is None:
438 user = self.config("ui", "username")
438 user = self.config("ui", "username")
439 if user is not None:
439 if user is not None:
440 user = os.path.expandvars(user)
440 user = os.path.expandvars(user)
441 if user is None:
441 if user is None:
442 user = os.environ.get("EMAIL")
442 user = os.environ.get("EMAIL")
443 if user is None and self.configbool("ui", "askusername"):
443 if user is None and self.configbool("ui", "askusername"):
444 user = self.prompt(_("enter a commit username:"), default=None)
444 user = self.prompt(_("enter a commit username:"), default=None)
445 if user is None and not self.interactive():
445 if user is None and not self.interactive():
446 try:
446 try:
447 user = '%s@%s' % (util.getuser(), socket.getfqdn())
447 user = '%s@%s' % (util.getuser(), socket.getfqdn())
448 self.warn(_("no username found, using '%s' instead\n") % user)
448 self.warn(_("no username found, using '%s' instead\n") % user)
449 except KeyError:
449 except KeyError:
450 pass
450 pass
451 if not user:
451 if not user:
452 raise util.Abort(_('no username supplied'),
452 raise util.Abort(_('no username supplied'),
453 hint=_('use "hg config --edit" '
453 hint=_('use "hg config --edit" '
454 ' to set your username'))
454 'to set your username'))
455 if "\n" in user:
455 if "\n" in user:
456 raise util.Abort(_("username %s contains a newline\n") % repr(user))
456 raise util.Abort(_("username %s contains a newline\n") % repr(user))
457 return user
457 return user
458
458
459 def shortuser(self, user):
459 def shortuser(self, user):
460 """Return a short representation of a user name or email address."""
460 """Return a short representation of a user name or email address."""
461 if not self.verbose:
461 if not self.verbose:
462 user = util.shortuser(user)
462 user = util.shortuser(user)
463 return user
463 return user
464
464
465 def expandpath(self, loc, default=None):
465 def expandpath(self, loc, default=None):
466 """Return repository location relative to cwd or from [paths]"""
466 """Return repository location relative to cwd or from [paths]"""
467 if util.hasscheme(loc) or os.path.isdir(os.path.join(loc, '.hg')):
467 if util.hasscheme(loc) or os.path.isdir(os.path.join(loc, '.hg')):
468 return loc
468 return loc
469
469
470 path = self.config('paths', loc)
470 path = self.config('paths', loc)
471 if not path and default is not None:
471 if not path and default is not None:
472 path = self.config('paths', default)
472 path = self.config('paths', default)
473 return path or loc
473 return path or loc
474
474
475 def pushbuffer(self):
475 def pushbuffer(self):
476 self._buffers.append([])
476 self._buffers.append([])
477
477
478 def popbuffer(self, labeled=False):
478 def popbuffer(self, labeled=False):
479 '''pop the last buffer and return the buffered output
479 '''pop the last buffer and return the buffered output
480
480
481 If labeled is True, any labels associated with buffered
481 If labeled is True, any labels associated with buffered
482 output will be handled. By default, this has no effect
482 output will be handled. By default, this has no effect
483 on the output returned, but extensions and GUI tools may
483 on the output returned, but extensions and GUI tools may
484 handle this argument and returned styled output. If output
484 handle this argument and returned styled output. If output
485 is being buffered so it can be captured and parsed or
485 is being buffered so it can be captured and parsed or
486 processed, labeled should not be set to True.
486 processed, labeled should not be set to True.
487 '''
487 '''
488 return "".join(self._buffers.pop())
488 return "".join(self._buffers.pop())
489
489
490 def write(self, *args, **opts):
490 def write(self, *args, **opts):
491 '''write args to output
491 '''write args to output
492
492
493 By default, this method simply writes to the buffer or stdout,
493 By default, this method simply writes to the buffer or stdout,
494 but extensions or GUI tools may override this method,
494 but extensions or GUI tools may override this method,
495 write_err(), popbuffer(), and label() to style output from
495 write_err(), popbuffer(), and label() to style output from
496 various parts of hg.
496 various parts of hg.
497
497
498 An optional keyword argument, "label", can be passed in.
498 An optional keyword argument, "label", can be passed in.
499 This should be a string containing label names separated by
499 This should be a string containing label names separated by
500 space. Label names take the form of "topic.type". For example,
500 space. Label names take the form of "topic.type". For example,
501 ui.debug() issues a label of "ui.debug".
501 ui.debug() issues a label of "ui.debug".
502
502
503 When labeling output for a specific command, a label of
503 When labeling output for a specific command, a label of
504 "cmdname.type" is recommended. For example, status issues
504 "cmdname.type" is recommended. For example, status issues
505 a label of "status.modified" for modified files.
505 a label of "status.modified" for modified files.
506 '''
506 '''
507 if self._buffers:
507 if self._buffers:
508 self._buffers[-1].extend([str(a) for a in args])
508 self._buffers[-1].extend([str(a) for a in args])
509 else:
509 else:
510 for a in args:
510 for a in args:
511 self.fout.write(str(a))
511 self.fout.write(str(a))
512
512
513 def write_err(self, *args, **opts):
513 def write_err(self, *args, **opts):
514 try:
514 try:
515 if not getattr(self.fout, 'closed', False):
515 if not getattr(self.fout, 'closed', False):
516 self.fout.flush()
516 self.fout.flush()
517 for a in args:
517 for a in args:
518 self.ferr.write(str(a))
518 self.ferr.write(str(a))
519 # stderr may be buffered under win32 when redirected to files,
519 # stderr may be buffered under win32 when redirected to files,
520 # including stdout.
520 # including stdout.
521 if not getattr(self.ferr, 'closed', False):
521 if not getattr(self.ferr, 'closed', False):
522 self.ferr.flush()
522 self.ferr.flush()
523 except IOError, inst:
523 except IOError, inst:
524 if inst.errno not in (errno.EPIPE, errno.EIO, errno.EBADF):
524 if inst.errno not in (errno.EPIPE, errno.EIO, errno.EBADF):
525 raise
525 raise
526
526
527 def flush(self):
527 def flush(self):
528 try: self.fout.flush()
528 try: self.fout.flush()
529 except (IOError, ValueError): pass
529 except (IOError, ValueError): pass
530 try: self.ferr.flush()
530 try: self.ferr.flush()
531 except (IOError, ValueError): pass
531 except (IOError, ValueError): pass
532
532
533 def _isatty(self, fh):
533 def _isatty(self, fh):
534 if self.configbool('ui', 'nontty', False):
534 if self.configbool('ui', 'nontty', False):
535 return False
535 return False
536 return util.isatty(fh)
536 return util.isatty(fh)
537
537
538 def interactive(self):
538 def interactive(self):
539 '''is interactive input allowed?
539 '''is interactive input allowed?
540
540
541 An interactive session is a session where input can be reasonably read
541 An interactive session is a session where input can be reasonably read
542 from `sys.stdin'. If this function returns false, any attempt to read
542 from `sys.stdin'. If this function returns false, any attempt to read
543 from stdin should fail with an error, unless a sensible default has been
543 from stdin should fail with an error, unless a sensible default has been
544 specified.
544 specified.
545
545
546 Interactiveness is triggered by the value of the `ui.interactive'
546 Interactiveness is triggered by the value of the `ui.interactive'
547 configuration variable or - if it is unset - when `sys.stdin' points
547 configuration variable or - if it is unset - when `sys.stdin' points
548 to a terminal device.
548 to a terminal device.
549
549
550 This function refers to input only; for output, see `ui.formatted()'.
550 This function refers to input only; for output, see `ui.formatted()'.
551 '''
551 '''
552 i = self.configbool("ui", "interactive", None)
552 i = self.configbool("ui", "interactive", None)
553 if i is None:
553 if i is None:
554 # some environments replace stdin without implementing isatty
554 # some environments replace stdin without implementing isatty
555 # usually those are non-interactive
555 # usually those are non-interactive
556 return self._isatty(self.fin)
556 return self._isatty(self.fin)
557
557
558 return i
558 return i
559
559
560 def termwidth(self):
560 def termwidth(self):
561 '''how wide is the terminal in columns?
561 '''how wide is the terminal in columns?
562 '''
562 '''
563 if 'COLUMNS' in os.environ:
563 if 'COLUMNS' in os.environ:
564 try:
564 try:
565 return int(os.environ['COLUMNS'])
565 return int(os.environ['COLUMNS'])
566 except ValueError:
566 except ValueError:
567 pass
567 pass
568 return util.termwidth()
568 return util.termwidth()
569
569
570 def formatted(self):
570 def formatted(self):
571 '''should formatted output be used?
571 '''should formatted output be used?
572
572
573 It is often desirable to format the output to suite the output medium.
573 It is often desirable to format the output to suite the output medium.
574 Examples of this are truncating long lines or colorizing messages.
574 Examples of this are truncating long lines or colorizing messages.
575 However, this is not often not desirable when piping output into other
575 However, this is not often not desirable when piping output into other
576 utilities, e.g. `grep'.
576 utilities, e.g. `grep'.
577
577
578 Formatted output is triggered by the value of the `ui.formatted'
578 Formatted output is triggered by the value of the `ui.formatted'
579 configuration variable or - if it is unset - when `sys.stdout' points
579 configuration variable or - if it is unset - when `sys.stdout' points
580 to a terminal device. Please note that `ui.formatted' should be
580 to a terminal device. Please note that `ui.formatted' should be
581 considered an implementation detail; it is not intended for use outside
581 considered an implementation detail; it is not intended for use outside
582 Mercurial or its extensions.
582 Mercurial or its extensions.
583
583
584 This function refers to output only; for input, see `ui.interactive()'.
584 This function refers to output only; for input, see `ui.interactive()'.
585 This function always returns false when in plain mode, see `ui.plain()'.
585 This function always returns false when in plain mode, see `ui.plain()'.
586 '''
586 '''
587 if self.plain():
587 if self.plain():
588 return False
588 return False
589
589
590 i = self.configbool("ui", "formatted", None)
590 i = self.configbool("ui", "formatted", None)
591 if i is None:
591 if i is None:
592 # some environments replace stdout without implementing isatty
592 # some environments replace stdout without implementing isatty
593 # usually those are non-interactive
593 # usually those are non-interactive
594 return self._isatty(self.fout)
594 return self._isatty(self.fout)
595
595
596 return i
596 return i
597
597
598 def _readline(self, prompt=''):
598 def _readline(self, prompt=''):
599 if self._isatty(self.fin):
599 if self._isatty(self.fin):
600 try:
600 try:
601 # magically add command line editing support, where
601 # magically add command line editing support, where
602 # available
602 # available
603 import readline
603 import readline
604 # force demandimport to really load the module
604 # force demandimport to really load the module
605 readline.read_history_file
605 readline.read_history_file
606 # windows sometimes raises something other than ImportError
606 # windows sometimes raises something other than ImportError
607 except Exception:
607 except Exception:
608 pass
608 pass
609
609
610 # call write() so output goes through subclassed implementation
610 # call write() so output goes through subclassed implementation
611 # e.g. color extension on Windows
611 # e.g. color extension on Windows
612 self.write(prompt)
612 self.write(prompt)
613
613
614 # instead of trying to emulate raw_input, swap (self.fin,
614 # instead of trying to emulate raw_input, swap (self.fin,
615 # self.fout) with (sys.stdin, sys.stdout)
615 # self.fout) with (sys.stdin, sys.stdout)
616 oldin = sys.stdin
616 oldin = sys.stdin
617 oldout = sys.stdout
617 oldout = sys.stdout
618 sys.stdin = self.fin
618 sys.stdin = self.fin
619 sys.stdout = self.fout
619 sys.stdout = self.fout
620 line = raw_input(' ')
620 line = raw_input(' ')
621 sys.stdin = oldin
621 sys.stdin = oldin
622 sys.stdout = oldout
622 sys.stdout = oldout
623
623
624 # When stdin is in binary mode on Windows, it can cause
624 # When stdin is in binary mode on Windows, it can cause
625 # raw_input() to emit an extra trailing carriage return
625 # raw_input() to emit an extra trailing carriage return
626 if os.linesep == '\r\n' and line and line[-1] == '\r':
626 if os.linesep == '\r\n' and line and line[-1] == '\r':
627 line = line[:-1]
627 line = line[:-1]
628 return line
628 return line
629
629
630 def prompt(self, msg, default="y"):
630 def prompt(self, msg, default="y"):
631 """Prompt user with msg, read response.
631 """Prompt user with msg, read response.
632 If ui is not interactive, the default is returned.
632 If ui is not interactive, the default is returned.
633 """
633 """
634 if not self.interactive():
634 if not self.interactive():
635 self.write(msg, ' ', default, "\n")
635 self.write(msg, ' ', default, "\n")
636 return default
636 return default
637 try:
637 try:
638 r = self._readline(self.label(msg, 'ui.prompt'))
638 r = self._readline(self.label(msg, 'ui.prompt'))
639 if not r:
639 if not r:
640 return default
640 return default
641 return r
641 return r
642 except EOFError:
642 except EOFError:
643 raise util.Abort(_('response expected'))
643 raise util.Abort(_('response expected'))
644
644
645 @staticmethod
645 @staticmethod
646 def extractchoices(prompt):
646 def extractchoices(prompt):
647 """Extract prompt message and list of choices from specified prompt.
647 """Extract prompt message and list of choices from specified prompt.
648
648
649 This returns tuple "(message, choices)", and "choices" is the
649 This returns tuple "(message, choices)", and "choices" is the
650 list of tuple "(response character, text without &)".
650 list of tuple "(response character, text without &)".
651 """
651 """
652 parts = prompt.split('$$')
652 parts = prompt.split('$$')
653 msg = parts[0].rstrip(' ')
653 msg = parts[0].rstrip(' ')
654 choices = [p.strip(' ') for p in parts[1:]]
654 choices = [p.strip(' ') for p in parts[1:]]
655 return (msg,
655 return (msg,
656 [(s[s.index('&') + 1].lower(), s.replace('&', '', 1))
656 [(s[s.index('&') + 1].lower(), s.replace('&', '', 1))
657 for s in choices])
657 for s in choices])
658
658
659 def promptchoice(self, prompt, default=0):
659 def promptchoice(self, prompt, default=0):
660 """Prompt user with a message, read response, and ensure it matches
660 """Prompt user with a message, read response, and ensure it matches
661 one of the provided choices. The prompt is formatted as follows:
661 one of the provided choices. The prompt is formatted as follows:
662
662
663 "would you like fries with that (Yn)? $$ &Yes $$ &No"
663 "would you like fries with that (Yn)? $$ &Yes $$ &No"
664
664
665 The index of the choice is returned. Responses are case
665 The index of the choice is returned. Responses are case
666 insensitive. If ui is not interactive, the default is
666 insensitive. If ui is not interactive, the default is
667 returned.
667 returned.
668 """
668 """
669
669
670 msg, choices = self.extractchoices(prompt)
670 msg, choices = self.extractchoices(prompt)
671 resps = [r for r, t in choices]
671 resps = [r for r, t in choices]
672 while True:
672 while True:
673 r = self.prompt(msg, resps[default])
673 r = self.prompt(msg, resps[default])
674 if r.lower() in resps:
674 if r.lower() in resps:
675 return resps.index(r.lower())
675 return resps.index(r.lower())
676 self.write(_("unrecognized response\n"))
676 self.write(_("unrecognized response\n"))
677
677
678 def getpass(self, prompt=None, default=None):
678 def getpass(self, prompt=None, default=None):
679 if not self.interactive():
679 if not self.interactive():
680 return default
680 return default
681 try:
681 try:
682 self.write_err(self.label(prompt or _('password: '), 'ui.prompt'))
682 self.write_err(self.label(prompt or _('password: '), 'ui.prompt'))
683 return getpass.getpass('')
683 return getpass.getpass('')
684 except EOFError:
684 except EOFError:
685 raise util.Abort(_('response expected'))
685 raise util.Abort(_('response expected'))
686 def status(self, *msg, **opts):
686 def status(self, *msg, **opts):
687 '''write status message to output (if ui.quiet is False)
687 '''write status message to output (if ui.quiet is False)
688
688
689 This adds an output label of "ui.status".
689 This adds an output label of "ui.status".
690 '''
690 '''
691 if not self.quiet:
691 if not self.quiet:
692 opts['label'] = opts.get('label', '') + ' ui.status'
692 opts['label'] = opts.get('label', '') + ' ui.status'
693 self.write(*msg, **opts)
693 self.write(*msg, **opts)
694 def warn(self, *msg, **opts):
694 def warn(self, *msg, **opts):
695 '''write warning message to output (stderr)
695 '''write warning message to output (stderr)
696
696
697 This adds an output label of "ui.warning".
697 This adds an output label of "ui.warning".
698 '''
698 '''
699 opts['label'] = opts.get('label', '') + ' ui.warning'
699 opts['label'] = opts.get('label', '') + ' ui.warning'
700 self.write_err(*msg, **opts)
700 self.write_err(*msg, **opts)
701 def note(self, *msg, **opts):
701 def note(self, *msg, **opts):
702 '''write note to output (if ui.verbose is True)
702 '''write note to output (if ui.verbose is True)
703
703
704 This adds an output label of "ui.note".
704 This adds an output label of "ui.note".
705 '''
705 '''
706 if self.verbose:
706 if self.verbose:
707 opts['label'] = opts.get('label', '') + ' ui.note'
707 opts['label'] = opts.get('label', '') + ' ui.note'
708 self.write(*msg, **opts)
708 self.write(*msg, **opts)
709 def debug(self, *msg, **opts):
709 def debug(self, *msg, **opts):
710 '''write debug message to output (if ui.debugflag is True)
710 '''write debug message to output (if ui.debugflag is True)
711
711
712 This adds an output label of "ui.debug".
712 This adds an output label of "ui.debug".
713 '''
713 '''
714 if self.debugflag:
714 if self.debugflag:
715 opts['label'] = opts.get('label', '') + ' ui.debug'
715 opts['label'] = opts.get('label', '') + ' ui.debug'
716 self.write(*msg, **opts)
716 self.write(*msg, **opts)
717 def edit(self, text, user):
717 def edit(self, text, user):
718 (fd, name) = tempfile.mkstemp(prefix="hg-editor-", suffix=".txt",
718 (fd, name) = tempfile.mkstemp(prefix="hg-editor-", suffix=".txt",
719 text=True)
719 text=True)
720 try:
720 try:
721 f = os.fdopen(fd, "w")
721 f = os.fdopen(fd, "w")
722 f.write(text)
722 f.write(text)
723 f.close()
723 f.close()
724
724
725 editor = self.geteditor()
725 editor = self.geteditor()
726
726
727 util.system("%s \"%s\"" % (editor, name),
727 util.system("%s \"%s\"" % (editor, name),
728 environ={'HGUSER': user},
728 environ={'HGUSER': user},
729 onerr=util.Abort, errprefix=_("edit failed"),
729 onerr=util.Abort, errprefix=_("edit failed"),
730 out=self.fout)
730 out=self.fout)
731
731
732 f = open(name)
732 f = open(name)
733 t = f.read()
733 t = f.read()
734 f.close()
734 f.close()
735 finally:
735 finally:
736 os.unlink(name)
736 os.unlink(name)
737
737
738 return t
738 return t
739
739
740 def traceback(self, exc=None, force=False):
740 def traceback(self, exc=None, force=False):
741 '''print exception traceback if traceback printing enabled or forced.
741 '''print exception traceback if traceback printing enabled or forced.
742 only to call in exception handler. returns true if traceback
742 only to call in exception handler. returns true if traceback
743 printed.'''
743 printed.'''
744 if self.tracebackflag or force:
744 if self.tracebackflag or force:
745 if exc is None:
745 if exc is None:
746 exc = sys.exc_info()
746 exc = sys.exc_info()
747 cause = getattr(exc[1], 'cause', None)
747 cause = getattr(exc[1], 'cause', None)
748
748
749 if cause is not None:
749 if cause is not None:
750 causetb = traceback.format_tb(cause[2])
750 causetb = traceback.format_tb(cause[2])
751 exctb = traceback.format_tb(exc[2])
751 exctb = traceback.format_tb(exc[2])
752 exconly = traceback.format_exception_only(cause[0], cause[1])
752 exconly = traceback.format_exception_only(cause[0], cause[1])
753
753
754 # exclude frame where 'exc' was chained and rethrown from exctb
754 # exclude frame where 'exc' was chained and rethrown from exctb
755 self.write_err('Traceback (most recent call last):\n',
755 self.write_err('Traceback (most recent call last):\n',
756 ''.join(exctb[:-1]),
756 ''.join(exctb[:-1]),
757 ''.join(causetb),
757 ''.join(causetb),
758 ''.join(exconly))
758 ''.join(exconly))
759 else:
759 else:
760 traceback.print_exception(exc[0], exc[1], exc[2],
760 traceback.print_exception(exc[0], exc[1], exc[2],
761 file=self.ferr)
761 file=self.ferr)
762 return self.tracebackflag or force
762 return self.tracebackflag or force
763
763
764 def geteditor(self):
764 def geteditor(self):
765 '''return editor to use'''
765 '''return editor to use'''
766 if sys.platform == 'plan9':
766 if sys.platform == 'plan9':
767 # vi is the MIPS instruction simulator on Plan 9. We
767 # vi is the MIPS instruction simulator on Plan 9. We
768 # instead default to E to plumb commit messages to
768 # instead default to E to plumb commit messages to
769 # avoid confusion.
769 # avoid confusion.
770 editor = 'E'
770 editor = 'E'
771 else:
771 else:
772 editor = 'vi'
772 editor = 'vi'
773 return (os.environ.get("HGEDITOR") or
773 return (os.environ.get("HGEDITOR") or
774 self.config("ui", "editor") or
774 self.config("ui", "editor") or
775 os.environ.get("VISUAL") or
775 os.environ.get("VISUAL") or
776 os.environ.get("EDITOR", editor))
776 os.environ.get("EDITOR", editor))
777
777
778 def progress(self, topic, pos, item="", unit="", total=None):
778 def progress(self, topic, pos, item="", unit="", total=None):
779 '''show a progress message
779 '''show a progress message
780
780
781 With stock hg, this is simply a debug message that is hidden
781 With stock hg, this is simply a debug message that is hidden
782 by default, but with extensions or GUI tools it may be
782 by default, but with extensions or GUI tools it may be
783 visible. 'topic' is the current operation, 'item' is a
783 visible. 'topic' is the current operation, 'item' is a
784 non-numeric marker of the current position (i.e. the currently
784 non-numeric marker of the current position (i.e. the currently
785 in-process file), 'pos' is the current numeric position (i.e.
785 in-process file), 'pos' is the current numeric position (i.e.
786 revision, bytes, etc.), unit is a corresponding unit label,
786 revision, bytes, etc.), unit is a corresponding unit label,
787 and total is the highest expected pos.
787 and total is the highest expected pos.
788
788
789 Multiple nested topics may be active at a time.
789 Multiple nested topics may be active at a time.
790
790
791 All topics should be marked closed by setting pos to None at
791 All topics should be marked closed by setting pos to None at
792 termination.
792 termination.
793 '''
793 '''
794
794
795 if pos is None or not self.debugflag:
795 if pos is None or not self.debugflag:
796 return
796 return
797
797
798 if unit:
798 if unit:
799 unit = ' ' + unit
799 unit = ' ' + unit
800 if item:
800 if item:
801 item = ' ' + item
801 item = ' ' + item
802
802
803 if total:
803 if total:
804 pct = 100.0 * pos / total
804 pct = 100.0 * pos / total
805 self.debug('%s:%s %s/%s%s (%4.2f%%)\n'
805 self.debug('%s:%s %s/%s%s (%4.2f%%)\n'
806 % (topic, item, pos, total, unit, pct))
806 % (topic, item, pos, total, unit, pct))
807 else:
807 else:
808 self.debug('%s:%s %s%s\n' % (topic, item, pos, unit))
808 self.debug('%s:%s %s%s\n' % (topic, item, pos, unit))
809
809
810 def log(self, service, *msg, **opts):
810 def log(self, service, *msg, **opts):
811 '''hook for logging facility extensions
811 '''hook for logging facility extensions
812
812
813 service should be a readily-identifiable subsystem, which will
813 service should be a readily-identifiable subsystem, which will
814 allow filtering.
814 allow filtering.
815 message should be a newline-terminated string to log.
815 message should be a newline-terminated string to log.
816 '''
816 '''
817 pass
817 pass
818
818
819 def label(self, msg, label):
819 def label(self, msg, label):
820 '''style msg based on supplied label
820 '''style msg based on supplied label
821
821
822 Like ui.write(), this just returns msg unchanged, but extensions
822 Like ui.write(), this just returns msg unchanged, but extensions
823 and GUI tools can override it to allow styling output without
823 and GUI tools can override it to allow styling output without
824 writing it.
824 writing it.
825
825
826 ui.write(s, 'label') is equivalent to
826 ui.write(s, 'label') is equivalent to
827 ui.write(ui.label(s, 'label')).
827 ui.write(ui.label(s, 'label')).
828 '''
828 '''
829 return msg
829 return msg
@@ -1,66 +1,66 b''
1 $ unset HGUSER
1 $ unset HGUSER
2 $ EMAIL="My Name <myname@example.com>"
2 $ EMAIL="My Name <myname@example.com>"
3 $ export EMAIL
3 $ export EMAIL
4
4
5 $ hg init test
5 $ hg init test
6 $ cd test
6 $ cd test
7 $ touch asdf
7 $ touch asdf
8 $ hg add asdf
8 $ hg add asdf
9 $ hg commit -m commit-1
9 $ hg commit -m commit-1
10 $ hg tip
10 $ hg tip
11 changeset: 0:53f268a58230
11 changeset: 0:53f268a58230
12 tag: tip
12 tag: tip
13 user: My Name <myname@example.com>
13 user: My Name <myname@example.com>
14 date: Thu Jan 01 00:00:00 1970 +0000
14 date: Thu Jan 01 00:00:00 1970 +0000
15 summary: commit-1
15 summary: commit-1
16
16
17
17
18 $ unset EMAIL
18 $ unset EMAIL
19 $ echo 1234 > asdf
19 $ echo 1234 > asdf
20 $ hg commit -u "foo@bar.com" -m commit-1
20 $ hg commit -u "foo@bar.com" -m commit-1
21 $ hg tip
21 $ hg tip
22 changeset: 1:3871b2a9e9bf
22 changeset: 1:3871b2a9e9bf
23 tag: tip
23 tag: tip
24 user: foo@bar.com
24 user: foo@bar.com
25 date: Thu Jan 01 00:00:00 1970 +0000
25 date: Thu Jan 01 00:00:00 1970 +0000
26 summary: commit-1
26 summary: commit-1
27
27
28 $ echo "[ui]" >> .hg/hgrc
28 $ echo "[ui]" >> .hg/hgrc
29 $ echo "username = foobar <foo@bar.com>" >> .hg/hgrc
29 $ echo "username = foobar <foo@bar.com>" >> .hg/hgrc
30 $ echo 12 > asdf
30 $ echo 12 > asdf
31 $ hg commit -m commit-1
31 $ hg commit -m commit-1
32 $ hg tip
32 $ hg tip
33 changeset: 2:8eeac6695c1c
33 changeset: 2:8eeac6695c1c
34 tag: tip
34 tag: tip
35 user: foobar <foo@bar.com>
35 user: foobar <foo@bar.com>
36 date: Thu Jan 01 00:00:00 1970 +0000
36 date: Thu Jan 01 00:00:00 1970 +0000
37 summary: commit-1
37 summary: commit-1
38
38
39 $ echo 1 > asdf
39 $ echo 1 > asdf
40 $ hg commit -u "foo@bar.com" -m commit-1
40 $ hg commit -u "foo@bar.com" -m commit-1
41 $ hg tip
41 $ hg tip
42 changeset: 3:957606a725e4
42 changeset: 3:957606a725e4
43 tag: tip
43 tag: tip
44 user: foo@bar.com
44 user: foo@bar.com
45 date: Thu Jan 01 00:00:00 1970 +0000
45 date: Thu Jan 01 00:00:00 1970 +0000
46 summary: commit-1
46 summary: commit-1
47
47
48 $ echo 123 > asdf
48 $ echo 123 > asdf
49 $ echo "[ui]" > .hg/hgrc
49 $ echo "[ui]" > .hg/hgrc
50 $ echo "username = " >> .hg/hgrc
50 $ echo "username = " >> .hg/hgrc
51 $ hg commit -m commit-1
51 $ hg commit -m commit-1
52 abort: no username supplied
52 abort: no username supplied
53 (use "hg config --edit" to set your username)
53 (use "hg config --edit" to set your username)
54 [255]
54 [255]
55 $ rm .hg/hgrc
55 $ rm .hg/hgrc
56 $ hg commit -m commit-1 2>&1
56 $ hg commit -m commit-1 2>&1
57 no username found, using '[^']*' instead (re)
57 no username found, using '[^']*' instead (re)
58
58
59 $ echo space > asdf
59 $ echo space > asdf
60 $ hg commit -u ' ' -m commit-1
60 $ hg commit -u ' ' -m commit-1
61 transaction abort!
61 transaction abort!
62 rollback completed
62 rollback completed
63 abort: empty username!
63 abort: empty username!
64 [255]
64 [255]
65
65
66 $ cd ..
66 $ cd ..
@@ -1,1302 +1,1302 b''
1 Set up a repo
1 Set up a repo
2
2
3 $ echo "[ui]" >> $HGRCPATH
3 $ echo "[ui]" >> $HGRCPATH
4 $ echo "interactive=true" >> $HGRCPATH
4 $ echo "interactive=true" >> $HGRCPATH
5 $ echo "[extensions]" >> $HGRCPATH
5 $ echo "[extensions]" >> $HGRCPATH
6 $ echo "record=" >> $HGRCPATH
6 $ echo "record=" >> $HGRCPATH
7
7
8 $ hg init a
8 $ hg init a
9 $ cd a
9 $ cd a
10
10
11 Select no files
11 Select no files
12
12
13 $ touch empty-rw
13 $ touch empty-rw
14 $ hg add empty-rw
14 $ hg add empty-rw
15
15
16 $ hg record empty-rw<<EOF
16 $ hg record empty-rw<<EOF
17 > n
17 > n
18 > EOF
18 > EOF
19 diff --git a/empty-rw b/empty-rw
19 diff --git a/empty-rw b/empty-rw
20 new file mode 100644
20 new file mode 100644
21 examine changes to 'empty-rw'? [Ynesfdaq?]
21 examine changes to 'empty-rw'? [Ynesfdaq?]
22 no changes to record
22 no changes to record
23
23
24 $ hg tip -p
24 $ hg tip -p
25 changeset: -1:000000000000
25 changeset: -1:000000000000
26 tag: tip
26 tag: tip
27 user:
27 user:
28 date: Thu Jan 01 00:00:00 1970 +0000
28 date: Thu Jan 01 00:00:00 1970 +0000
29
29
30
30
31
31
32 Select files but no hunks
32 Select files but no hunks
33
33
34 $ hg record empty-rw<<EOF
34 $ hg record empty-rw<<EOF
35 > y
35 > y
36 > n
36 > n
37 > EOF
37 > EOF
38 diff --git a/empty-rw b/empty-rw
38 diff --git a/empty-rw b/empty-rw
39 new file mode 100644
39 new file mode 100644
40 examine changes to 'empty-rw'? [Ynesfdaq?]
40 examine changes to 'empty-rw'? [Ynesfdaq?]
41 abort: empty commit message
41 abort: empty commit message
42 [255]
42 [255]
43
43
44 $ hg tip -p
44 $ hg tip -p
45 changeset: -1:000000000000
45 changeset: -1:000000000000
46 tag: tip
46 tag: tip
47 user:
47 user:
48 date: Thu Jan 01 00:00:00 1970 +0000
48 date: Thu Jan 01 00:00:00 1970 +0000
49
49
50
50
51
51
52 Record empty file
52 Record empty file
53
53
54 $ hg record -d '0 0' -m empty empty-rw<<EOF
54 $ hg record -d '0 0' -m empty empty-rw<<EOF
55 > y
55 > y
56 > y
56 > y
57 > EOF
57 > EOF
58 diff --git a/empty-rw b/empty-rw
58 diff --git a/empty-rw b/empty-rw
59 new file mode 100644
59 new file mode 100644
60 examine changes to 'empty-rw'? [Ynesfdaq?]
60 examine changes to 'empty-rw'? [Ynesfdaq?]
61
61
62 $ hg tip -p
62 $ hg tip -p
63 changeset: 0:c0708cf4e46e
63 changeset: 0:c0708cf4e46e
64 tag: tip
64 tag: tip
65 user: test
65 user: test
66 date: Thu Jan 01 00:00:00 1970 +0000
66 date: Thu Jan 01 00:00:00 1970 +0000
67 summary: empty
67 summary: empty
68
68
69
69
70
70
71 Summary shows we updated to the new cset
71 Summary shows we updated to the new cset
72
72
73 $ hg summary
73 $ hg summary
74 parent: 0:c0708cf4e46e tip
74 parent: 0:c0708cf4e46e tip
75 empty
75 empty
76 branch: default
76 branch: default
77 commit: (clean)
77 commit: (clean)
78 update: (current)
78 update: (current)
79
79
80 Rename empty file
80 Rename empty file
81
81
82 $ hg mv empty-rw empty-rename
82 $ hg mv empty-rw empty-rename
83 $ hg record -d '1 0' -m rename<<EOF
83 $ hg record -d '1 0' -m rename<<EOF
84 > y
84 > y
85 > EOF
85 > EOF
86 diff --git a/empty-rw b/empty-rename
86 diff --git a/empty-rw b/empty-rename
87 rename from empty-rw
87 rename from empty-rw
88 rename to empty-rename
88 rename to empty-rename
89 examine changes to 'empty-rw' and 'empty-rename'? [Ynesfdaq?]
89 examine changes to 'empty-rw' and 'empty-rename'? [Ynesfdaq?]
90
90
91 $ hg tip -p
91 $ hg tip -p
92 changeset: 1:d695e8dcb197
92 changeset: 1:d695e8dcb197
93 tag: tip
93 tag: tip
94 user: test
94 user: test
95 date: Thu Jan 01 00:00:01 1970 +0000
95 date: Thu Jan 01 00:00:01 1970 +0000
96 summary: rename
96 summary: rename
97
97
98
98
99
99
100 Copy empty file
100 Copy empty file
101
101
102 $ hg cp empty-rename empty-copy
102 $ hg cp empty-rename empty-copy
103 $ hg record -d '2 0' -m copy<<EOF
103 $ hg record -d '2 0' -m copy<<EOF
104 > y
104 > y
105 > EOF
105 > EOF
106 diff --git a/empty-rename b/empty-copy
106 diff --git a/empty-rename b/empty-copy
107 copy from empty-rename
107 copy from empty-rename
108 copy to empty-copy
108 copy to empty-copy
109 examine changes to 'empty-rename' and 'empty-copy'? [Ynesfdaq?]
109 examine changes to 'empty-rename' and 'empty-copy'? [Ynesfdaq?]
110
110
111 $ hg tip -p
111 $ hg tip -p
112 changeset: 2:1d4b90bea524
112 changeset: 2:1d4b90bea524
113 tag: tip
113 tag: tip
114 user: test
114 user: test
115 date: Thu Jan 01 00:00:02 1970 +0000
115 date: Thu Jan 01 00:00:02 1970 +0000
116 summary: copy
116 summary: copy
117
117
118
118
119
119
120 Delete empty file
120 Delete empty file
121
121
122 $ hg rm empty-copy
122 $ hg rm empty-copy
123 $ hg record -d '3 0' -m delete<<EOF
123 $ hg record -d '3 0' -m delete<<EOF
124 > y
124 > y
125 > EOF
125 > EOF
126 diff --git a/empty-copy b/empty-copy
126 diff --git a/empty-copy b/empty-copy
127 deleted file mode 100644
127 deleted file mode 100644
128 examine changes to 'empty-copy'? [Ynesfdaq?]
128 examine changes to 'empty-copy'? [Ynesfdaq?]
129
129
130 $ hg tip -p
130 $ hg tip -p
131 changeset: 3:b39a238f01a1
131 changeset: 3:b39a238f01a1
132 tag: tip
132 tag: tip
133 user: test
133 user: test
134 date: Thu Jan 01 00:00:03 1970 +0000
134 date: Thu Jan 01 00:00:03 1970 +0000
135 summary: delete
135 summary: delete
136
136
137
137
138
138
139 Add binary file
139 Add binary file
140
140
141 $ hg bundle --base -2 tip.bundle
141 $ hg bundle --base -2 tip.bundle
142 1 changesets found
142 1 changesets found
143 $ hg add tip.bundle
143 $ hg add tip.bundle
144 $ hg record -d '4 0' -m binary<<EOF
144 $ hg record -d '4 0' -m binary<<EOF
145 > y
145 > y
146 > EOF
146 > EOF
147 diff --git a/tip.bundle b/tip.bundle
147 diff --git a/tip.bundle b/tip.bundle
148 new file mode 100644
148 new file mode 100644
149 this is a binary file
149 this is a binary file
150 examine changes to 'tip.bundle'? [Ynesfdaq?]
150 examine changes to 'tip.bundle'? [Ynesfdaq?]
151
151
152 $ hg tip -p
152 $ hg tip -p
153 changeset: 4:ad816da3711e
153 changeset: 4:ad816da3711e
154 tag: tip
154 tag: tip
155 user: test
155 user: test
156 date: Thu Jan 01 00:00:04 1970 +0000
156 date: Thu Jan 01 00:00:04 1970 +0000
157 summary: binary
157 summary: binary
158
158
159 diff -r b39a238f01a1 -r ad816da3711e tip.bundle
159 diff -r b39a238f01a1 -r ad816da3711e tip.bundle
160 Binary file tip.bundle has changed
160 Binary file tip.bundle has changed
161
161
162
162
163 Change binary file
163 Change binary file
164
164
165 $ hg bundle --base -2 tip.bundle
165 $ hg bundle --base -2 tip.bundle
166 1 changesets found
166 1 changesets found
167 $ hg record -d '5 0' -m binary-change<<EOF
167 $ hg record -d '5 0' -m binary-change<<EOF
168 > y
168 > y
169 > EOF
169 > EOF
170 diff --git a/tip.bundle b/tip.bundle
170 diff --git a/tip.bundle b/tip.bundle
171 this modifies a binary file (all or nothing)
171 this modifies a binary file (all or nothing)
172 examine changes to 'tip.bundle'? [Ynesfdaq?]
172 examine changes to 'tip.bundle'? [Ynesfdaq?]
173
173
174 $ hg tip -p
174 $ hg tip -p
175 changeset: 5:dccd6f3eb485
175 changeset: 5:dccd6f3eb485
176 tag: tip
176 tag: tip
177 user: test
177 user: test
178 date: Thu Jan 01 00:00:05 1970 +0000
178 date: Thu Jan 01 00:00:05 1970 +0000
179 summary: binary-change
179 summary: binary-change
180
180
181 diff -r ad816da3711e -r dccd6f3eb485 tip.bundle
181 diff -r ad816da3711e -r dccd6f3eb485 tip.bundle
182 Binary file tip.bundle has changed
182 Binary file tip.bundle has changed
183
183
184
184
185 Rename and change binary file
185 Rename and change binary file
186
186
187 $ hg mv tip.bundle top.bundle
187 $ hg mv tip.bundle top.bundle
188 $ hg bundle --base -2 top.bundle
188 $ hg bundle --base -2 top.bundle
189 1 changesets found
189 1 changesets found
190 $ hg record -d '6 0' -m binary-change-rename<<EOF
190 $ hg record -d '6 0' -m binary-change-rename<<EOF
191 > y
191 > y
192 > EOF
192 > EOF
193 diff --git a/tip.bundle b/top.bundle
193 diff --git a/tip.bundle b/top.bundle
194 rename from tip.bundle
194 rename from tip.bundle
195 rename to top.bundle
195 rename to top.bundle
196 this modifies a binary file (all or nothing)
196 this modifies a binary file (all or nothing)
197 examine changes to 'tip.bundle' and 'top.bundle'? [Ynesfdaq?]
197 examine changes to 'tip.bundle' and 'top.bundle'? [Ynesfdaq?]
198
198
199 $ hg tip -p
199 $ hg tip -p
200 changeset: 6:7fa44105f5b3
200 changeset: 6:7fa44105f5b3
201 tag: tip
201 tag: tip
202 user: test
202 user: test
203 date: Thu Jan 01 00:00:06 1970 +0000
203 date: Thu Jan 01 00:00:06 1970 +0000
204 summary: binary-change-rename
204 summary: binary-change-rename
205
205
206 diff -r dccd6f3eb485 -r 7fa44105f5b3 tip.bundle
206 diff -r dccd6f3eb485 -r 7fa44105f5b3 tip.bundle
207 Binary file tip.bundle has changed
207 Binary file tip.bundle has changed
208 diff -r dccd6f3eb485 -r 7fa44105f5b3 top.bundle
208 diff -r dccd6f3eb485 -r 7fa44105f5b3 top.bundle
209 Binary file top.bundle has changed
209 Binary file top.bundle has changed
210
210
211
211
212 Add plain file
212 Add plain file
213
213
214 $ for i in 1 2 3 4 5 6 7 8 9 10; do
214 $ for i in 1 2 3 4 5 6 7 8 9 10; do
215 > echo $i >> plain
215 > echo $i >> plain
216 > done
216 > done
217
217
218 $ hg add plain
218 $ hg add plain
219 $ hg record -d '7 0' -m plain plain<<EOF
219 $ hg record -d '7 0' -m plain plain<<EOF
220 > y
220 > y
221 > y
221 > y
222 > EOF
222 > EOF
223 diff --git a/plain b/plain
223 diff --git a/plain b/plain
224 new file mode 100644
224 new file mode 100644
225 examine changes to 'plain'? [Ynesfdaq?]
225 examine changes to 'plain'? [Ynesfdaq?]
226
226
227 $ hg tip -p
227 $ hg tip -p
228 changeset: 7:11fb457c1be4
228 changeset: 7:11fb457c1be4
229 tag: tip
229 tag: tip
230 user: test
230 user: test
231 date: Thu Jan 01 00:00:07 1970 +0000
231 date: Thu Jan 01 00:00:07 1970 +0000
232 summary: plain
232 summary: plain
233
233
234 diff -r 7fa44105f5b3 -r 11fb457c1be4 plain
234 diff -r 7fa44105f5b3 -r 11fb457c1be4 plain
235 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
235 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
236 +++ b/plain Thu Jan 01 00:00:07 1970 +0000
236 +++ b/plain Thu Jan 01 00:00:07 1970 +0000
237 @@ -0,0 +1,10 @@
237 @@ -0,0 +1,10 @@
238 +1
238 +1
239 +2
239 +2
240 +3
240 +3
241 +4
241 +4
242 +5
242 +5
243 +6
243 +6
244 +7
244 +7
245 +8
245 +8
246 +9
246 +9
247 +10
247 +10
248
248
249 Modify end of plain file with username unset
249 Modify end of plain file with username unset
250
250
251 $ echo 11 >> plain
251 $ echo 11 >> plain
252 $ unset HGUSER
252 $ unset HGUSER
253 $ hg record --config ui.username= -d '8 0' -m end plain
253 $ hg record --config ui.username= -d '8 0' -m end plain
254 abort: no username supplied
254 abort: no username supplied
255 (use "hg config --edit" to set your username)
255 (use "hg config --edit" to set your username)
256 [255]
256 [255]
257
257
258
258
259 Modify end of plain file, also test that diffopts are accounted for
259 Modify end of plain file, also test that diffopts are accounted for
260
260
261 $ HGUSER="test"
261 $ HGUSER="test"
262 $ export HGUSER
262 $ export HGUSER
263 $ hg record --config diff.showfunc=true -d '8 0' -m end plain <<EOF
263 $ hg record --config diff.showfunc=true -d '8 0' -m end plain <<EOF
264 > y
264 > y
265 > y
265 > y
266 > EOF
266 > EOF
267 diff --git a/plain b/plain
267 diff --git a/plain b/plain
268 1 hunks, 1 lines changed
268 1 hunks, 1 lines changed
269 examine changes to 'plain'? [Ynesfdaq?]
269 examine changes to 'plain'? [Ynesfdaq?]
270 @@ -8,3 +8,4 @@ 7
270 @@ -8,3 +8,4 @@ 7
271 8
271 8
272 9
272 9
273 10
273 10
274 +11
274 +11
275 record this change to 'plain'? [Ynesfdaq?]
275 record this change to 'plain'? [Ynesfdaq?]
276
276
277 Modify end of plain file, no EOL
277 Modify end of plain file, no EOL
278
278
279 $ hg tip --template '{node}' >> plain
279 $ hg tip --template '{node}' >> plain
280 $ hg record -d '9 0' -m noeol plain <<EOF
280 $ hg record -d '9 0' -m noeol plain <<EOF
281 > y
281 > y
282 > y
282 > y
283 > EOF
283 > EOF
284 diff --git a/plain b/plain
284 diff --git a/plain b/plain
285 1 hunks, 1 lines changed
285 1 hunks, 1 lines changed
286 examine changes to 'plain'? [Ynesfdaq?]
286 examine changes to 'plain'? [Ynesfdaq?]
287 @@ -9,3 +9,4 @@
287 @@ -9,3 +9,4 @@
288 9
288 9
289 10
289 10
290 11
290 11
291 +7264f99c5f5ff3261504828afa4fb4d406c3af54
291 +7264f99c5f5ff3261504828afa4fb4d406c3af54
292 \ No newline at end of file
292 \ No newline at end of file
293 record this change to 'plain'? [Ynesfdaq?]
293 record this change to 'plain'? [Ynesfdaq?]
294
294
295 Modify end of plain file, add EOL
295 Modify end of plain file, add EOL
296
296
297 $ echo >> plain
297 $ echo >> plain
298 $ echo 1 > plain2
298 $ echo 1 > plain2
299 $ hg add plain2
299 $ hg add plain2
300 $ hg record -d '10 0' -m eol plain plain2 <<EOF
300 $ hg record -d '10 0' -m eol plain plain2 <<EOF
301 > y
301 > y
302 > y
302 > y
303 > y
303 > y
304 > EOF
304 > EOF
305 diff --git a/plain b/plain
305 diff --git a/plain b/plain
306 1 hunks, 1 lines changed
306 1 hunks, 1 lines changed
307 examine changes to 'plain'? [Ynesfdaq?]
307 examine changes to 'plain'? [Ynesfdaq?]
308 @@ -9,4 +9,4 @@
308 @@ -9,4 +9,4 @@
309 9
309 9
310 10
310 10
311 11
311 11
312 -7264f99c5f5ff3261504828afa4fb4d406c3af54
312 -7264f99c5f5ff3261504828afa4fb4d406c3af54
313 \ No newline at end of file
313 \ No newline at end of file
314 +7264f99c5f5ff3261504828afa4fb4d406c3af54
314 +7264f99c5f5ff3261504828afa4fb4d406c3af54
315 record change 1/2 to 'plain'? [Ynesfdaq?]
315 record change 1/2 to 'plain'? [Ynesfdaq?]
316 diff --git a/plain2 b/plain2
316 diff --git a/plain2 b/plain2
317 new file mode 100644
317 new file mode 100644
318 examine changes to 'plain2'? [Ynesfdaq?]
318 examine changes to 'plain2'? [Ynesfdaq?]
319
319
320 Modify beginning, trim end, record both, add another file to test
320 Modify beginning, trim end, record both, add another file to test
321 changes numbering
321 changes numbering
322
322
323 $ rm plain
323 $ rm plain
324 $ for i in 2 2 3 4 5 6 7 8 9 10; do
324 $ for i in 2 2 3 4 5 6 7 8 9 10; do
325 > echo $i >> plain
325 > echo $i >> plain
326 > done
326 > done
327 $ echo 2 >> plain2
327 $ echo 2 >> plain2
328
328
329 $ hg record -d '10 0' -m begin-and-end plain plain2 <<EOF
329 $ hg record -d '10 0' -m begin-and-end plain plain2 <<EOF
330 > y
330 > y
331 > y
331 > y
332 > y
332 > y
333 > y
333 > y
334 > y
334 > y
335 > EOF
335 > EOF
336 diff --git a/plain b/plain
336 diff --git a/plain b/plain
337 2 hunks, 3 lines changed
337 2 hunks, 3 lines changed
338 examine changes to 'plain'? [Ynesfdaq?]
338 examine changes to 'plain'? [Ynesfdaq?]
339 @@ -1,4 +1,4 @@
339 @@ -1,4 +1,4 @@
340 -1
340 -1
341 +2
341 +2
342 2
342 2
343 3
343 3
344 4
344 4
345 record change 1/3 to 'plain'? [Ynesfdaq?]
345 record change 1/3 to 'plain'? [Ynesfdaq?]
346 @@ -8,5 +8,3 @@
346 @@ -8,5 +8,3 @@
347 8
347 8
348 9
348 9
349 10
349 10
350 -11
350 -11
351 -7264f99c5f5ff3261504828afa4fb4d406c3af54
351 -7264f99c5f5ff3261504828afa4fb4d406c3af54
352 record change 2/3 to 'plain'? [Ynesfdaq?]
352 record change 2/3 to 'plain'? [Ynesfdaq?]
353 diff --git a/plain2 b/plain2
353 diff --git a/plain2 b/plain2
354 1 hunks, 1 lines changed
354 1 hunks, 1 lines changed
355 examine changes to 'plain2'? [Ynesfdaq?]
355 examine changes to 'plain2'? [Ynesfdaq?]
356 @@ -1,1 +1,2 @@
356 @@ -1,1 +1,2 @@
357 1
357 1
358 +2
358 +2
359 record change 3/3 to 'plain2'? [Ynesfdaq?]
359 record change 3/3 to 'plain2'? [Ynesfdaq?]
360
360
361 $ hg tip -p
361 $ hg tip -p
362 changeset: 11:21df83db12b8
362 changeset: 11:21df83db12b8
363 tag: tip
363 tag: tip
364 user: test
364 user: test
365 date: Thu Jan 01 00:00:10 1970 +0000
365 date: Thu Jan 01 00:00:10 1970 +0000
366 summary: begin-and-end
366 summary: begin-and-end
367
367
368 diff -r ddb8b281c3ff -r 21df83db12b8 plain
368 diff -r ddb8b281c3ff -r 21df83db12b8 plain
369 --- a/plain Thu Jan 01 00:00:10 1970 +0000
369 --- a/plain Thu Jan 01 00:00:10 1970 +0000
370 +++ b/plain Thu Jan 01 00:00:10 1970 +0000
370 +++ b/plain Thu Jan 01 00:00:10 1970 +0000
371 @@ -1,4 +1,4 @@
371 @@ -1,4 +1,4 @@
372 -1
372 -1
373 +2
373 +2
374 2
374 2
375 3
375 3
376 4
376 4
377 @@ -8,5 +8,3 @@
377 @@ -8,5 +8,3 @@
378 8
378 8
379 9
379 9
380 10
380 10
381 -11
381 -11
382 -7264f99c5f5ff3261504828afa4fb4d406c3af54
382 -7264f99c5f5ff3261504828afa4fb4d406c3af54
383 diff -r ddb8b281c3ff -r 21df83db12b8 plain2
383 diff -r ddb8b281c3ff -r 21df83db12b8 plain2
384 --- a/plain2 Thu Jan 01 00:00:10 1970 +0000
384 --- a/plain2 Thu Jan 01 00:00:10 1970 +0000
385 +++ b/plain2 Thu Jan 01 00:00:10 1970 +0000
385 +++ b/plain2 Thu Jan 01 00:00:10 1970 +0000
386 @@ -1,1 +1,2 @@
386 @@ -1,1 +1,2 @@
387 1
387 1
388 +2
388 +2
389
389
390
390
391 Trim beginning, modify end
391 Trim beginning, modify end
392
392
393 $ rm plain
393 $ rm plain
394 > for i in 4 5 6 7 8 9 10.new; do
394 > for i in 4 5 6 7 8 9 10.new; do
395 > echo $i >> plain
395 > echo $i >> plain
396 > done
396 > done
397
397
398 Record end
398 Record end
399
399
400 $ hg record -d '11 0' -m end-only plain <<EOF
400 $ hg record -d '11 0' -m end-only plain <<EOF
401 > y
401 > y
402 > n
402 > n
403 > y
403 > y
404 > EOF
404 > EOF
405 diff --git a/plain b/plain
405 diff --git a/plain b/plain
406 2 hunks, 4 lines changed
406 2 hunks, 4 lines changed
407 examine changes to 'plain'? [Ynesfdaq?]
407 examine changes to 'plain'? [Ynesfdaq?]
408 @@ -1,9 +1,6 @@
408 @@ -1,9 +1,6 @@
409 -2
409 -2
410 -2
410 -2
411 -3
411 -3
412 4
412 4
413 5
413 5
414 6
414 6
415 7
415 7
416 8
416 8
417 9
417 9
418 record change 1/2 to 'plain'? [Ynesfdaq?]
418 record change 1/2 to 'plain'? [Ynesfdaq?]
419 @@ -4,7 +1,7 @@
419 @@ -4,7 +1,7 @@
420 4
420 4
421 5
421 5
422 6
422 6
423 7
423 7
424 8
424 8
425 9
425 9
426 -10
426 -10
427 +10.new
427 +10.new
428 record change 2/2 to 'plain'? [Ynesfdaq?]
428 record change 2/2 to 'plain'? [Ynesfdaq?]
429
429
430 $ hg tip -p
430 $ hg tip -p
431 changeset: 12:99337501826f
431 changeset: 12:99337501826f
432 tag: tip
432 tag: tip
433 user: test
433 user: test
434 date: Thu Jan 01 00:00:11 1970 +0000
434 date: Thu Jan 01 00:00:11 1970 +0000
435 summary: end-only
435 summary: end-only
436
436
437 diff -r 21df83db12b8 -r 99337501826f plain
437 diff -r 21df83db12b8 -r 99337501826f plain
438 --- a/plain Thu Jan 01 00:00:10 1970 +0000
438 --- a/plain Thu Jan 01 00:00:10 1970 +0000
439 +++ b/plain Thu Jan 01 00:00:11 1970 +0000
439 +++ b/plain Thu Jan 01 00:00:11 1970 +0000
440 @@ -7,4 +7,4 @@
440 @@ -7,4 +7,4 @@
441 7
441 7
442 8
442 8
443 9
443 9
444 -10
444 -10
445 +10.new
445 +10.new
446
446
447
447
448 Record beginning
448 Record beginning
449
449
450 $ hg record -d '12 0' -m begin-only plain <<EOF
450 $ hg record -d '12 0' -m begin-only plain <<EOF
451 > y
451 > y
452 > y
452 > y
453 > EOF
453 > EOF
454 diff --git a/plain b/plain
454 diff --git a/plain b/plain
455 1 hunks, 3 lines changed
455 1 hunks, 3 lines changed
456 examine changes to 'plain'? [Ynesfdaq?]
456 examine changes to 'plain'? [Ynesfdaq?]
457 @@ -1,6 +1,3 @@
457 @@ -1,6 +1,3 @@
458 -2
458 -2
459 -2
459 -2
460 -3
460 -3
461 4
461 4
462 5
462 5
463 6
463 6
464 record this change to 'plain'? [Ynesfdaq?]
464 record this change to 'plain'? [Ynesfdaq?]
465
465
466 $ hg tip -p
466 $ hg tip -p
467 changeset: 13:bbd45465d540
467 changeset: 13:bbd45465d540
468 tag: tip
468 tag: tip
469 user: test
469 user: test
470 date: Thu Jan 01 00:00:12 1970 +0000
470 date: Thu Jan 01 00:00:12 1970 +0000
471 summary: begin-only
471 summary: begin-only
472
472
473 diff -r 99337501826f -r bbd45465d540 plain
473 diff -r 99337501826f -r bbd45465d540 plain
474 --- a/plain Thu Jan 01 00:00:11 1970 +0000
474 --- a/plain Thu Jan 01 00:00:11 1970 +0000
475 +++ b/plain Thu Jan 01 00:00:12 1970 +0000
475 +++ b/plain Thu Jan 01 00:00:12 1970 +0000
476 @@ -1,6 +1,3 @@
476 @@ -1,6 +1,3 @@
477 -2
477 -2
478 -2
478 -2
479 -3
479 -3
480 4
480 4
481 5
481 5
482 6
482 6
483
483
484
484
485 Add to beginning, trim from end
485 Add to beginning, trim from end
486
486
487 $ rm plain
487 $ rm plain
488 $ for i in 1 2 3 4 5 6 7 8 9; do
488 $ for i in 1 2 3 4 5 6 7 8 9; do
489 > echo $i >> plain
489 > echo $i >> plain
490 > done
490 > done
491
491
492 Record end
492 Record end
493
493
494 $ hg record --traceback -d '13 0' -m end-again plain<<EOF
494 $ hg record --traceback -d '13 0' -m end-again plain<<EOF
495 > y
495 > y
496 > n
496 > n
497 > y
497 > y
498 > EOF
498 > EOF
499 diff --git a/plain b/plain
499 diff --git a/plain b/plain
500 2 hunks, 4 lines changed
500 2 hunks, 4 lines changed
501 examine changes to 'plain'? [Ynesfdaq?]
501 examine changes to 'plain'? [Ynesfdaq?]
502 @@ -1,6 +1,9 @@
502 @@ -1,6 +1,9 @@
503 +1
503 +1
504 +2
504 +2
505 +3
505 +3
506 4
506 4
507 5
507 5
508 6
508 6
509 7
509 7
510 8
510 8
511 9
511 9
512 record change 1/2 to 'plain'? [Ynesfdaq?]
512 record change 1/2 to 'plain'? [Ynesfdaq?]
513 @@ -1,7 +4,6 @@
513 @@ -1,7 +4,6 @@
514 4
514 4
515 5
515 5
516 6
516 6
517 7
517 7
518 8
518 8
519 9
519 9
520 -10.new
520 -10.new
521 record change 2/2 to 'plain'? [Ynesfdaq?]
521 record change 2/2 to 'plain'? [Ynesfdaq?]
522
522
523 Add to beginning, middle, end
523 Add to beginning, middle, end
524
524
525 $ rm plain
525 $ rm plain
526 $ for i in 1 2 3 4 5 5.new 5.reallynew 6 7 8 9 10 11; do
526 $ for i in 1 2 3 4 5 5.new 5.reallynew 6 7 8 9 10 11; do
527 > echo $i >> plain
527 > echo $i >> plain
528 > done
528 > done
529
529
530 Record beginning, middle
530 Record beginning, middle
531
531
532 $ hg record -d '14 0' -m middle-only plain <<EOF
532 $ hg record -d '14 0' -m middle-only plain <<EOF
533 > y
533 > y
534 > y
534 > y
535 > y
535 > y
536 > n
536 > n
537 > EOF
537 > EOF
538 diff --git a/plain b/plain
538 diff --git a/plain b/plain
539 3 hunks, 7 lines changed
539 3 hunks, 7 lines changed
540 examine changes to 'plain'? [Ynesfdaq?]
540 examine changes to 'plain'? [Ynesfdaq?]
541 @@ -1,2 +1,5 @@
541 @@ -1,2 +1,5 @@
542 +1
542 +1
543 +2
543 +2
544 +3
544 +3
545 4
545 4
546 5
546 5
547 record change 1/3 to 'plain'? [Ynesfdaq?]
547 record change 1/3 to 'plain'? [Ynesfdaq?]
548 @@ -1,6 +4,8 @@
548 @@ -1,6 +4,8 @@
549 4
549 4
550 5
550 5
551 +5.new
551 +5.new
552 +5.reallynew
552 +5.reallynew
553 6
553 6
554 7
554 7
555 8
555 8
556 9
556 9
557 record change 2/3 to 'plain'? [Ynesfdaq?]
557 record change 2/3 to 'plain'? [Ynesfdaq?]
558 @@ -3,4 +8,6 @@
558 @@ -3,4 +8,6 @@
559 6
559 6
560 7
560 7
561 8
561 8
562 9
562 9
563 +10
563 +10
564 +11
564 +11
565 record change 3/3 to 'plain'? [Ynesfdaq?]
565 record change 3/3 to 'plain'? [Ynesfdaq?]
566
566
567 $ hg tip -p
567 $ hg tip -p
568 changeset: 15:f34a7937ec33
568 changeset: 15:f34a7937ec33
569 tag: tip
569 tag: tip
570 user: test
570 user: test
571 date: Thu Jan 01 00:00:14 1970 +0000
571 date: Thu Jan 01 00:00:14 1970 +0000
572 summary: middle-only
572 summary: middle-only
573
573
574 diff -r 82c065d0b850 -r f34a7937ec33 plain
574 diff -r 82c065d0b850 -r f34a7937ec33 plain
575 --- a/plain Thu Jan 01 00:00:13 1970 +0000
575 --- a/plain Thu Jan 01 00:00:13 1970 +0000
576 +++ b/plain Thu Jan 01 00:00:14 1970 +0000
576 +++ b/plain Thu Jan 01 00:00:14 1970 +0000
577 @@ -1,5 +1,10 @@
577 @@ -1,5 +1,10 @@
578 +1
578 +1
579 +2
579 +2
580 +3
580 +3
581 4
581 4
582 5
582 5
583 +5.new
583 +5.new
584 +5.reallynew
584 +5.reallynew
585 6
585 6
586 7
586 7
587 8
587 8
588
588
589
589
590 Record end
590 Record end
591
591
592 $ hg record -d '15 0' -m end-only plain <<EOF
592 $ hg record -d '15 0' -m end-only plain <<EOF
593 > y
593 > y
594 > y
594 > y
595 > EOF
595 > EOF
596 diff --git a/plain b/plain
596 diff --git a/plain b/plain
597 1 hunks, 2 lines changed
597 1 hunks, 2 lines changed
598 examine changes to 'plain'? [Ynesfdaq?]
598 examine changes to 'plain'? [Ynesfdaq?]
599 @@ -9,3 +9,5 @@
599 @@ -9,3 +9,5 @@
600 7
600 7
601 8
601 8
602 9
602 9
603 +10
603 +10
604 +11
604 +11
605 record this change to 'plain'? [Ynesfdaq?]
605 record this change to 'plain'? [Ynesfdaq?]
606
606
607 $ hg tip -p
607 $ hg tip -p
608 changeset: 16:f9900b71a04c
608 changeset: 16:f9900b71a04c
609 tag: tip
609 tag: tip
610 user: test
610 user: test
611 date: Thu Jan 01 00:00:15 1970 +0000
611 date: Thu Jan 01 00:00:15 1970 +0000
612 summary: end-only
612 summary: end-only
613
613
614 diff -r f34a7937ec33 -r f9900b71a04c plain
614 diff -r f34a7937ec33 -r f9900b71a04c plain
615 --- a/plain Thu Jan 01 00:00:14 1970 +0000
615 --- a/plain Thu Jan 01 00:00:14 1970 +0000
616 +++ b/plain Thu Jan 01 00:00:15 1970 +0000
616 +++ b/plain Thu Jan 01 00:00:15 1970 +0000
617 @@ -9,3 +9,5 @@
617 @@ -9,3 +9,5 @@
618 7
618 7
619 8
619 8
620 9
620 9
621 +10
621 +10
622 +11
622 +11
623
623
624
624
625 $ mkdir subdir
625 $ mkdir subdir
626 $ cd subdir
626 $ cd subdir
627 $ echo a > a
627 $ echo a > a
628 $ hg ci -d '16 0' -Amsubdir
628 $ hg ci -d '16 0' -Amsubdir
629 adding subdir/a
629 adding subdir/a
630
630
631 $ echo a >> a
631 $ echo a >> a
632 $ hg record -d '16 0' -m subdir-change a <<EOF
632 $ hg record -d '16 0' -m subdir-change a <<EOF
633 > y
633 > y
634 > y
634 > y
635 > EOF
635 > EOF
636 diff --git a/subdir/a b/subdir/a
636 diff --git a/subdir/a b/subdir/a
637 1 hunks, 1 lines changed
637 1 hunks, 1 lines changed
638 examine changes to 'subdir/a'? [Ynesfdaq?]
638 examine changes to 'subdir/a'? [Ynesfdaq?]
639 @@ -1,1 +1,2 @@
639 @@ -1,1 +1,2 @@
640 a
640 a
641 +a
641 +a
642 record this change to 'subdir/a'? [Ynesfdaq?]
642 record this change to 'subdir/a'? [Ynesfdaq?]
643
643
644 $ hg tip -p
644 $ hg tip -p
645 changeset: 18:61be427a9deb
645 changeset: 18:61be427a9deb
646 tag: tip
646 tag: tip
647 user: test
647 user: test
648 date: Thu Jan 01 00:00:16 1970 +0000
648 date: Thu Jan 01 00:00:16 1970 +0000
649 summary: subdir-change
649 summary: subdir-change
650
650
651 diff -r a7ffae4d61cb -r 61be427a9deb subdir/a
651 diff -r a7ffae4d61cb -r 61be427a9deb subdir/a
652 --- a/subdir/a Thu Jan 01 00:00:16 1970 +0000
652 --- a/subdir/a Thu Jan 01 00:00:16 1970 +0000
653 +++ b/subdir/a Thu Jan 01 00:00:16 1970 +0000
653 +++ b/subdir/a Thu Jan 01 00:00:16 1970 +0000
654 @@ -1,1 +1,2 @@
654 @@ -1,1 +1,2 @@
655 a
655 a
656 +a
656 +a
657
657
658
658
659 $ echo a > f1
659 $ echo a > f1
660 $ echo b > f2
660 $ echo b > f2
661 $ hg add f1 f2
661 $ hg add f1 f2
662
662
663 $ hg ci -mz -d '17 0'
663 $ hg ci -mz -d '17 0'
664
664
665 $ echo a >> f1
665 $ echo a >> f1
666 $ echo b >> f2
666 $ echo b >> f2
667
667
668 Help, quit
668 Help, quit
669
669
670 $ hg record <<EOF
670 $ hg record <<EOF
671 > ?
671 > ?
672 > q
672 > q
673 > EOF
673 > EOF
674 diff --git a/subdir/f1 b/subdir/f1
674 diff --git a/subdir/f1 b/subdir/f1
675 1 hunks, 1 lines changed
675 1 hunks, 1 lines changed
676 examine changes to 'subdir/f1'? [Ynesfdaq?]
676 examine changes to 'subdir/f1'? [Ynesfdaq?]
677 y - yes, record this change
677 y - yes, record this change
678 n - no, skip this change
678 n - no, skip this change
679 e - edit this change manually
679 e - edit this change manually
680 s - skip remaining changes to this file
680 s - skip remaining changes to this file
681 f - record remaining changes to this file
681 f - record remaining changes to this file
682 d - done, skip remaining changes and files
682 d - done, skip remaining changes and files
683 a - record all changes to all remaining files
683 a - record all changes to all remaining files
684 q - quit, recording no changes
684 q - quit, recording no changes
685 ? - ? (display help)
685 ? - ? (display help)
686 examine changes to 'subdir/f1'? [Ynesfdaq?]
686 examine changes to 'subdir/f1'? [Ynesfdaq?]
687 abort: user quit
687 abort: user quit
688 [255]
688 [255]
689
689
690 Skip
690 Skip
691
691
692 $ hg record <<EOF
692 $ hg record <<EOF
693 > s
693 > s
694 > EOF
694 > EOF
695 diff --git a/subdir/f1 b/subdir/f1
695 diff --git a/subdir/f1 b/subdir/f1
696 1 hunks, 1 lines changed
696 1 hunks, 1 lines changed
697 examine changes to 'subdir/f1'? [Ynesfdaq?]
697 examine changes to 'subdir/f1'? [Ynesfdaq?]
698 diff --git a/subdir/f2 b/subdir/f2
698 diff --git a/subdir/f2 b/subdir/f2
699 1 hunks, 1 lines changed
699 1 hunks, 1 lines changed
700 examine changes to 'subdir/f2'? [Ynesfdaq?] abort: response expected
700 examine changes to 'subdir/f2'? [Ynesfdaq?] abort: response expected
701 [255]
701 [255]
702
702
703 No
703 No
704
704
705 $ hg record <<EOF
705 $ hg record <<EOF
706 > n
706 > n
707 > EOF
707 > EOF
708 diff --git a/subdir/f1 b/subdir/f1
708 diff --git a/subdir/f1 b/subdir/f1
709 1 hunks, 1 lines changed
709 1 hunks, 1 lines changed
710 examine changes to 'subdir/f1'? [Ynesfdaq?]
710 examine changes to 'subdir/f1'? [Ynesfdaq?]
711 diff --git a/subdir/f2 b/subdir/f2
711 diff --git a/subdir/f2 b/subdir/f2
712 1 hunks, 1 lines changed
712 1 hunks, 1 lines changed
713 examine changes to 'subdir/f2'? [Ynesfdaq?] abort: response expected
713 examine changes to 'subdir/f2'? [Ynesfdaq?] abort: response expected
714 [255]
714 [255]
715
715
716 f, quit
716 f, quit
717
717
718 $ hg record <<EOF
718 $ hg record <<EOF
719 > f
719 > f
720 > q
720 > q
721 > EOF
721 > EOF
722 diff --git a/subdir/f1 b/subdir/f1
722 diff --git a/subdir/f1 b/subdir/f1
723 1 hunks, 1 lines changed
723 1 hunks, 1 lines changed
724 examine changes to 'subdir/f1'? [Ynesfdaq?]
724 examine changes to 'subdir/f1'? [Ynesfdaq?]
725 diff --git a/subdir/f2 b/subdir/f2
725 diff --git a/subdir/f2 b/subdir/f2
726 1 hunks, 1 lines changed
726 1 hunks, 1 lines changed
727 examine changes to 'subdir/f2'? [Ynesfdaq?]
727 examine changes to 'subdir/f2'? [Ynesfdaq?]
728 abort: user quit
728 abort: user quit
729 [255]
729 [255]
730
730
731 s, all
731 s, all
732
732
733 $ hg record -d '18 0' -mx <<EOF
733 $ hg record -d '18 0' -mx <<EOF
734 > s
734 > s
735 > a
735 > a
736 > EOF
736 > EOF
737 diff --git a/subdir/f1 b/subdir/f1
737 diff --git a/subdir/f1 b/subdir/f1
738 1 hunks, 1 lines changed
738 1 hunks, 1 lines changed
739 examine changes to 'subdir/f1'? [Ynesfdaq?]
739 examine changes to 'subdir/f1'? [Ynesfdaq?]
740 diff --git a/subdir/f2 b/subdir/f2
740 diff --git a/subdir/f2 b/subdir/f2
741 1 hunks, 1 lines changed
741 1 hunks, 1 lines changed
742 examine changes to 'subdir/f2'? [Ynesfdaq?]
742 examine changes to 'subdir/f2'? [Ynesfdaq?]
743
743
744 $ hg tip -p
744 $ hg tip -p
745 changeset: 20:b3df3dda369a
745 changeset: 20:b3df3dda369a
746 tag: tip
746 tag: tip
747 user: test
747 user: test
748 date: Thu Jan 01 00:00:18 1970 +0000
748 date: Thu Jan 01 00:00:18 1970 +0000
749 summary: x
749 summary: x
750
750
751 diff -r 6e02d6c9906d -r b3df3dda369a subdir/f2
751 diff -r 6e02d6c9906d -r b3df3dda369a subdir/f2
752 --- a/subdir/f2 Thu Jan 01 00:00:17 1970 +0000
752 --- a/subdir/f2 Thu Jan 01 00:00:17 1970 +0000
753 +++ b/subdir/f2 Thu Jan 01 00:00:18 1970 +0000
753 +++ b/subdir/f2 Thu Jan 01 00:00:18 1970 +0000
754 @@ -1,1 +1,2 @@
754 @@ -1,1 +1,2 @@
755 b
755 b
756 +b
756 +b
757
757
758
758
759 f
759 f
760
760
761 $ hg record -d '19 0' -my <<EOF
761 $ hg record -d '19 0' -my <<EOF
762 > f
762 > f
763 > EOF
763 > EOF
764 diff --git a/subdir/f1 b/subdir/f1
764 diff --git a/subdir/f1 b/subdir/f1
765 1 hunks, 1 lines changed
765 1 hunks, 1 lines changed
766 examine changes to 'subdir/f1'? [Ynesfdaq?]
766 examine changes to 'subdir/f1'? [Ynesfdaq?]
767
767
768 $ hg tip -p
768 $ hg tip -p
769 changeset: 21:38ec577f126b
769 changeset: 21:38ec577f126b
770 tag: tip
770 tag: tip
771 user: test
771 user: test
772 date: Thu Jan 01 00:00:19 1970 +0000
772 date: Thu Jan 01 00:00:19 1970 +0000
773 summary: y
773 summary: y
774
774
775 diff -r b3df3dda369a -r 38ec577f126b subdir/f1
775 diff -r b3df3dda369a -r 38ec577f126b subdir/f1
776 --- a/subdir/f1 Thu Jan 01 00:00:18 1970 +0000
776 --- a/subdir/f1 Thu Jan 01 00:00:18 1970 +0000
777 +++ b/subdir/f1 Thu Jan 01 00:00:19 1970 +0000
777 +++ b/subdir/f1 Thu Jan 01 00:00:19 1970 +0000
778 @@ -1,1 +1,2 @@
778 @@ -1,1 +1,2 @@
779 a
779 a
780 +a
780 +a
781
781
782
782
783 #if execbit
783 #if execbit
784
784
785 Preserve chmod +x
785 Preserve chmod +x
786
786
787 $ chmod +x f1
787 $ chmod +x f1
788 $ echo a >> f1
788 $ echo a >> f1
789 $ hg record -d '20 0' -mz <<EOF
789 $ hg record -d '20 0' -mz <<EOF
790 > y
790 > y
791 > y
791 > y
792 > y
792 > y
793 > EOF
793 > EOF
794 diff --git a/subdir/f1 b/subdir/f1
794 diff --git a/subdir/f1 b/subdir/f1
795 old mode 100644
795 old mode 100644
796 new mode 100755
796 new mode 100755
797 1 hunks, 1 lines changed
797 1 hunks, 1 lines changed
798 examine changes to 'subdir/f1'? [Ynesfdaq?]
798 examine changes to 'subdir/f1'? [Ynesfdaq?]
799 @@ -1,2 +1,3 @@
799 @@ -1,2 +1,3 @@
800 a
800 a
801 a
801 a
802 +a
802 +a
803 record this change to 'subdir/f1'? [Ynesfdaq?]
803 record this change to 'subdir/f1'? [Ynesfdaq?]
804
804
805 $ hg tip --config diff.git=True -p
805 $ hg tip --config diff.git=True -p
806 changeset: 22:3261adceb075
806 changeset: 22:3261adceb075
807 tag: tip
807 tag: tip
808 user: test
808 user: test
809 date: Thu Jan 01 00:00:20 1970 +0000
809 date: Thu Jan 01 00:00:20 1970 +0000
810 summary: z
810 summary: z
811
811
812 diff --git a/subdir/f1 b/subdir/f1
812 diff --git a/subdir/f1 b/subdir/f1
813 old mode 100644
813 old mode 100644
814 new mode 100755
814 new mode 100755
815 --- a/subdir/f1
815 --- a/subdir/f1
816 +++ b/subdir/f1
816 +++ b/subdir/f1
817 @@ -1,2 +1,3 @@
817 @@ -1,2 +1,3 @@
818 a
818 a
819 a
819 a
820 +a
820 +a
821
821
822
822
823 Preserve execute permission on original
823 Preserve execute permission on original
824
824
825 $ echo b >> f1
825 $ echo b >> f1
826 $ hg record -d '21 0' -maa <<EOF
826 $ hg record -d '21 0' -maa <<EOF
827 > y
827 > y
828 > y
828 > y
829 > y
829 > y
830 > EOF
830 > EOF
831 diff --git a/subdir/f1 b/subdir/f1
831 diff --git a/subdir/f1 b/subdir/f1
832 1 hunks, 1 lines changed
832 1 hunks, 1 lines changed
833 examine changes to 'subdir/f1'? [Ynesfdaq?]
833 examine changes to 'subdir/f1'? [Ynesfdaq?]
834 @@ -1,3 +1,4 @@
834 @@ -1,3 +1,4 @@
835 a
835 a
836 a
836 a
837 a
837 a
838 +b
838 +b
839 record this change to 'subdir/f1'? [Ynesfdaq?]
839 record this change to 'subdir/f1'? [Ynesfdaq?]
840
840
841 $ hg tip --config diff.git=True -p
841 $ hg tip --config diff.git=True -p
842 changeset: 23:b429867550db
842 changeset: 23:b429867550db
843 tag: tip
843 tag: tip
844 user: test
844 user: test
845 date: Thu Jan 01 00:00:21 1970 +0000
845 date: Thu Jan 01 00:00:21 1970 +0000
846 summary: aa
846 summary: aa
847
847
848 diff --git a/subdir/f1 b/subdir/f1
848 diff --git a/subdir/f1 b/subdir/f1
849 --- a/subdir/f1
849 --- a/subdir/f1
850 +++ b/subdir/f1
850 +++ b/subdir/f1
851 @@ -1,3 +1,4 @@
851 @@ -1,3 +1,4 @@
852 a
852 a
853 a
853 a
854 a
854 a
855 +b
855 +b
856
856
857
857
858 Preserve chmod -x
858 Preserve chmod -x
859
859
860 $ chmod -x f1
860 $ chmod -x f1
861 $ echo c >> f1
861 $ echo c >> f1
862 $ hg record -d '22 0' -mab <<EOF
862 $ hg record -d '22 0' -mab <<EOF
863 > y
863 > y
864 > y
864 > y
865 > y
865 > y
866 > EOF
866 > EOF
867 diff --git a/subdir/f1 b/subdir/f1
867 diff --git a/subdir/f1 b/subdir/f1
868 old mode 100755
868 old mode 100755
869 new mode 100644
869 new mode 100644
870 1 hunks, 1 lines changed
870 1 hunks, 1 lines changed
871 examine changes to 'subdir/f1'? [Ynesfdaq?]
871 examine changes to 'subdir/f1'? [Ynesfdaq?]
872 @@ -2,3 +2,4 @@
872 @@ -2,3 +2,4 @@
873 a
873 a
874 a
874 a
875 b
875 b
876 +c
876 +c
877 record this change to 'subdir/f1'? [Ynesfdaq?]
877 record this change to 'subdir/f1'? [Ynesfdaq?]
878
878
879 $ hg tip --config diff.git=True -p
879 $ hg tip --config diff.git=True -p
880 changeset: 24:0b082130c20a
880 changeset: 24:0b082130c20a
881 tag: tip
881 tag: tip
882 user: test
882 user: test
883 date: Thu Jan 01 00:00:22 1970 +0000
883 date: Thu Jan 01 00:00:22 1970 +0000
884 summary: ab
884 summary: ab
885
885
886 diff --git a/subdir/f1 b/subdir/f1
886 diff --git a/subdir/f1 b/subdir/f1
887 old mode 100755
887 old mode 100755
888 new mode 100644
888 new mode 100644
889 --- a/subdir/f1
889 --- a/subdir/f1
890 +++ b/subdir/f1
890 +++ b/subdir/f1
891 @@ -2,3 +2,4 @@
891 @@ -2,3 +2,4 @@
892 a
892 a
893 a
893 a
894 b
894 b
895 +c
895 +c
896
896
897
897
898 #else
898 #else
899
899
900 Slightly bogus tests to get almost same repo structure as when x bit is used
900 Slightly bogus tests to get almost same repo structure as when x bit is used
901 - but with different hashes.
901 - but with different hashes.
902
902
903 Mock "Preserve chmod +x"
903 Mock "Preserve chmod +x"
904
904
905 $ echo a >> f1
905 $ echo a >> f1
906 $ hg record -d '20 0' -mz <<EOF
906 $ hg record -d '20 0' -mz <<EOF
907 > y
907 > y
908 > y
908 > y
909 > y
909 > y
910 > EOF
910 > EOF
911 diff --git a/subdir/f1 b/subdir/f1
911 diff --git a/subdir/f1 b/subdir/f1
912 1 hunks, 1 lines changed
912 1 hunks, 1 lines changed
913 examine changes to 'subdir/f1'? [Ynesfdaq?]
913 examine changes to 'subdir/f1'? [Ynesfdaq?]
914 @@ -1,2 +1,3 @@
914 @@ -1,2 +1,3 @@
915 a
915 a
916 a
916 a
917 +a
917 +a
918 record this change to 'subdir/f1'? [Ynesfdaq?]
918 record this change to 'subdir/f1'? [Ynesfdaq?]
919
919
920 $ hg tip --config diff.git=True -p
920 $ hg tip --config diff.git=True -p
921 changeset: 22:0d463bd428f5
921 changeset: 22:0d463bd428f5
922 tag: tip
922 tag: tip
923 user: test
923 user: test
924 date: Thu Jan 01 00:00:20 1970 +0000
924 date: Thu Jan 01 00:00:20 1970 +0000
925 summary: z
925 summary: z
926
926
927 diff --git a/subdir/f1 b/subdir/f1
927 diff --git a/subdir/f1 b/subdir/f1
928 --- a/subdir/f1
928 --- a/subdir/f1
929 +++ b/subdir/f1
929 +++ b/subdir/f1
930 @@ -1,2 +1,3 @@
930 @@ -1,2 +1,3 @@
931 a
931 a
932 a
932 a
933 +a
933 +a
934
934
935
935
936 Mock "Preserve execute permission on original"
936 Mock "Preserve execute permission on original"
937
937
938 $ echo b >> f1
938 $ echo b >> f1
939 $ hg record -d '21 0' -maa <<EOF
939 $ hg record -d '21 0' -maa <<EOF
940 > y
940 > y
941 > y
941 > y
942 > y
942 > y
943 > EOF
943 > EOF
944 diff --git a/subdir/f1 b/subdir/f1
944 diff --git a/subdir/f1 b/subdir/f1
945 1 hunks, 1 lines changed
945 1 hunks, 1 lines changed
946 examine changes to 'subdir/f1'? [Ynesfdaq?]
946 examine changes to 'subdir/f1'? [Ynesfdaq?]
947 @@ -1,3 +1,4 @@
947 @@ -1,3 +1,4 @@
948 a
948 a
949 a
949 a
950 a
950 a
951 +b
951 +b
952 record this change to 'subdir/f1'? [Ynesfdaq?]
952 record this change to 'subdir/f1'? [Ynesfdaq?]
953
953
954 $ hg tip --config diff.git=True -p
954 $ hg tip --config diff.git=True -p
955 changeset: 23:0eab41a3e524
955 changeset: 23:0eab41a3e524
956 tag: tip
956 tag: tip
957 user: test
957 user: test
958 date: Thu Jan 01 00:00:21 1970 +0000
958 date: Thu Jan 01 00:00:21 1970 +0000
959 summary: aa
959 summary: aa
960
960
961 diff --git a/subdir/f1 b/subdir/f1
961 diff --git a/subdir/f1 b/subdir/f1
962 --- a/subdir/f1
962 --- a/subdir/f1
963 +++ b/subdir/f1
963 +++ b/subdir/f1
964 @@ -1,3 +1,4 @@
964 @@ -1,3 +1,4 @@
965 a
965 a
966 a
966 a
967 a
967 a
968 +b
968 +b
969
969
970
970
971 Mock "Preserve chmod -x"
971 Mock "Preserve chmod -x"
972
972
973 $ chmod -x f1
973 $ chmod -x f1
974 $ echo c >> f1
974 $ echo c >> f1
975 $ hg record -d '22 0' -mab <<EOF
975 $ hg record -d '22 0' -mab <<EOF
976 > y
976 > y
977 > y
977 > y
978 > y
978 > y
979 > EOF
979 > EOF
980 diff --git a/subdir/f1 b/subdir/f1
980 diff --git a/subdir/f1 b/subdir/f1
981 1 hunks, 1 lines changed
981 1 hunks, 1 lines changed
982 examine changes to 'subdir/f1'? [Ynesfdaq?]
982 examine changes to 'subdir/f1'? [Ynesfdaq?]
983 @@ -2,3 +2,4 @@
983 @@ -2,3 +2,4 @@
984 a
984 a
985 a
985 a
986 b
986 b
987 +c
987 +c
988 record this change to 'subdir/f1'? [Ynesfdaq?]
988 record this change to 'subdir/f1'? [Ynesfdaq?]
989
989
990 $ hg tip --config diff.git=True -p
990 $ hg tip --config diff.git=True -p
991 changeset: 24:f4f718f27b7c
991 changeset: 24:f4f718f27b7c
992 tag: tip
992 tag: tip
993 user: test
993 user: test
994 date: Thu Jan 01 00:00:22 1970 +0000
994 date: Thu Jan 01 00:00:22 1970 +0000
995 summary: ab
995 summary: ab
996
996
997 diff --git a/subdir/f1 b/subdir/f1
997 diff --git a/subdir/f1 b/subdir/f1
998 --- a/subdir/f1
998 --- a/subdir/f1
999 +++ b/subdir/f1
999 +++ b/subdir/f1
1000 @@ -2,3 +2,4 @@
1000 @@ -2,3 +2,4 @@
1001 a
1001 a
1002 a
1002 a
1003 b
1003 b
1004 +c
1004 +c
1005
1005
1006
1006
1007 #endif
1007 #endif
1008
1008
1009 $ cd ..
1009 $ cd ..
1010
1010
1011
1011
1012 Abort early when a merge is in progress
1012 Abort early when a merge is in progress
1013
1013
1014 $ hg up 4
1014 $ hg up 4
1015 1 files updated, 0 files merged, 6 files removed, 0 files unresolved
1015 1 files updated, 0 files merged, 6 files removed, 0 files unresolved
1016
1016
1017 $ touch iwillmergethat
1017 $ touch iwillmergethat
1018 $ hg add iwillmergethat
1018 $ hg add iwillmergethat
1019
1019
1020 $ hg branch thatbranch
1020 $ hg branch thatbranch
1021 marked working directory as branch thatbranch
1021 marked working directory as branch thatbranch
1022 (branches are permanent and global, did you want a bookmark?)
1022 (branches are permanent and global, did you want a bookmark?)
1023
1023
1024 $ hg ci -m'new head'
1024 $ hg ci -m'new head'
1025
1025
1026 $ hg up default
1026 $ hg up default
1027 6 files updated, 0 files merged, 2 files removed, 0 files unresolved
1027 6 files updated, 0 files merged, 2 files removed, 0 files unresolved
1028
1028
1029 $ hg merge thatbranch
1029 $ hg merge thatbranch
1030 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1030 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1031 (branch merge, don't forget to commit)
1031 (branch merge, don't forget to commit)
1032
1032
1033 $ hg record -m'will abort'
1033 $ hg record -m'will abort'
1034 abort: cannot partially commit a merge (use "hg commit" instead)
1034 abort: cannot partially commit a merge (use "hg commit" instead)
1035 [255]
1035 [255]
1036
1036
1037 $ hg up -C
1037 $ hg up -C
1038 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1038 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1039
1039
1040 Editing patch (and ignoring trailing text)
1040 Editing patch (and ignoring trailing text)
1041
1041
1042 $ cat > editor.sh << '__EOF__'
1042 $ cat > editor.sh << '__EOF__'
1043 > sed -e 7d -e '5s/^-/ /' -e '/^# ---/i\
1043 > sed -e 7d -e '5s/^-/ /' -e '/^# ---/i\
1044 > trailing\nditto' "$1" > tmp
1044 > trailing\nditto' "$1" > tmp
1045 > mv tmp "$1"
1045 > mv tmp "$1"
1046 > __EOF__
1046 > __EOF__
1047 $ cat > editedfile << '__EOF__'
1047 $ cat > editedfile << '__EOF__'
1048 > This is the first line
1048 > This is the first line
1049 > This is the second line
1049 > This is the second line
1050 > This is the third line
1050 > This is the third line
1051 > __EOF__
1051 > __EOF__
1052 $ hg add editedfile
1052 $ hg add editedfile
1053 $ hg commit -medit-patch-1
1053 $ hg commit -medit-patch-1
1054 $ cat > editedfile << '__EOF__'
1054 $ cat > editedfile << '__EOF__'
1055 > This line has changed
1055 > This line has changed
1056 > This change will be committed
1056 > This change will be committed
1057 > This is the third line
1057 > This is the third line
1058 > __EOF__
1058 > __EOF__
1059 $ HGEDITOR="\"sh\" \"`pwd`/editor.sh\"" hg record -d '23 0' -medit-patch-2 <<EOF
1059 $ HGEDITOR="\"sh\" \"`pwd`/editor.sh\"" hg record -d '23 0' -medit-patch-2 <<EOF
1060 > y
1060 > y
1061 > e
1061 > e
1062 > EOF
1062 > EOF
1063 diff --git a/editedfile b/editedfile
1063 diff --git a/editedfile b/editedfile
1064 1 hunks, 2 lines changed
1064 1 hunks, 2 lines changed
1065 examine changes to 'editedfile'? [Ynesfdaq?]
1065 examine changes to 'editedfile'? [Ynesfdaq?]
1066 @@ -1,3 +1,3 @@
1066 @@ -1,3 +1,3 @@
1067 -This is the first line
1067 -This is the first line
1068 -This is the second line
1068 -This is the second line
1069 +This line has changed
1069 +This line has changed
1070 +This change will be committed
1070 +This change will be committed
1071 This is the third line
1071 This is the third line
1072 record this change to 'editedfile'? [Ynesfdaq?]
1072 record this change to 'editedfile'? [Ynesfdaq?]
1073 $ cat editedfile
1073 $ cat editedfile
1074 This line has changed
1074 This line has changed
1075 This change will be committed
1075 This change will be committed
1076 This is the third line
1076 This is the third line
1077 $ hg cat -r tip editedfile
1077 $ hg cat -r tip editedfile
1078 This is the first line
1078 This is the first line
1079 This change will be committed
1079 This change will be committed
1080 This is the third line
1080 This is the third line
1081 $ hg revert editedfile
1081 $ hg revert editedfile
1082
1082
1083 Trying to edit patch for whole file
1083 Trying to edit patch for whole file
1084
1084
1085 $ echo "This is the fourth line" >> editedfile
1085 $ echo "This is the fourth line" >> editedfile
1086 $ hg record <<EOF
1086 $ hg record <<EOF
1087 > e
1087 > e
1088 > q
1088 > q
1089 > EOF
1089 > EOF
1090 diff --git a/editedfile b/editedfile
1090 diff --git a/editedfile b/editedfile
1091 1 hunks, 1 lines changed
1091 1 hunks, 1 lines changed
1092 examine changes to 'editedfile'? [Ynesfdaq?]
1092 examine changes to 'editedfile'? [Ynesfdaq?]
1093 cannot edit patch for whole file
1093 cannot edit patch for whole file
1094 examine changes to 'editedfile'? [Ynesfdaq?]
1094 examine changes to 'editedfile'? [Ynesfdaq?]
1095 abort: user quit
1095 abort: user quit
1096 [255]
1096 [255]
1097 $ hg revert editedfile
1097 $ hg revert editedfile
1098
1098
1099 Removing changes from patch
1099 Removing changes from patch
1100
1100
1101 $ sed -e '3s/third/second/' -e '2s/will/will not/' -e 1d editedfile > tmp
1101 $ sed -e '3s/third/second/' -e '2s/will/will not/' -e 1d editedfile > tmp
1102 $ mv tmp editedfile
1102 $ mv tmp editedfile
1103 $ echo "This line has been added" >> editedfile
1103 $ echo "This line has been added" >> editedfile
1104 $ cat > editor.sh << '__EOF__'
1104 $ cat > editor.sh << '__EOF__'
1105 > sed -e 's/^[-+]/ /' "$1" > tmp
1105 > sed -e 's/^[-+]/ /' "$1" > tmp
1106 > mv tmp "$1"
1106 > mv tmp "$1"
1107 > __EOF__
1107 > __EOF__
1108 $ HGEDITOR="\"sh\" \"`pwd`/editor.sh\"" hg record <<EOF
1108 $ HGEDITOR="\"sh\" \"`pwd`/editor.sh\"" hg record <<EOF
1109 > y
1109 > y
1110 > e
1110 > e
1111 > EOF
1111 > EOF
1112 diff --git a/editedfile b/editedfile
1112 diff --git a/editedfile b/editedfile
1113 1 hunks, 3 lines changed
1113 1 hunks, 3 lines changed
1114 examine changes to 'editedfile'? [Ynesfdaq?]
1114 examine changes to 'editedfile'? [Ynesfdaq?]
1115 @@ -1,3 +1,3 @@
1115 @@ -1,3 +1,3 @@
1116 -This is the first line
1116 -This is the first line
1117 -This change will be committed
1117 -This change will be committed
1118 -This is the third line
1118 -This is the third line
1119 +This change will not be committed
1119 +This change will not be committed
1120 +This is the second line
1120 +This is the second line
1121 +This line has been added
1121 +This line has been added
1122 record this change to 'editedfile'? [Ynesfdaq?]
1122 record this change to 'editedfile'? [Ynesfdaq?]
1123 no changes to record
1123 no changes to record
1124 $ cat editedfile
1124 $ cat editedfile
1125 This change will not be committed
1125 This change will not be committed
1126 This is the second line
1126 This is the second line
1127 This line has been added
1127 This line has been added
1128 $ hg cat -r tip editedfile
1128 $ hg cat -r tip editedfile
1129 This is the first line
1129 This is the first line
1130 This change will be committed
1130 This change will be committed
1131 This is the third line
1131 This is the third line
1132 $ hg revert editedfile
1132 $ hg revert editedfile
1133
1133
1134 Invalid patch
1134 Invalid patch
1135
1135
1136 $ sed -e '3s/third/second/' -e '2s/will/will not/' -e 1d editedfile > tmp
1136 $ sed -e '3s/third/second/' -e '2s/will/will not/' -e 1d editedfile > tmp
1137 $ mv tmp editedfile
1137 $ mv tmp editedfile
1138 $ echo "This line has been added" >> editedfile
1138 $ echo "This line has been added" >> editedfile
1139 $ cat > editor.sh << '__EOF__'
1139 $ cat > editor.sh << '__EOF__'
1140 > sed s/This/That/ "$1" > tmp
1140 > sed s/This/That/ "$1" > tmp
1141 > mv tmp "$1"
1141 > mv tmp "$1"
1142 > __EOF__
1142 > __EOF__
1143 $ HGEDITOR="\"sh\" \"`pwd`/editor.sh\"" hg record <<EOF
1143 $ HGEDITOR="\"sh\" \"`pwd`/editor.sh\"" hg record <<EOF
1144 > y
1144 > y
1145 > e
1145 > e
1146 > EOF
1146 > EOF
1147 diff --git a/editedfile b/editedfile
1147 diff --git a/editedfile b/editedfile
1148 1 hunks, 3 lines changed
1148 1 hunks, 3 lines changed
1149 examine changes to 'editedfile'? [Ynesfdaq?]
1149 examine changes to 'editedfile'? [Ynesfdaq?]
1150 @@ -1,3 +1,3 @@
1150 @@ -1,3 +1,3 @@
1151 -This is the first line
1151 -This is the first line
1152 -This change will be committed
1152 -This change will be committed
1153 -This is the third line
1153 -This is the third line
1154 +This change will not be committed
1154 +This change will not be committed
1155 +This is the second line
1155 +This is the second line
1156 +This line has been added
1156 +This line has been added
1157 record this change to 'editedfile'? [Ynesfdaq?]
1157 record this change to 'editedfile'? [Ynesfdaq?]
1158 patching file editedfile
1158 patching file editedfile
1159 Hunk #1 FAILED at 0
1159 Hunk #1 FAILED at 0
1160 1 out of 1 hunks FAILED -- saving rejects to file editedfile.rej
1160 1 out of 1 hunks FAILED -- saving rejects to file editedfile.rej
1161 abort: patch failed to apply
1161 abort: patch failed to apply
1162 [255]
1162 [255]
1163 $ cat editedfile
1163 $ cat editedfile
1164 This change will not be committed
1164 This change will not be committed
1165 This is the second line
1165 This is the second line
1166 This line has been added
1166 This line has been added
1167 $ hg cat -r tip editedfile
1167 $ hg cat -r tip editedfile
1168 This is the first line
1168 This is the first line
1169 This change will be committed
1169 This change will be committed
1170 This is the third line
1170 This is the third line
1171 $ cat editedfile.rej
1171 $ cat editedfile.rej
1172 --- editedfile
1172 --- editedfile
1173 +++ editedfile
1173 +++ editedfile
1174 @@ -1,3 +1,3 @@
1174 @@ -1,3 +1,3 @@
1175 -That is the first line
1175 -That is the first line
1176 -That change will be committed
1176 -That change will be committed
1177 -That is the third line
1177 -That is the third line
1178 +That change will not be committed
1178 +That change will not be committed
1179 +That is the second line
1179 +That is the second line
1180 +That line has been added
1180 +That line has been added
1181
1181
1182 Malformed patch - error handling
1182 Malformed patch - error handling
1183
1183
1184 $ cat > editor.sh << '__EOF__'
1184 $ cat > editor.sh << '__EOF__'
1185 > sed -e '/^@/p' "$1" > tmp
1185 > sed -e '/^@/p' "$1" > tmp
1186 > mv tmp "$1"
1186 > mv tmp "$1"
1187 > __EOF__
1187 > __EOF__
1188 $ HGEDITOR="\"sh\" \"`pwd`/editor.sh\"" hg record <<EOF
1188 $ HGEDITOR="\"sh\" \"`pwd`/editor.sh\"" hg record <<EOF
1189 > y
1189 > y
1190 > e
1190 > e
1191 > EOF
1191 > EOF
1192 diff --git a/editedfile b/editedfile
1192 diff --git a/editedfile b/editedfile
1193 1 hunks, 3 lines changed
1193 1 hunks, 3 lines changed
1194 examine changes to 'editedfile'? [Ynesfdaq?]
1194 examine changes to 'editedfile'? [Ynesfdaq?]
1195 @@ -1,3 +1,3 @@
1195 @@ -1,3 +1,3 @@
1196 -This is the first line
1196 -This is the first line
1197 -This change will be committed
1197 -This change will be committed
1198 -This is the third line
1198 -This is the third line
1199 +This change will not be committed
1199 +This change will not be committed
1200 +This is the second line
1200 +This is the second line
1201 +This line has been added
1201 +This line has been added
1202 record this change to 'editedfile'? [Ynesfdaq?]
1202 record this change to 'editedfile'? [Ynesfdaq?]
1203 abort: error parsing patch: unhandled transition: range -> range
1203 abort: error parsing patch: unhandled transition: range -> range
1204 [255]
1204 [255]
1205
1205
1206 random text in random positions is still an error
1206 random text in random positions is still an error
1207
1207
1208 $ cat > editor.sh << '__EOF__'
1208 $ cat > editor.sh << '__EOF__'
1209 > sed -e '/^@/i\
1209 > sed -e '/^@/i\
1210 > other' "$1" > tmp
1210 > other' "$1" > tmp
1211 > mv tmp "$1"
1211 > mv tmp "$1"
1212 > __EOF__
1212 > __EOF__
1213 $ HGEDITOR="\"sh\" \"`pwd`/editor.sh\"" hg record <<EOF
1213 $ HGEDITOR="\"sh\" \"`pwd`/editor.sh\"" hg record <<EOF
1214 > y
1214 > y
1215 > e
1215 > e
1216 > EOF
1216 > EOF
1217 diff --git a/editedfile b/editedfile
1217 diff --git a/editedfile b/editedfile
1218 1 hunks, 3 lines changed
1218 1 hunks, 3 lines changed
1219 examine changes to 'editedfile'? [Ynesfdaq?]
1219 examine changes to 'editedfile'? [Ynesfdaq?]
1220 @@ -1,3 +1,3 @@
1220 @@ -1,3 +1,3 @@
1221 -This is the first line
1221 -This is the first line
1222 -This change will be committed
1222 -This change will be committed
1223 -This is the third line
1223 -This is the third line
1224 +This change will not be committed
1224 +This change will not be committed
1225 +This is the second line
1225 +This is the second line
1226 +This line has been added
1226 +This line has been added
1227 record this change to 'editedfile'? [Ynesfdaq?]
1227 record this change to 'editedfile'? [Ynesfdaq?]
1228 abort: error parsing patch: unhandled transition: file -> other
1228 abort: error parsing patch: unhandled transition: file -> other
1229 [255]
1229 [255]
1230
1230
1231 $ hg up -C
1231 $ hg up -C
1232 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1232 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1233
1233
1234 With win32text
1234 With win32text
1235
1235
1236 $ echo '[extensions]' >> .hg/hgrc
1236 $ echo '[extensions]' >> .hg/hgrc
1237 $ echo 'win32text = ' >> .hg/hgrc
1237 $ echo 'win32text = ' >> .hg/hgrc
1238 $ echo '[decode]' >> .hg/hgrc
1238 $ echo '[decode]' >> .hg/hgrc
1239 $ echo '** = cleverdecode:' >> .hg/hgrc
1239 $ echo '** = cleverdecode:' >> .hg/hgrc
1240 $ echo '[encode]' >> .hg/hgrc
1240 $ echo '[encode]' >> .hg/hgrc
1241 $ echo '** = cleverencode:' >> .hg/hgrc
1241 $ echo '** = cleverencode:' >> .hg/hgrc
1242 $ echo '[patch]' >> .hg/hgrc
1242 $ echo '[patch]' >> .hg/hgrc
1243 $ echo 'eol = crlf' >> .hg/hgrc
1243 $ echo 'eol = crlf' >> .hg/hgrc
1244
1244
1245 Ignore win32text deprecation warning for now:
1245 Ignore win32text deprecation warning for now:
1246
1246
1247 $ echo '[win32text]' >> .hg/hgrc
1247 $ echo '[win32text]' >> .hg/hgrc
1248 $ echo 'warn = no' >> .hg/hgrc
1248 $ echo 'warn = no' >> .hg/hgrc
1249
1249
1250 $ echo d >> subdir/f1
1250 $ echo d >> subdir/f1
1251 $ hg record -d '24 0' -mw1 <<EOF
1251 $ hg record -d '24 0' -mw1 <<EOF
1252 > y
1252 > y
1253 > y
1253 > y
1254 > EOF
1254 > EOF
1255 diff --git a/subdir/f1 b/subdir/f1
1255 diff --git a/subdir/f1 b/subdir/f1
1256 1 hunks, 1 lines changed
1256 1 hunks, 1 lines changed
1257 examine changes to 'subdir/f1'? [Ynesfdaq?]
1257 examine changes to 'subdir/f1'? [Ynesfdaq?]
1258 @@ -3,3 +3,4 @@
1258 @@ -3,3 +3,4 @@
1259 a
1259 a
1260 b
1260 b
1261 c
1261 c
1262 +d
1262 +d
1263 record this change to 'subdir/f1'? [Ynesfdaq?]
1263 record this change to 'subdir/f1'? [Ynesfdaq?]
1264
1264
1265 $ hg tip -p
1265 $ hg tip -p
1266 changeset: 28:* (glob)
1266 changeset: 28:* (glob)
1267 tag: tip
1267 tag: tip
1268 user: test
1268 user: test
1269 date: Thu Jan 01 00:00:24 1970 +0000
1269 date: Thu Jan 01 00:00:24 1970 +0000
1270 summary: w1
1270 summary: w1
1271
1271
1272 diff -r ???????????? -r ???????????? subdir/f1 (glob)
1272 diff -r ???????????? -r ???????????? subdir/f1 (glob)
1273 --- a/subdir/f1 Thu Jan 01 00:00:23 1970 +0000
1273 --- a/subdir/f1 Thu Jan 01 00:00:23 1970 +0000
1274 +++ b/subdir/f1 Thu Jan 01 00:00:24 1970 +0000
1274 +++ b/subdir/f1 Thu Jan 01 00:00:24 1970 +0000
1275 @@ -3,3 +3,4 @@
1275 @@ -3,3 +3,4 @@
1276 a
1276 a
1277 b
1277 b
1278 c
1278 c
1279 +d
1279 +d
1280
1280
1281 Test --user when ui.username not set
1281 Test --user when ui.username not set
1282 $ unset HGUSER
1282 $ unset HGUSER
1283 $ echo e >> subdir/f1
1283 $ echo e >> subdir/f1
1284 $ hg record --config ui.username= -d '8 0' --user xyz -m "user flag" <<EOF
1284 $ hg record --config ui.username= -d '8 0' --user xyz -m "user flag" <<EOF
1285 > y
1285 > y
1286 > y
1286 > y
1287 > EOF
1287 > EOF
1288 diff --git a/subdir/f1 b/subdir/f1
1288 diff --git a/subdir/f1 b/subdir/f1
1289 1 hunks, 1 lines changed
1289 1 hunks, 1 lines changed
1290 examine changes to 'subdir/f1'? [Ynesfdaq?]
1290 examine changes to 'subdir/f1'? [Ynesfdaq?]
1291 @@ -4,3 +4,4 @@
1291 @@ -4,3 +4,4 @@
1292 b
1292 b
1293 c
1293 c
1294 d
1294 d
1295 +e
1295 +e
1296 record this change to 'subdir/f1'? [Ynesfdaq?]
1296 record this change to 'subdir/f1'? [Ynesfdaq?]
1297 $ hg log --template '{author}\n' -l 1
1297 $ hg log --template '{author}\n' -l 1
1298 xyz
1298 xyz
1299 $ HGUSER="test"
1299 $ HGUSER="test"
1300 $ export HGUSER
1300 $ export HGUSER
1301
1301
1302 $ cd ..
1302 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now