##// END OF EJS Templates
color: respect HGPLAINEXCEPT=color to allow colors while scripting (issue5749)...
Augie Fackler -
r35176:d4805a5e default
parent child Browse files
Show More
@@ -1,518 +1,518
1 1 # utility for color output for Mercurial commands
2 2 #
3 3 # Copyright (C) 2007 Kevin Christen <kevin.christen@gmail.com> and other
4 4 #
5 5 # This software may be used and distributed according to the terms of the
6 6 # GNU General Public License version 2 or any later version.
7 7
8 8 from __future__ import absolute_import
9 9
10 10 import re
11 11
12 12 from .i18n import _
13 13
14 14 from . import (
15 15 encoding,
16 16 pycompat,
17 17 util
18 18 )
19 19
20 20 try:
21 21 import curses
22 22 # Mapping from effect name to terminfo attribute name (or raw code) or
23 23 # color number. This will also force-load the curses module.
24 24 _baseterminfoparams = {
25 25 'none': (True, 'sgr0', ''),
26 26 'standout': (True, 'smso', ''),
27 27 'underline': (True, 'smul', ''),
28 28 'reverse': (True, 'rev', ''),
29 29 'inverse': (True, 'rev', ''),
30 30 'blink': (True, 'blink', ''),
31 31 'dim': (True, 'dim', ''),
32 32 'bold': (True, 'bold', ''),
33 33 'invisible': (True, 'invis', ''),
34 34 'italic': (True, 'sitm', ''),
35 35 'black': (False, curses.COLOR_BLACK, ''),
36 36 'red': (False, curses.COLOR_RED, ''),
37 37 'green': (False, curses.COLOR_GREEN, ''),
38 38 'yellow': (False, curses.COLOR_YELLOW, ''),
39 39 'blue': (False, curses.COLOR_BLUE, ''),
40 40 'magenta': (False, curses.COLOR_MAGENTA, ''),
41 41 'cyan': (False, curses.COLOR_CYAN, ''),
42 42 'white': (False, curses.COLOR_WHITE, ''),
43 43 }
44 44 except ImportError:
45 45 curses = None
46 46 _baseterminfoparams = {}
47 47
48 48 # start and stop parameters for effects
49 49 _effects = {
50 50 'none': 0,
51 51 'black': 30,
52 52 'red': 31,
53 53 'green': 32,
54 54 'yellow': 33,
55 55 'blue': 34,
56 56 'magenta': 35,
57 57 'cyan': 36,
58 58 'white': 37,
59 59 'bold': 1,
60 60 'italic': 3,
61 61 'underline': 4,
62 62 'inverse': 7,
63 63 'dim': 2,
64 64 'black_background': 40,
65 65 'red_background': 41,
66 66 'green_background': 42,
67 67 'yellow_background': 43,
68 68 'blue_background': 44,
69 69 'purple_background': 45,
70 70 'cyan_background': 46,
71 71 'white_background': 47,
72 72 }
73 73
74 74 _defaultstyles = {
75 75 'grep.match': 'red bold',
76 76 'grep.linenumber': 'green',
77 77 'grep.rev': 'green',
78 78 'grep.change': 'green',
79 79 'grep.sep': 'cyan',
80 80 'grep.filename': 'magenta',
81 81 'grep.user': 'magenta',
82 82 'grep.date': 'magenta',
83 83 'bookmarks.active': 'green',
84 84 'branches.active': 'none',
85 85 'branches.closed': 'black bold',
86 86 'branches.current': 'green',
87 87 'branches.inactive': 'none',
88 88 'diff.changed': 'white',
89 89 'diff.deleted': 'red',
90 90 'diff.diffline': 'bold',
91 91 'diff.extended': 'cyan bold',
92 92 'diff.file_a': 'red bold',
93 93 'diff.file_b': 'green bold',
94 94 'diff.hunk': 'magenta',
95 95 'diff.inserted': 'green',
96 96 'diff.tab': '',
97 97 'diff.trailingwhitespace': 'bold red_background',
98 98 'changeset.public': '',
99 99 'changeset.draft': '',
100 100 'changeset.secret': '',
101 101 'diffstat.deleted': 'red',
102 102 'diffstat.inserted': 'green',
103 103 'histedit.remaining': 'red bold',
104 104 'ui.prompt': 'yellow',
105 105 'log.changeset': 'yellow',
106 106 'patchbomb.finalsummary': '',
107 107 'patchbomb.from': 'magenta',
108 108 'patchbomb.to': 'cyan',
109 109 'patchbomb.subject': 'green',
110 110 'patchbomb.diffstats': '',
111 111 'rebase.rebased': 'blue',
112 112 'rebase.remaining': 'red bold',
113 113 'resolve.resolved': 'green bold',
114 114 'resolve.unresolved': 'red bold',
115 115 'shelve.age': 'cyan',
116 116 'shelve.newest': 'green bold',
117 117 'shelve.name': 'blue bold',
118 118 'status.added': 'green bold',
119 119 'status.clean': 'none',
120 120 'status.copied': 'none',
121 121 'status.deleted': 'cyan bold underline',
122 122 'status.ignored': 'black bold',
123 123 'status.modified': 'blue bold',
124 124 'status.removed': 'red bold',
125 125 'status.unknown': 'magenta bold underline',
126 126 'tags.normal': 'green',
127 127 'tags.local': 'black bold',
128 128 }
129 129
130 130 def loadcolortable(ui, extname, colortable):
131 131 _defaultstyles.update(colortable)
132 132
133 133 def _terminfosetup(ui, mode, formatted):
134 134 '''Initialize terminfo data and the terminal if we're in terminfo mode.'''
135 135
136 136 # If we failed to load curses, we go ahead and return.
137 137 if curses is None:
138 138 return
139 139 # Otherwise, see what the config file says.
140 140 if mode not in ('auto', 'terminfo'):
141 141 return
142 142 ui._terminfoparams.update(_baseterminfoparams)
143 143
144 144 for key, val in ui.configitems('color'):
145 145 if key.startswith('color.'):
146 146 newval = (False, int(val), '')
147 147 ui._terminfoparams[key[6:]] = newval
148 148 elif key.startswith('terminfo.'):
149 149 newval = (True, '', val.replace('\\E', '\x1b'))
150 150 ui._terminfoparams[key[9:]] = newval
151 151 try:
152 152 curses.setupterm()
153 153 except curses.error as e:
154 154 ui._terminfoparams.clear()
155 155 return
156 156
157 157 for key, (b, e, c) in ui._terminfoparams.items():
158 158 if not b:
159 159 continue
160 160 if not c and not curses.tigetstr(e):
161 161 # Most terminals don't support dim, invis, etc, so don't be
162 162 # noisy and use ui.debug().
163 163 ui.debug("no terminfo entry for %s\n" % e)
164 164 del ui._terminfoparams[key]
165 165 if not curses.tigetstr('setaf') or not curses.tigetstr('setab'):
166 166 # Only warn about missing terminfo entries if we explicitly asked for
167 167 # terminfo mode and we're in a formatted terminal.
168 168 if mode == "terminfo" and formatted:
169 169 ui.warn(_("no terminfo entry for setab/setaf: reverting to "
170 170 "ECMA-48 color\n"))
171 171 ui._terminfoparams.clear()
172 172
173 173 def setup(ui):
174 174 """configure color on a ui
175 175
176 176 That function both set the colormode for the ui object and read
177 177 the configuration looking for custom colors and effect definitions."""
178 178 mode = _modesetup(ui)
179 179 ui._colormode = mode
180 180 if mode and mode != 'debug':
181 181 configstyles(ui)
182 182
183 183 def _modesetup(ui):
184 if ui.plain():
184 if ui.plain('color'):
185 185 return None
186 186 config = ui.config('ui', 'color')
187 187 if config == 'debug':
188 188 return 'debug'
189 189
190 190 auto = (config == 'auto')
191 191 always = False
192 192 if not auto and util.parsebool(config):
193 193 # We want the config to behave like a boolean, "on" is actually auto,
194 194 # but "always" value is treated as a special case to reduce confusion.
195 195 if ui.configsource('ui', 'color') == '--color' or config == 'always':
196 196 always = True
197 197 else:
198 198 auto = True
199 199
200 200 if not always and not auto:
201 201 return None
202 202
203 203 formatted = (always or (encoding.environ.get('TERM') != 'dumb'
204 204 and ui.formatted()))
205 205
206 206 mode = ui.config('color', 'mode')
207 207
208 208 # If pager is active, color.pagermode overrides color.mode.
209 209 if getattr(ui, 'pageractive', False):
210 210 mode = ui.config('color', 'pagermode', mode)
211 211
212 212 realmode = mode
213 213 if pycompat.iswindows:
214 214 from . import win32
215 215
216 216 term = encoding.environ.get('TERM')
217 217 # TERM won't be defined in a vanilla cmd.exe environment.
218 218
219 219 # UNIX-like environments on Windows such as Cygwin and MSYS will
220 220 # set TERM. They appear to make a best effort attempt at setting it
221 221 # to something appropriate. However, not all environments with TERM
222 222 # defined support ANSI.
223 223 ansienviron = term and 'xterm' in term
224 224
225 225 if mode == 'auto':
226 226 # Since "ansi" could result in terminal gibberish, we error on the
227 227 # side of selecting "win32". However, if w32effects is not defined,
228 228 # we almost certainly don't support "win32", so don't even try.
229 229 # w32ffects is not populated when stdout is redirected, so checking
230 230 # it first avoids win32 calls in a state known to error out.
231 231 if ansienviron or not w32effects or win32.enablevtmode():
232 232 realmode = 'ansi'
233 233 else:
234 234 realmode = 'win32'
235 235 # An empty w32effects is a clue that stdout is redirected, and thus
236 236 # cannot enable VT mode.
237 237 elif mode == 'ansi' and w32effects and not ansienviron:
238 238 win32.enablevtmode()
239 239 elif mode == 'auto':
240 240 realmode = 'ansi'
241 241
242 242 def modewarn():
243 243 # only warn if color.mode was explicitly set and we're in
244 244 # a formatted terminal
245 245 if mode == realmode and formatted:
246 246 ui.warn(_('warning: failed to set color mode to %s\n') % mode)
247 247
248 248 if realmode == 'win32':
249 249 ui._terminfoparams.clear()
250 250 if not w32effects:
251 251 modewarn()
252 252 return None
253 253 elif realmode == 'ansi':
254 254 ui._terminfoparams.clear()
255 255 elif realmode == 'terminfo':
256 256 _terminfosetup(ui, mode, formatted)
257 257 if not ui._terminfoparams:
258 258 ## FIXME Shouldn't we return None in this case too?
259 259 modewarn()
260 260 realmode = 'ansi'
261 261 else:
262 262 return None
263 263
264 264 if always or (auto and formatted):
265 265 return realmode
266 266 return None
267 267
268 268 def configstyles(ui):
269 269 ui._styles.update(_defaultstyles)
270 270 for status, cfgeffects in ui.configitems('color'):
271 271 if '.' not in status or status.startswith(('color.', 'terminfo.')):
272 272 continue
273 273 cfgeffects = ui.configlist('color', status)
274 274 if cfgeffects:
275 275 good = []
276 276 for e in cfgeffects:
277 277 if valideffect(ui, e):
278 278 good.append(e)
279 279 else:
280 280 ui.warn(_("ignoring unknown color/effect %r "
281 281 "(configured in color.%s)\n")
282 282 % (e, status))
283 283 ui._styles[status] = ' '.join(good)
284 284
285 285 def _activeeffects(ui):
286 286 '''Return the effects map for the color mode set on the ui.'''
287 287 if ui._colormode == 'win32':
288 288 return w32effects
289 289 elif ui._colormode is not None:
290 290 return _effects
291 291 return {}
292 292
293 293 def valideffect(ui, effect):
294 294 'Determine if the effect is valid or not.'
295 295 return ((not ui._terminfoparams and effect in _activeeffects(ui))
296 296 or (effect in ui._terminfoparams
297 297 or effect[:-11] in ui._terminfoparams))
298 298
299 299 def _effect_str(ui, effect):
300 300 '''Helper function for render_effects().'''
301 301
302 302 bg = False
303 303 if effect.endswith('_background'):
304 304 bg = True
305 305 effect = effect[:-11]
306 306 try:
307 307 attr, val, termcode = ui._terminfoparams[effect]
308 308 except KeyError:
309 309 return ''
310 310 if attr:
311 311 if termcode:
312 312 return termcode
313 313 else:
314 314 return curses.tigetstr(val)
315 315 elif bg:
316 316 return curses.tparm(curses.tigetstr('setab'), val)
317 317 else:
318 318 return curses.tparm(curses.tigetstr('setaf'), val)
319 319
320 320 def _mergeeffects(text, start, stop):
321 321 """Insert start sequence at every occurrence of stop sequence
322 322
323 323 >>> s = _mergeeffects(b'cyan', b'[C]', b'|')
324 324 >>> s = _mergeeffects(s + b'yellow', b'[Y]', b'|')
325 325 >>> s = _mergeeffects(b'ma' + s + b'genta', b'[M]', b'|')
326 326 >>> s = _mergeeffects(b'red' + s, b'[R]', b'|')
327 327 >>> s
328 328 '[R]red[M]ma[Y][C]cyan|[R][M][Y]yellow|[R][M]genta|'
329 329 """
330 330 parts = []
331 331 for t in text.split(stop):
332 332 if not t:
333 333 continue
334 334 parts.extend([start, t, stop])
335 335 return ''.join(parts)
336 336
337 337 def _render_effects(ui, text, effects):
338 338 'Wrap text in commands to turn on each effect.'
339 339 if not text:
340 340 return text
341 341 if ui._terminfoparams:
342 342 start = ''.join(_effect_str(ui, effect)
343 343 for effect in ['none'] + effects.split())
344 344 stop = _effect_str(ui, 'none')
345 345 else:
346 346 activeeffects = _activeeffects(ui)
347 347 start = [pycompat.bytestr(activeeffects[e])
348 348 for e in ['none'] + effects.split()]
349 349 start = '\033[' + ';'.join(start) + 'm'
350 350 stop = '\033[' + pycompat.bytestr(activeeffects['none']) + 'm'
351 351 return _mergeeffects(text, start, stop)
352 352
353 353 _ansieffectre = re.compile(br'\x1b\[[0-9;]*m')
354 354
355 355 def stripeffects(text):
356 356 """Strip ANSI control codes which could be inserted by colorlabel()"""
357 357 return _ansieffectre.sub('', text)
358 358
359 359 def colorlabel(ui, msg, label):
360 360 """add color control code according to the mode"""
361 361 if ui._colormode == 'debug':
362 362 if label and msg:
363 363 if msg[-1] == '\n':
364 364 msg = "[%s|%s]\n" % (label, msg[:-1])
365 365 else:
366 366 msg = "[%s|%s]" % (label, msg)
367 367 elif ui._colormode is not None:
368 368 effects = []
369 369 for l in label.split():
370 370 s = ui._styles.get(l, '')
371 371 if s:
372 372 effects.append(s)
373 373 elif valideffect(ui, l):
374 374 effects.append(l)
375 375 effects = ' '.join(effects)
376 376 if effects:
377 377 msg = '\n'.join([_render_effects(ui, line, effects)
378 378 for line in msg.split('\n')])
379 379 return msg
380 380
381 381 w32effects = None
382 382 if pycompat.iswindows:
383 383 import ctypes
384 384
385 385 _kernel32 = ctypes.windll.kernel32
386 386
387 387 _WORD = ctypes.c_ushort
388 388
389 389 _INVALID_HANDLE_VALUE = -1
390 390
391 391 class _COORD(ctypes.Structure):
392 392 _fields_ = [('X', ctypes.c_short),
393 393 ('Y', ctypes.c_short)]
394 394
395 395 class _SMALL_RECT(ctypes.Structure):
396 396 _fields_ = [('Left', ctypes.c_short),
397 397 ('Top', ctypes.c_short),
398 398 ('Right', ctypes.c_short),
399 399 ('Bottom', ctypes.c_short)]
400 400
401 401 class _CONSOLE_SCREEN_BUFFER_INFO(ctypes.Structure):
402 402 _fields_ = [('dwSize', _COORD),
403 403 ('dwCursorPosition', _COORD),
404 404 ('wAttributes', _WORD),
405 405 ('srWindow', _SMALL_RECT),
406 406 ('dwMaximumWindowSize', _COORD)]
407 407
408 408 _STD_OUTPUT_HANDLE = 0xfffffff5 # (DWORD)-11
409 409 _STD_ERROR_HANDLE = 0xfffffff4 # (DWORD)-12
410 410
411 411 _FOREGROUND_BLUE = 0x0001
412 412 _FOREGROUND_GREEN = 0x0002
413 413 _FOREGROUND_RED = 0x0004
414 414 _FOREGROUND_INTENSITY = 0x0008
415 415
416 416 _BACKGROUND_BLUE = 0x0010
417 417 _BACKGROUND_GREEN = 0x0020
418 418 _BACKGROUND_RED = 0x0040
419 419 _BACKGROUND_INTENSITY = 0x0080
420 420
421 421 _COMMON_LVB_REVERSE_VIDEO = 0x4000
422 422 _COMMON_LVB_UNDERSCORE = 0x8000
423 423
424 424 # http://msdn.microsoft.com/en-us/library/ms682088%28VS.85%29.aspx
425 425 w32effects = {
426 426 'none': -1,
427 427 'black': 0,
428 428 'red': _FOREGROUND_RED,
429 429 'green': _FOREGROUND_GREEN,
430 430 'yellow': _FOREGROUND_RED | _FOREGROUND_GREEN,
431 431 'blue': _FOREGROUND_BLUE,
432 432 'magenta': _FOREGROUND_BLUE | _FOREGROUND_RED,
433 433 'cyan': _FOREGROUND_BLUE | _FOREGROUND_GREEN,
434 434 'white': _FOREGROUND_RED | _FOREGROUND_GREEN | _FOREGROUND_BLUE,
435 435 'bold': _FOREGROUND_INTENSITY,
436 436 'black_background': 0x100, # unused value > 0x0f
437 437 'red_background': _BACKGROUND_RED,
438 438 'green_background': _BACKGROUND_GREEN,
439 439 'yellow_background': _BACKGROUND_RED | _BACKGROUND_GREEN,
440 440 'blue_background': _BACKGROUND_BLUE,
441 441 'purple_background': _BACKGROUND_BLUE | _BACKGROUND_RED,
442 442 'cyan_background': _BACKGROUND_BLUE | _BACKGROUND_GREEN,
443 443 'white_background': (_BACKGROUND_RED | _BACKGROUND_GREEN |
444 444 _BACKGROUND_BLUE),
445 445 'bold_background': _BACKGROUND_INTENSITY,
446 446 'underline': _COMMON_LVB_UNDERSCORE, # double-byte charsets only
447 447 'inverse': _COMMON_LVB_REVERSE_VIDEO, # double-byte charsets only
448 448 }
449 449
450 450 passthrough = {_FOREGROUND_INTENSITY,
451 451 _BACKGROUND_INTENSITY,
452 452 _COMMON_LVB_UNDERSCORE,
453 453 _COMMON_LVB_REVERSE_VIDEO}
454 454
455 455 stdout = _kernel32.GetStdHandle(
456 456 _STD_OUTPUT_HANDLE) # don't close the handle returned
457 457 if stdout is None or stdout == _INVALID_HANDLE_VALUE:
458 458 w32effects = None
459 459 else:
460 460 csbi = _CONSOLE_SCREEN_BUFFER_INFO()
461 461 if not _kernel32.GetConsoleScreenBufferInfo(
462 462 stdout, ctypes.byref(csbi)):
463 463 # stdout may not support GetConsoleScreenBufferInfo()
464 464 # when called from subprocess or redirected
465 465 w32effects = None
466 466 else:
467 467 origattr = csbi.wAttributes
468 468 ansire = re.compile('\033\[([^m]*)m([^\033]*)(.*)',
469 469 re.MULTILINE | re.DOTALL)
470 470
471 471 def win32print(ui, writefunc, *msgs, **opts):
472 472 for text in msgs:
473 473 _win32print(ui, text, writefunc, **opts)
474 474
475 475 def _win32print(ui, text, writefunc, **opts):
476 476 label = opts.get('label', '')
477 477 attr = origattr
478 478
479 479 def mapcolor(val, attr):
480 480 if val == -1:
481 481 return origattr
482 482 elif val in passthrough:
483 483 return attr | val
484 484 elif val > 0x0f:
485 485 return (val & 0x70) | (attr & 0x8f)
486 486 else:
487 487 return (val & 0x07) | (attr & 0xf8)
488 488
489 489 # determine console attributes based on labels
490 490 for l in label.split():
491 491 style = ui._styles.get(l, '')
492 492 for effect in style.split():
493 493 try:
494 494 attr = mapcolor(w32effects[effect], attr)
495 495 except KeyError:
496 496 # w32effects could not have certain attributes so we skip
497 497 # them if not found
498 498 pass
499 499 # hack to ensure regexp finds data
500 500 if not text.startswith('\033['):
501 501 text = '\033[m' + text
502 502
503 503 # Look for ANSI-like codes embedded in text
504 504 m = re.match(ansire, text)
505 505
506 506 try:
507 507 while m:
508 508 for sattr in m.group(1).split(';'):
509 509 if sattr:
510 510 attr = mapcolor(int(sattr), attr)
511 511 ui.flush()
512 512 _kernel32.SetConsoleTextAttribute(stdout, attr)
513 513 writefunc(m.group(2), **opts)
514 514 m = re.match(ansire, m.group(3))
515 515 finally:
516 516 # Explicitly reset original attributes
517 517 ui.flush()
518 518 _kernel32.SetConsoleTextAttribute(stdout, origattr)
@@ -1,111 +1,113
1 1 HG
2 2 Path to the 'hg' executable, automatically passed when running
3 3 hooks, extensions or external tools. If unset or empty, this is
4 4 the hg executable's name if it's frozen, or an executable named
5 5 'hg' (with %PATHEXT% [defaulting to COM/EXE/BAT/CMD] extensions on
6 6 Windows) is searched.
7 7
8 8 HGEDITOR
9 9 This is the name of the editor to run when committing. See EDITOR.
10 10
11 11 (deprecated, see :hg:`help config.ui.editor`)
12 12
13 13 HGENCODING
14 14 This overrides the default locale setting detected by Mercurial.
15 15 This setting is used to convert data including usernames,
16 16 changeset descriptions, tag names, and branches. This setting can
17 17 be overridden with the --encoding command-line option.
18 18
19 19 HGENCODINGMODE
20 20 This sets Mercurial's behavior for handling unknown characters
21 21 while transcoding user input. The default is "strict", which
22 22 causes Mercurial to abort if it can't map a character. Other
23 23 settings include "replace", which replaces unknown characters, and
24 24 "ignore", which drops them. This setting can be overridden with
25 25 the --encodingmode command-line option.
26 26
27 27 HGENCODINGAMBIGUOUS
28 28 This sets Mercurial's behavior for handling characters with
29 29 "ambiguous" widths like accented Latin characters with East Asian
30 30 fonts. By default, Mercurial assumes ambiguous characters are
31 31 narrow, set this variable to "wide" if such characters cause
32 32 formatting problems.
33 33
34 34 HGMERGE
35 35 An executable to use for resolving merge conflicts. The program
36 36 will be executed with three arguments: local file, remote file,
37 37 ancestor file.
38 38
39 39 (deprecated, see :hg:`help config.ui.merge`)
40 40
41 41 HGRCPATH
42 42 A list of files or directories to search for configuration
43 43 files. Item separator is ":" on Unix, ";" on Windows. If HGRCPATH
44 44 is not set, platform default search path is used. If empty, only
45 45 the .hg/hgrc from the current repository is read.
46 46
47 47 For each element in HGRCPATH:
48 48
49 49 - if it's a directory, all files ending with .rc are added
50 50 - otherwise, the file itself will be added
51 51
52 52 HGPLAIN
53 53 When set, this disables any configuration settings that might
54 54 change Mercurial's default output. This includes encoding,
55 55 defaults, verbose mode, debug mode, quiet mode, tracebacks, and
56 56 localization. This can be useful when scripting against Mercurial
57 57 in the face of existing user configuration.
58 58
59 59 Equivalent options set via command line flags or environment
60 60 variables are not overridden.
61 61
62 62 HGPLAINEXCEPT
63 63 This is a comma-separated list of features to preserve when
64 64 HGPLAIN is enabled. Currently the following values are supported:
65 65
66 66 ``alias``
67 67 Don't remove aliases.
68 ``color``
69 Don't disable colored output.
68 70 ``i18n``
69 71 Preserve internationalization.
70 72 ``revsetalias``
71 73 Don't remove revset aliases.
72 74 ``templatealias``
73 75 Don't remove template aliases.
74 76 ``progress``
75 77 Don't hide progress output.
76 78
77 79 Setting HGPLAINEXCEPT to anything (even an empty string) will
78 80 enable plain mode.
79 81
80 82 HGUSER
81 83 This is the string used as the author of a commit. If not set,
82 84 available values will be considered in this order:
83 85
84 86 - HGUSER (deprecated)
85 87 - configuration files from the HGRCPATH
86 88 - EMAIL
87 89 - interactive prompt
88 90 - LOGNAME (with ``@hostname`` appended)
89 91
90 92 (deprecated, see :hg:`help config.ui.username`)
91 93
92 94 EMAIL
93 95 May be used as the author of a commit; see HGUSER.
94 96
95 97 LOGNAME
96 98 May be used as the author of a commit; see HGUSER.
97 99
98 100 VISUAL
99 101 This is the name of the editor to use when committing. See EDITOR.
100 102
101 103 EDITOR
102 104 Sometimes Mercurial needs to open a text file in an editor for a
103 105 user to modify, for example when writing commit messages. The
104 106 editor it uses is determined by looking at the environment
105 107 variables HGEDITOR, VISUAL and EDITOR, in that order. The first
106 108 non-empty one is chosen. If all of them are empty, the editor
107 109 defaults to 'vi'.
108 110
109 111 PYTHONPATH
110 112 This is used by Python to find imported modules and may need to be
111 113 set appropriately if this Mercurial is not installed system-wide.
@@ -1,389 +1,405
1 1 $ cat <<EOF >> $HGRCPATH
2 2 > [ui]
3 3 > color = always
4 4 > [color]
5 5 > mode = ansi
6 6 > EOF
7 7 Terminfo codes compatibility fix
8 8 $ echo "color.none=0" >> $HGRCPATH
9 9
10 10 $ hg init repo1
11 11 $ cd repo1
12 12 $ mkdir a b a/1 b/1 b/2
13 13 $ touch in_root a/in_a b/in_b a/1/in_a_1 b/1/in_b_1 b/2/in_b_2
14 14
15 15 hg status in repo root:
16 16
17 17 $ hg status
18 18 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4ma/1/in_a_1\x1b[0m (esc)
19 19 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4ma/in_a\x1b[0m (esc)
20 20 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4mb/1/in_b_1\x1b[0m (esc)
21 21 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4mb/2/in_b_2\x1b[0m (esc)
22 22 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4mb/in_b\x1b[0m (esc)
23 23 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4min_root\x1b[0m (esc)
24 24
25 25 $ hg status --color=debug
26 26 [status.unknown|? ][status.unknown|a/1/in_a_1]
27 27 [status.unknown|? ][status.unknown|a/in_a]
28 28 [status.unknown|? ][status.unknown|b/1/in_b_1]
29 29 [status.unknown|? ][status.unknown|b/2/in_b_2]
30 30 [status.unknown|? ][status.unknown|b/in_b]
31 31 [status.unknown|? ][status.unknown|in_root]
32 HGPLAIN disables color
33 $ HGPLAIN=1 hg status --color=debug
34 ? a/1/in_a_1
35 ? a/in_a
36 ? b/1/in_b_1
37 ? b/2/in_b_2
38 ? b/in_b
39 ? in_root
40 HGPLAINEXCEPT=color does not disable color
41 $ HGPLAINEXCEPT=color hg status --color=debug
42 [status.unknown|? ][status.unknown|a/1/in_a_1]
43 [status.unknown|? ][status.unknown|a/in_a]
44 [status.unknown|? ][status.unknown|b/1/in_b_1]
45 [status.unknown|? ][status.unknown|b/2/in_b_2]
46 [status.unknown|? ][status.unknown|b/in_b]
47 [status.unknown|? ][status.unknown|in_root]
32 48
33 49 hg status with template
34 50 $ hg status -T "{label('red', path)}\n" --color=debug
35 51 [red|a/1/in_a_1]
36 52 [red|a/in_a]
37 53 [red|b/1/in_b_1]
38 54 [red|b/2/in_b_2]
39 55 [red|b/in_b]
40 56 [red|in_root]
41 57
42 58 hg status . in repo root:
43 59
44 60 $ hg status .
45 61 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4ma/1/in_a_1\x1b[0m (esc)
46 62 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4ma/in_a\x1b[0m (esc)
47 63 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4mb/1/in_b_1\x1b[0m (esc)
48 64 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4mb/2/in_b_2\x1b[0m (esc)
49 65 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4mb/in_b\x1b[0m (esc)
50 66 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4min_root\x1b[0m (esc)
51 67
52 68 $ hg status --cwd a
53 69 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4ma/1/in_a_1\x1b[0m (esc)
54 70 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4ma/in_a\x1b[0m (esc)
55 71 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4mb/1/in_b_1\x1b[0m (esc)
56 72 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4mb/2/in_b_2\x1b[0m (esc)
57 73 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4mb/in_b\x1b[0m (esc)
58 74 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4min_root\x1b[0m (esc)
59 75 $ hg status --cwd a .
60 76 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4m1/in_a_1\x1b[0m (esc)
61 77 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4min_a\x1b[0m (esc)
62 78 $ hg status --cwd a ..
63 79 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4m1/in_a_1\x1b[0m (esc)
64 80 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4min_a\x1b[0m (esc)
65 81 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4m../b/1/in_b_1\x1b[0m (esc)
66 82 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4m../b/2/in_b_2\x1b[0m (esc)
67 83 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4m../b/in_b\x1b[0m (esc)
68 84 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4m../in_root\x1b[0m (esc)
69 85
70 86 $ hg status --cwd b
71 87 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4ma/1/in_a_1\x1b[0m (esc)
72 88 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4ma/in_a\x1b[0m (esc)
73 89 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4mb/1/in_b_1\x1b[0m (esc)
74 90 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4mb/2/in_b_2\x1b[0m (esc)
75 91 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4mb/in_b\x1b[0m (esc)
76 92 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4min_root\x1b[0m (esc)
77 93 $ hg status --cwd b .
78 94 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4m1/in_b_1\x1b[0m (esc)
79 95 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4m2/in_b_2\x1b[0m (esc)
80 96 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4min_b\x1b[0m (esc)
81 97 $ hg status --cwd b ..
82 98 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4m../a/1/in_a_1\x1b[0m (esc)
83 99 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4m../a/in_a\x1b[0m (esc)
84 100 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4m1/in_b_1\x1b[0m (esc)
85 101 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4m2/in_b_2\x1b[0m (esc)
86 102 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4min_b\x1b[0m (esc)
87 103 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4m../in_root\x1b[0m (esc)
88 104
89 105 $ hg status --cwd a/1
90 106 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4ma/1/in_a_1\x1b[0m (esc)
91 107 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4ma/in_a\x1b[0m (esc)
92 108 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4mb/1/in_b_1\x1b[0m (esc)
93 109 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4mb/2/in_b_2\x1b[0m (esc)
94 110 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4mb/in_b\x1b[0m (esc)
95 111 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4min_root\x1b[0m (esc)
96 112 $ hg status --cwd a/1 .
97 113 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4min_a_1\x1b[0m (esc)
98 114 $ hg status --cwd a/1 ..
99 115 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4min_a_1\x1b[0m (esc)
100 116 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4m../in_a\x1b[0m (esc)
101 117
102 118 $ hg status --cwd b/1
103 119 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4ma/1/in_a_1\x1b[0m (esc)
104 120 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4ma/in_a\x1b[0m (esc)
105 121 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4mb/1/in_b_1\x1b[0m (esc)
106 122 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4mb/2/in_b_2\x1b[0m (esc)
107 123 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4mb/in_b\x1b[0m (esc)
108 124 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4min_root\x1b[0m (esc)
109 125 $ hg status --cwd b/1 .
110 126 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4min_b_1\x1b[0m (esc)
111 127 $ hg status --cwd b/1 ..
112 128 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4min_b_1\x1b[0m (esc)
113 129 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4m../2/in_b_2\x1b[0m (esc)
114 130 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4m../in_b\x1b[0m (esc)
115 131
116 132 $ hg status --cwd b/2
117 133 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4ma/1/in_a_1\x1b[0m (esc)
118 134 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4ma/in_a\x1b[0m (esc)
119 135 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4mb/1/in_b_1\x1b[0m (esc)
120 136 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4mb/2/in_b_2\x1b[0m (esc)
121 137 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4mb/in_b\x1b[0m (esc)
122 138 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4min_root\x1b[0m (esc)
123 139 $ hg status --cwd b/2 .
124 140 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4min_b_2\x1b[0m (esc)
125 141 $ hg status --cwd b/2 ..
126 142 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4m../1/in_b_1\x1b[0m (esc)
127 143 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4min_b_2\x1b[0m (esc)
128 144 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4m../in_b\x1b[0m (esc)
129 145
130 146 Make sure --color=never works
131 147 $ hg status --color=never
132 148 ? a/1/in_a_1
133 149 ? a/in_a
134 150 ? b/1/in_b_1
135 151 ? b/2/in_b_2
136 152 ? b/in_b
137 153 ? in_root
138 154
139 155 Make sure ui.formatted=False works
140 156 $ hg status --color=auto --config ui.formatted=False
141 157 ? a/1/in_a_1
142 158 ? a/in_a
143 159 ? b/1/in_b_1
144 160 ? b/2/in_b_2
145 161 ? b/in_b
146 162 ? in_root
147 163
148 164 $ cd ..
149 165
150 166 $ hg init repo2
151 167 $ cd repo2
152 168 $ touch modified removed deleted ignored
153 169 $ echo "^ignored$" > .hgignore
154 170 $ hg ci -A -m 'initial checkin'
155 171 adding .hgignore
156 172 adding deleted
157 173 adding modified
158 174 adding removed
159 175 $ hg log --color=debug
160 176 [log.changeset changeset.draft|changeset: 0:389aef86a55e]
161 177 [log.tag|tag: tip]
162 178 [log.user|user: test]
163 179 [log.date|date: Thu Jan 01 00:00:00 1970 +0000]
164 180 [log.summary|summary: initial checkin]
165 181
166 182 $ hg log -Tcompact --color=debug
167 183 [log.changeset changeset.draft|0][tip] [log.node|389aef86a55e] [log.date|1970-01-01 00:00 +0000] [log.user|test]
168 184 [ui.note log.description|initial checkin]
169 185
170 186 Labels on empty strings should not be displayed, labels on custom
171 187 templates should be.
172 188
173 189 $ hg log --color=debug -T '{label("my.label",author)}\n{label("skipped.label","")}'
174 190 [my.label|test]
175 191 $ touch modified added unknown ignored
176 192 $ hg add added
177 193 $ hg remove removed
178 194 $ rm deleted
179 195
180 196 hg status:
181 197
182 198 $ hg status
183 199 \x1b[0;32;1mA \x1b[0m\x1b[0;32;1madded\x1b[0m (esc)
184 200 \x1b[0;31;1mR \x1b[0m\x1b[0;31;1mremoved\x1b[0m (esc)
185 201 \x1b[0;36;1;4m! \x1b[0m\x1b[0;36;1;4mdeleted\x1b[0m (esc)
186 202 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4munknown\x1b[0m (esc)
187 203
188 204 hg status modified added removed deleted unknown never-existed ignored:
189 205
190 206 $ hg status modified added removed deleted unknown never-existed ignored
191 207 never-existed: * (glob)
192 208 \x1b[0;32;1mA \x1b[0m\x1b[0;32;1madded\x1b[0m (esc)
193 209 \x1b[0;31;1mR \x1b[0m\x1b[0;31;1mremoved\x1b[0m (esc)
194 210 \x1b[0;36;1;4m! \x1b[0m\x1b[0;36;1;4mdeleted\x1b[0m (esc)
195 211 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4munknown\x1b[0m (esc)
196 212
197 213 $ hg copy modified copied
198 214
199 215 hg status -C:
200 216
201 217 $ hg status -C
202 218 \x1b[0;32;1mA \x1b[0m\x1b[0;32;1madded\x1b[0m (esc)
203 219 \x1b[0;32;1mA \x1b[0m\x1b[0;32;1mcopied\x1b[0m (esc)
204 220 \x1b[0;0m modified\x1b[0m (esc)
205 221 \x1b[0;31;1mR \x1b[0m\x1b[0;31;1mremoved\x1b[0m (esc)
206 222 \x1b[0;36;1;4m! \x1b[0m\x1b[0;36;1;4mdeleted\x1b[0m (esc)
207 223 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4munknown\x1b[0m (esc)
208 224
209 225 hg status -A:
210 226
211 227 $ hg status -A
212 228 \x1b[0;32;1mA \x1b[0m\x1b[0;32;1madded\x1b[0m (esc)
213 229 \x1b[0;32;1mA \x1b[0m\x1b[0;32;1mcopied\x1b[0m (esc)
214 230 \x1b[0;0m modified\x1b[0m (esc)
215 231 \x1b[0;31;1mR \x1b[0m\x1b[0;31;1mremoved\x1b[0m (esc)
216 232 \x1b[0;36;1;4m! \x1b[0m\x1b[0;36;1;4mdeleted\x1b[0m (esc)
217 233 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4munknown\x1b[0m (esc)
218 234 \x1b[0;30;1mI \x1b[0m\x1b[0;30;1mignored\x1b[0m (esc)
219 235 \x1b[0;0mC \x1b[0m\x1b[0;0m.hgignore\x1b[0m (esc)
220 236 \x1b[0;0mC \x1b[0m\x1b[0;0mmodified\x1b[0m (esc)
221 237
222 238
223 239 hg status -A (with terminfo color):
224 240
225 241 #if tic
226 242
227 243 $ mkdir "$TESTTMP/terminfo"
228 244 $ TERMINFO="$TESTTMP/terminfo" tic "$TESTDIR/hgterm.ti"
229 245 $ TERM=hgterm TERMINFO="$TESTTMP/terminfo" hg status --config color.mode=terminfo -A
230 246 \x1b[30m\x1b[32m\x1b[1mA \x1b[30m\x1b[30m\x1b[32m\x1b[1madded\x1b[30m (esc)
231 247 \x1b[30m\x1b[32m\x1b[1mA \x1b[30m\x1b[30m\x1b[32m\x1b[1mcopied\x1b[30m (esc)
232 248 \x1b[30m\x1b[30m modified\x1b[30m (esc)
233 249 \x1b[30m\x1b[31m\x1b[1mR \x1b[30m\x1b[30m\x1b[31m\x1b[1mremoved\x1b[30m (esc)
234 250 \x1b[30m\x1b[36m\x1b[1m\x1b[4m! \x1b[30m\x1b[30m\x1b[36m\x1b[1m\x1b[4mdeleted\x1b[30m (esc)
235 251 \x1b[30m\x1b[35m\x1b[1m\x1b[4m? \x1b[30m\x1b[30m\x1b[35m\x1b[1m\x1b[4munknown\x1b[30m (esc)
236 252 \x1b[30m\x1b[30m\x1b[1mI \x1b[30m\x1b[30m\x1b[30m\x1b[1mignored\x1b[30m (esc)
237 253 \x1b[30m\x1b[30mC \x1b[30m\x1b[30m\x1b[30m.hgignore\x1b[30m (esc)
238 254 \x1b[30m\x1b[30mC \x1b[30m\x1b[30m\x1b[30mmodified\x1b[30m (esc)
239 255
240 256 The user can define effects with raw terminfo codes:
241 257
242 258 $ cat <<EOF >> $HGRCPATH
243 259 > # Completely bogus code for dim
244 260 > terminfo.dim = \E[88m
245 261 > # We can override what's in the terminfo database, too
246 262 > terminfo.bold = \E[2m
247 263 > EOF
248 264 $ TERM=hgterm TERMINFO="$TESTTMP/terminfo" hg status --config color.mode=terminfo --config color.status.clean=dim -A
249 265 \x1b[30m\x1b[32m\x1b[2mA \x1b[30m\x1b[30m\x1b[32m\x1b[2madded\x1b[30m (esc)
250 266 \x1b[30m\x1b[32m\x1b[2mA \x1b[30m\x1b[30m\x1b[32m\x1b[2mcopied\x1b[30m (esc)
251 267 \x1b[30m\x1b[30m modified\x1b[30m (esc)
252 268 \x1b[30m\x1b[31m\x1b[2mR \x1b[30m\x1b[30m\x1b[31m\x1b[2mremoved\x1b[30m (esc)
253 269 \x1b[30m\x1b[36m\x1b[2m\x1b[4m! \x1b[30m\x1b[30m\x1b[36m\x1b[2m\x1b[4mdeleted\x1b[30m (esc)
254 270 \x1b[30m\x1b[35m\x1b[2m\x1b[4m? \x1b[30m\x1b[30m\x1b[35m\x1b[2m\x1b[4munknown\x1b[30m (esc)
255 271 \x1b[30m\x1b[30m\x1b[2mI \x1b[30m\x1b[30m\x1b[30m\x1b[2mignored\x1b[30m (esc)
256 272 \x1b[30m\x1b[88mC \x1b[30m\x1b[30m\x1b[88m.hgignore\x1b[30m (esc)
257 273 \x1b[30m\x1b[88mC \x1b[30m\x1b[30m\x1b[88mmodified\x1b[30m (esc)
258 274
259 275 #endif
260 276
261 277
262 278 $ echo "^ignoreddir$" > .hgignore
263 279 $ mkdir ignoreddir
264 280 $ touch ignoreddir/file
265 281
266 282 hg status ignoreddir/file:
267 283
268 284 $ hg status ignoreddir/file
269 285
270 286 hg status -i ignoreddir/file:
271 287
272 288 $ hg status -i ignoreddir/file
273 289 \x1b[0;30;1mI \x1b[0m\x1b[0;30;1mignoreddir/file\x1b[0m (esc)
274 290 $ cd ..
275 291
276 292 check 'status -q' and some combinations
277 293
278 294 $ hg init repo3
279 295 $ cd repo3
280 296 $ touch modified removed deleted ignored
281 297 $ echo "^ignored$" > .hgignore
282 298 $ hg commit -A -m 'initial checkin'
283 299 adding .hgignore
284 300 adding deleted
285 301 adding modified
286 302 adding removed
287 303 $ touch added unknown ignored
288 304 $ hg add added
289 305 $ echo "test" >> modified
290 306 $ hg remove removed
291 307 $ rm deleted
292 308 $ hg copy modified copied
293 309
294 310 test unknown color
295 311
296 312 $ hg --config color.status.modified=periwinkle status
297 313 ignoring unknown color/effect 'periwinkle' (configured in color.status.modified)
298 314 ignoring unknown color/effect 'periwinkle' (configured in color.status.modified)
299 315 ignoring unknown color/effect 'periwinkle' (configured in color.status.modified)
300 316 M modified
301 317 \x1b[0;32;1mA \x1b[0m\x1b[0;32;1madded\x1b[0m (esc)
302 318 \x1b[0;32;1mA \x1b[0m\x1b[0;32;1mcopied\x1b[0m (esc)
303 319 \x1b[0;31;1mR \x1b[0m\x1b[0;31;1mremoved\x1b[0m (esc)
304 320 \x1b[0;36;1;4m! \x1b[0m\x1b[0;36;1;4mdeleted\x1b[0m (esc)
305 321 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4munknown\x1b[0m (esc)
306 322
307 323 Run status with 2 different flags.
308 324 Check if result is the same or different.
309 325 If result is not as expected, raise error
310 326
311 327 $ assert() {
312 328 > hg status $1 > ../a
313 329 > hg status $2 > ../b
314 330 > if diff ../a ../b > /dev/null; then
315 331 > out=0
316 332 > else
317 333 > out=1
318 334 > fi
319 335 > if [ $3 -eq 0 ]; then
320 336 > df="same"
321 337 > else
322 338 > df="different"
323 339 > fi
324 340 > if [ $out -ne $3 ]; then
325 341 > echo "Error on $1 and $2, should be $df."
326 342 > fi
327 343 > }
328 344
329 345 assert flag1 flag2 [0-same | 1-different]
330 346
331 347 $ assert "-q" "-mard" 0
332 348 $ assert "-A" "-marduicC" 0
333 349 $ assert "-qA" "-mardcC" 0
334 350 $ assert "-qAui" "-A" 0
335 351 $ assert "-qAu" "-marducC" 0
336 352 $ assert "-qAi" "-mardicC" 0
337 353 $ assert "-qu" "-u" 0
338 354 $ assert "-q" "-u" 1
339 355 $ assert "-m" "-a" 1
340 356 $ assert "-r" "-d" 1
341 357 $ cd ..
342 358
343 359 test 'resolve -l'
344 360
345 361 $ hg init repo4
346 362 $ cd repo4
347 363 $ echo "file a" > a
348 364 $ echo "file b" > b
349 365 $ hg add a b
350 366 $ hg commit -m "initial"
351 367 $ echo "file a change 1" > a
352 368 $ echo "file b change 1" > b
353 369 $ hg commit -m "head 1"
354 370 $ hg update 0
355 371 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
356 372 $ echo "file a change 2" > a
357 373 $ echo "file b change 2" > b
358 374 $ hg commit -m "head 2"
359 375 created new head
360 376 $ hg merge
361 377 merging a
362 378 merging b
363 379 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
364 380 warning: conflicts while merging b! (edit, then use 'hg resolve --mark')
365 381 0 files updated, 0 files merged, 0 files removed, 2 files unresolved
366 382 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
367 383 [1]
368 384 $ hg resolve -m b
369 385
370 386 hg resolve with one unresolved, one resolved:
371 387
372 388 $ hg resolve -l
373 389 \x1b[0;31;1mU \x1b[0m\x1b[0;31;1ma\x1b[0m (esc)
374 390 \x1b[0;32;1mR \x1b[0m\x1b[0;32;1mb\x1b[0m (esc)
375 391
376 392 color coding of error message with current availability of curses
377 393
378 394 $ hg unknowncommand > /dev/null
379 395 hg: unknown command 'unknowncommand'
380 396 [255]
381 397
382 398 color coding of error message without curses
383 399
384 400 $ echo 'raise ImportError' > curses.py
385 401 $ PYTHONPATH=`pwd`:$PYTHONPATH hg unknowncommand > /dev/null
386 402 hg: unknown command 'unknowncommand'
387 403 [255]
388 404
389 405 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now