##// END OF EJS Templates
addremove: add associated color for the new labels...
Boris Feld -
r39126:ddc1da13 default
parent child Browse files
Show More
@@ -1,535 +1,537 b''
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 )
18 18
19 19 from .utils import (
20 20 stringutil,
21 21 )
22 22
23 23 try:
24 24 import curses
25 25 # Mapping from effect name to terminfo attribute name (or raw code) or
26 26 # color number. This will also force-load the curses module.
27 27 _baseterminfoparams = {
28 28 'none': (True, 'sgr0', ''),
29 29 'standout': (True, 'smso', ''),
30 30 'underline': (True, 'smul', ''),
31 31 'reverse': (True, 'rev', ''),
32 32 'inverse': (True, 'rev', ''),
33 33 'blink': (True, 'blink', ''),
34 34 'dim': (True, 'dim', ''),
35 35 'bold': (True, 'bold', ''),
36 36 'invisible': (True, 'invis', ''),
37 37 'italic': (True, 'sitm', ''),
38 38 'black': (False, curses.COLOR_BLACK, ''),
39 39 'red': (False, curses.COLOR_RED, ''),
40 40 'green': (False, curses.COLOR_GREEN, ''),
41 41 'yellow': (False, curses.COLOR_YELLOW, ''),
42 42 'blue': (False, curses.COLOR_BLUE, ''),
43 43 'magenta': (False, curses.COLOR_MAGENTA, ''),
44 44 'cyan': (False, curses.COLOR_CYAN, ''),
45 45 'white': (False, curses.COLOR_WHITE, ''),
46 46 }
47 47 except ImportError:
48 48 curses = None
49 49 _baseterminfoparams = {}
50 50
51 51 # start and stop parameters for effects
52 52 _effects = {
53 53 'none': 0,
54 54 'black': 30,
55 55 'red': 31,
56 56 'green': 32,
57 57 'yellow': 33,
58 58 'blue': 34,
59 59 'magenta': 35,
60 60 'cyan': 36,
61 61 'white': 37,
62 62 'bold': 1,
63 63 'italic': 3,
64 64 'underline': 4,
65 65 'inverse': 7,
66 66 'dim': 2,
67 67 'black_background': 40,
68 68 'red_background': 41,
69 69 'green_background': 42,
70 70 'yellow_background': 43,
71 71 'blue_background': 44,
72 72 'purple_background': 45,
73 73 'cyan_background': 46,
74 74 'white_background': 47,
75 75 }
76 76
77 77 _defaultstyles = {
78 78 'grep.match': 'red bold',
79 79 'grep.linenumber': 'green',
80 80 'grep.rev': 'green',
81 81 'grep.change': 'green',
82 82 'grep.sep': 'cyan',
83 83 'grep.filename': 'magenta',
84 84 'grep.user': 'magenta',
85 85 'grep.date': 'magenta',
86 'addremove.added': 'green',
87 'addremove.removed': 'red',
86 88 'bookmarks.active': 'green',
87 89 'branches.active': 'none',
88 90 'branches.closed': 'black bold',
89 91 'branches.current': 'green',
90 92 'branches.inactive': 'none',
91 93 'diff.changed': 'white',
92 94 'diff.deleted': 'red',
93 95 'diff.deleted.changed': 'red bold underline',
94 96 'diff.deleted.unchanged': 'red',
95 97 'diff.diffline': 'bold',
96 98 'diff.extended': 'cyan bold',
97 99 'diff.file_a': 'red bold',
98 100 'diff.file_b': 'green bold',
99 101 'diff.hunk': 'magenta',
100 102 'diff.inserted': 'green',
101 103 'diff.inserted.changed': 'green bold underline',
102 104 'diff.inserted.unchanged': 'green',
103 105 'diff.tab': '',
104 106 'diff.trailingwhitespace': 'bold red_background',
105 107 'changeset.public': '',
106 108 'changeset.draft': '',
107 109 'changeset.secret': '',
108 110 'diffstat.deleted': 'red',
109 111 'diffstat.inserted': 'green',
110 112 'formatvariant.name.mismatchconfig': 'red',
111 113 'formatvariant.name.mismatchdefault': 'yellow',
112 114 'formatvariant.name.uptodate': 'green',
113 115 'formatvariant.repo.mismatchconfig': 'red',
114 116 'formatvariant.repo.mismatchdefault': 'yellow',
115 117 'formatvariant.repo.uptodate': 'green',
116 118 'formatvariant.config.special': 'yellow',
117 119 'formatvariant.config.default': 'green',
118 120 'formatvariant.default': '',
119 121 'histedit.remaining': 'red bold',
120 122 'ui.error': 'red',
121 123 'ui.prompt': 'yellow',
122 124 'log.changeset': 'yellow',
123 125 'patchbomb.finalsummary': '',
124 126 'patchbomb.from': 'magenta',
125 127 'patchbomb.to': 'cyan',
126 128 'patchbomb.subject': 'green',
127 129 'patchbomb.diffstats': '',
128 130 'rebase.rebased': 'blue',
129 131 'rebase.remaining': 'red bold',
130 132 'resolve.resolved': 'green bold',
131 133 'resolve.unresolved': 'red bold',
132 134 'shelve.age': 'cyan',
133 135 'shelve.newest': 'green bold',
134 136 'shelve.name': 'blue bold',
135 137 'status.added': 'green bold',
136 138 'status.clean': 'none',
137 139 'status.copied': 'none',
138 140 'status.deleted': 'cyan bold underline',
139 141 'status.ignored': 'black bold',
140 142 'status.modified': 'blue bold',
141 143 'status.removed': 'red bold',
142 144 'status.unknown': 'magenta bold underline',
143 145 'tags.normal': 'green',
144 146 'tags.local': 'black bold',
145 147 }
146 148
147 149 def loadcolortable(ui, extname, colortable):
148 150 _defaultstyles.update(colortable)
149 151
150 152 def _terminfosetup(ui, mode, formatted):
151 153 '''Initialize terminfo data and the terminal if we're in terminfo mode.'''
152 154
153 155 # If we failed to load curses, we go ahead and return.
154 156 if curses is None:
155 157 return
156 158 # Otherwise, see what the config file says.
157 159 if mode not in ('auto', 'terminfo'):
158 160 return
159 161 ui._terminfoparams.update(_baseterminfoparams)
160 162
161 163 for key, val in ui.configitems('color'):
162 164 if key.startswith('color.'):
163 165 newval = (False, int(val), '')
164 166 ui._terminfoparams[key[6:]] = newval
165 167 elif key.startswith('terminfo.'):
166 168 newval = (True, '', val.replace('\\E', '\x1b'))
167 169 ui._terminfoparams[key[9:]] = newval
168 170 try:
169 171 curses.setupterm()
170 172 except curses.error as e:
171 173 ui._terminfoparams.clear()
172 174 return
173 175
174 176 for key, (b, e, c) in ui._terminfoparams.copy().items():
175 177 if not b:
176 178 continue
177 179 if not c and not curses.tigetstr(pycompat.sysstr(e)):
178 180 # Most terminals don't support dim, invis, etc, so don't be
179 181 # noisy and use ui.debug().
180 182 ui.debug("no terminfo entry for %s\n" % e)
181 183 del ui._terminfoparams[key]
182 184 if not curses.tigetstr(r'setaf') or not curses.tigetstr(r'setab'):
183 185 # Only warn about missing terminfo entries if we explicitly asked for
184 186 # terminfo mode and we're in a formatted terminal.
185 187 if mode == "terminfo" and formatted:
186 188 ui.warn(_("no terminfo entry for setab/setaf: reverting to "
187 189 "ECMA-48 color\n"))
188 190 ui._terminfoparams.clear()
189 191
190 192 def setup(ui):
191 193 """configure color on a ui
192 194
193 195 That function both set the colormode for the ui object and read
194 196 the configuration looking for custom colors and effect definitions."""
195 197 mode = _modesetup(ui)
196 198 ui._colormode = mode
197 199 if mode and mode != 'debug':
198 200 configstyles(ui)
199 201
200 202 def _modesetup(ui):
201 203 if ui.plain('color'):
202 204 return None
203 205 config = ui.config('ui', 'color')
204 206 if config == 'debug':
205 207 return 'debug'
206 208
207 209 auto = (config == 'auto')
208 210 always = False
209 211 if not auto and stringutil.parsebool(config):
210 212 # We want the config to behave like a boolean, "on" is actually auto,
211 213 # but "always" value is treated as a special case to reduce confusion.
212 214 if ui.configsource('ui', 'color') == '--color' or config == 'always':
213 215 always = True
214 216 else:
215 217 auto = True
216 218
217 219 if not always and not auto:
218 220 return None
219 221
220 222 formatted = (always or (encoding.environ.get('TERM') != 'dumb'
221 223 and ui.formatted()))
222 224
223 225 mode = ui.config('color', 'mode')
224 226
225 227 # If pager is active, color.pagermode overrides color.mode.
226 228 if getattr(ui, 'pageractive', False):
227 229 mode = ui.config('color', 'pagermode', mode)
228 230
229 231 realmode = mode
230 232 if pycompat.iswindows:
231 233 from . import win32
232 234
233 235 term = encoding.environ.get('TERM')
234 236 # TERM won't be defined in a vanilla cmd.exe environment.
235 237
236 238 # UNIX-like environments on Windows such as Cygwin and MSYS will
237 239 # set TERM. They appear to make a best effort attempt at setting it
238 240 # to something appropriate. However, not all environments with TERM
239 241 # defined support ANSI.
240 242 ansienviron = term and 'xterm' in term
241 243
242 244 if mode == 'auto':
243 245 # Since "ansi" could result in terminal gibberish, we error on the
244 246 # side of selecting "win32". However, if w32effects is not defined,
245 247 # we almost certainly don't support "win32", so don't even try.
246 248 # w32ffects is not populated when stdout is redirected, so checking
247 249 # it first avoids win32 calls in a state known to error out.
248 250 if ansienviron or not w32effects or win32.enablevtmode():
249 251 realmode = 'ansi'
250 252 else:
251 253 realmode = 'win32'
252 254 # An empty w32effects is a clue that stdout is redirected, and thus
253 255 # cannot enable VT mode.
254 256 elif mode == 'ansi' and w32effects and not ansienviron:
255 257 win32.enablevtmode()
256 258 elif mode == 'auto':
257 259 realmode = 'ansi'
258 260
259 261 def modewarn():
260 262 # only warn if color.mode was explicitly set and we're in
261 263 # a formatted terminal
262 264 if mode == realmode and formatted:
263 265 ui.warn(_('warning: failed to set color mode to %s\n') % mode)
264 266
265 267 if realmode == 'win32':
266 268 ui._terminfoparams.clear()
267 269 if not w32effects:
268 270 modewarn()
269 271 return None
270 272 elif realmode == 'ansi':
271 273 ui._terminfoparams.clear()
272 274 elif realmode == 'terminfo':
273 275 _terminfosetup(ui, mode, formatted)
274 276 if not ui._terminfoparams:
275 277 ## FIXME Shouldn't we return None in this case too?
276 278 modewarn()
277 279 realmode = 'ansi'
278 280 else:
279 281 return None
280 282
281 283 if always or (auto and formatted):
282 284 return realmode
283 285 return None
284 286
285 287 def configstyles(ui):
286 288 ui._styles.update(_defaultstyles)
287 289 for status, cfgeffects in ui.configitems('color'):
288 290 if '.' not in status or status.startswith(('color.', 'terminfo.')):
289 291 continue
290 292 cfgeffects = ui.configlist('color', status)
291 293 if cfgeffects:
292 294 good = []
293 295 for e in cfgeffects:
294 296 if valideffect(ui, e):
295 297 good.append(e)
296 298 else:
297 299 ui.warn(_("ignoring unknown color/effect %r "
298 300 "(configured in color.%s)\n")
299 301 % (e, status))
300 302 ui._styles[status] = ' '.join(good)
301 303
302 304 def _activeeffects(ui):
303 305 '''Return the effects map for the color mode set on the ui.'''
304 306 if ui._colormode == 'win32':
305 307 return w32effects
306 308 elif ui._colormode is not None:
307 309 return _effects
308 310 return {}
309 311
310 312 def valideffect(ui, effect):
311 313 'Determine if the effect is valid or not.'
312 314 return ((not ui._terminfoparams and effect in _activeeffects(ui))
313 315 or (effect in ui._terminfoparams
314 316 or effect[:-11] in ui._terminfoparams))
315 317
316 318 def _effect_str(ui, effect):
317 319 '''Helper function for render_effects().'''
318 320
319 321 bg = False
320 322 if effect.endswith('_background'):
321 323 bg = True
322 324 effect = effect[:-11]
323 325 try:
324 326 attr, val, termcode = ui._terminfoparams[effect]
325 327 except KeyError:
326 328 return ''
327 329 if attr:
328 330 if termcode:
329 331 return termcode
330 332 else:
331 333 return curses.tigetstr(pycompat.sysstr(val))
332 334 elif bg:
333 335 return curses.tparm(curses.tigetstr(r'setab'), val)
334 336 else:
335 337 return curses.tparm(curses.tigetstr(r'setaf'), val)
336 338
337 339 def _mergeeffects(text, start, stop):
338 340 """Insert start sequence at every occurrence of stop sequence
339 341
340 342 >>> s = _mergeeffects(b'cyan', b'[C]', b'|')
341 343 >>> s = _mergeeffects(s + b'yellow', b'[Y]', b'|')
342 344 >>> s = _mergeeffects(b'ma' + s + b'genta', b'[M]', b'|')
343 345 >>> s = _mergeeffects(b'red' + s, b'[R]', b'|')
344 346 >>> s
345 347 '[R]red[M]ma[Y][C]cyan|[R][M][Y]yellow|[R][M]genta|'
346 348 """
347 349 parts = []
348 350 for t in text.split(stop):
349 351 if not t:
350 352 continue
351 353 parts.extend([start, t, stop])
352 354 return ''.join(parts)
353 355
354 356 def _render_effects(ui, text, effects):
355 357 'Wrap text in commands to turn on each effect.'
356 358 if not text:
357 359 return text
358 360 if ui._terminfoparams:
359 361 start = ''.join(_effect_str(ui, effect)
360 362 for effect in ['none'] + effects.split())
361 363 stop = _effect_str(ui, 'none')
362 364 else:
363 365 activeeffects = _activeeffects(ui)
364 366 start = [pycompat.bytestr(activeeffects[e])
365 367 for e in ['none'] + effects.split()]
366 368 start = '\033[' + ';'.join(start) + 'm'
367 369 stop = '\033[' + pycompat.bytestr(activeeffects['none']) + 'm'
368 370 return _mergeeffects(text, start, stop)
369 371
370 372 _ansieffectre = re.compile(br'\x1b\[[0-9;]*m')
371 373
372 374 def stripeffects(text):
373 375 """Strip ANSI control codes which could be inserted by colorlabel()"""
374 376 return _ansieffectre.sub('', text)
375 377
376 378 def colorlabel(ui, msg, label):
377 379 """add color control code according to the mode"""
378 380 if ui._colormode == 'debug':
379 381 if label and msg:
380 382 if msg.endswith('\n'):
381 383 msg = "[%s|%s]\n" % (label, msg[:-1])
382 384 else:
383 385 msg = "[%s|%s]" % (label, msg)
384 386 elif ui._colormode is not None:
385 387 effects = []
386 388 for l in label.split():
387 389 s = ui._styles.get(l, '')
388 390 if s:
389 391 effects.append(s)
390 392 elif valideffect(ui, l):
391 393 effects.append(l)
392 394 effects = ' '.join(effects)
393 395 if effects:
394 396 msg = '\n'.join([_render_effects(ui, line, effects)
395 397 for line in msg.split('\n')])
396 398 return msg
397 399
398 400 w32effects = None
399 401 if pycompat.iswindows:
400 402 import ctypes
401 403
402 404 _kernel32 = ctypes.windll.kernel32
403 405
404 406 _WORD = ctypes.c_ushort
405 407
406 408 _INVALID_HANDLE_VALUE = -1
407 409
408 410 class _COORD(ctypes.Structure):
409 411 _fields_ = [('X', ctypes.c_short),
410 412 ('Y', ctypes.c_short)]
411 413
412 414 class _SMALL_RECT(ctypes.Structure):
413 415 _fields_ = [('Left', ctypes.c_short),
414 416 ('Top', ctypes.c_short),
415 417 ('Right', ctypes.c_short),
416 418 ('Bottom', ctypes.c_short)]
417 419
418 420 class _CONSOLE_SCREEN_BUFFER_INFO(ctypes.Structure):
419 421 _fields_ = [('dwSize', _COORD),
420 422 ('dwCursorPosition', _COORD),
421 423 ('wAttributes', _WORD),
422 424 ('srWindow', _SMALL_RECT),
423 425 ('dwMaximumWindowSize', _COORD)]
424 426
425 427 _STD_OUTPUT_HANDLE = 0xfffffff5 # (DWORD)-11
426 428 _STD_ERROR_HANDLE = 0xfffffff4 # (DWORD)-12
427 429
428 430 _FOREGROUND_BLUE = 0x0001
429 431 _FOREGROUND_GREEN = 0x0002
430 432 _FOREGROUND_RED = 0x0004
431 433 _FOREGROUND_INTENSITY = 0x0008
432 434
433 435 _BACKGROUND_BLUE = 0x0010
434 436 _BACKGROUND_GREEN = 0x0020
435 437 _BACKGROUND_RED = 0x0040
436 438 _BACKGROUND_INTENSITY = 0x0080
437 439
438 440 _COMMON_LVB_REVERSE_VIDEO = 0x4000
439 441 _COMMON_LVB_UNDERSCORE = 0x8000
440 442
441 443 # http://msdn.microsoft.com/en-us/library/ms682088%28VS.85%29.aspx
442 444 w32effects = {
443 445 'none': -1,
444 446 'black': 0,
445 447 'red': _FOREGROUND_RED,
446 448 'green': _FOREGROUND_GREEN,
447 449 'yellow': _FOREGROUND_RED | _FOREGROUND_GREEN,
448 450 'blue': _FOREGROUND_BLUE,
449 451 'magenta': _FOREGROUND_BLUE | _FOREGROUND_RED,
450 452 'cyan': _FOREGROUND_BLUE | _FOREGROUND_GREEN,
451 453 'white': _FOREGROUND_RED | _FOREGROUND_GREEN | _FOREGROUND_BLUE,
452 454 'bold': _FOREGROUND_INTENSITY,
453 455 'black_background': 0x100, # unused value > 0x0f
454 456 'red_background': _BACKGROUND_RED,
455 457 'green_background': _BACKGROUND_GREEN,
456 458 'yellow_background': _BACKGROUND_RED | _BACKGROUND_GREEN,
457 459 'blue_background': _BACKGROUND_BLUE,
458 460 'purple_background': _BACKGROUND_BLUE | _BACKGROUND_RED,
459 461 'cyan_background': _BACKGROUND_BLUE | _BACKGROUND_GREEN,
460 462 'white_background': (_BACKGROUND_RED | _BACKGROUND_GREEN |
461 463 _BACKGROUND_BLUE),
462 464 'bold_background': _BACKGROUND_INTENSITY,
463 465 'underline': _COMMON_LVB_UNDERSCORE, # double-byte charsets only
464 466 'inverse': _COMMON_LVB_REVERSE_VIDEO, # double-byte charsets only
465 467 }
466 468
467 469 passthrough = {_FOREGROUND_INTENSITY,
468 470 _BACKGROUND_INTENSITY,
469 471 _COMMON_LVB_UNDERSCORE,
470 472 _COMMON_LVB_REVERSE_VIDEO}
471 473
472 474 stdout = _kernel32.GetStdHandle(
473 475 _STD_OUTPUT_HANDLE) # don't close the handle returned
474 476 if stdout is None or stdout == _INVALID_HANDLE_VALUE:
475 477 w32effects = None
476 478 else:
477 479 csbi = _CONSOLE_SCREEN_BUFFER_INFO()
478 480 if not _kernel32.GetConsoleScreenBufferInfo(
479 481 stdout, ctypes.byref(csbi)):
480 482 # stdout may not support GetConsoleScreenBufferInfo()
481 483 # when called from subprocess or redirected
482 484 w32effects = None
483 485 else:
484 486 origattr = csbi.wAttributes
485 487 ansire = re.compile('\033\[([^m]*)m([^\033]*)(.*)',
486 488 re.MULTILINE | re.DOTALL)
487 489
488 490 def win32print(ui, writefunc, *msgs, **opts):
489 491 for text in msgs:
490 492 _win32print(ui, text, writefunc, **opts)
491 493
492 494 def _win32print(ui, text, writefunc, **opts):
493 495 label = opts.get(r'label', '')
494 496 attr = origattr
495 497
496 498 def mapcolor(val, attr):
497 499 if val == -1:
498 500 return origattr
499 501 elif val in passthrough:
500 502 return attr | val
501 503 elif val > 0x0f:
502 504 return (val & 0x70) | (attr & 0x8f)
503 505 else:
504 506 return (val & 0x07) | (attr & 0xf8)
505 507
506 508 # determine console attributes based on labels
507 509 for l in label.split():
508 510 style = ui._styles.get(l, '')
509 511 for effect in style.split():
510 512 try:
511 513 attr = mapcolor(w32effects[effect], attr)
512 514 except KeyError:
513 515 # w32effects could not have certain attributes so we skip
514 516 # them if not found
515 517 pass
516 518 # hack to ensure regexp finds data
517 519 if not text.startswith('\033['):
518 520 text = '\033[m' + text
519 521
520 522 # Look for ANSI-like codes embedded in text
521 523 m = re.match(ansire, text)
522 524
523 525 try:
524 526 while m:
525 527 for sattr in m.group(1).split(';'):
526 528 if sattr:
527 529 attr = mapcolor(int(sattr), attr)
528 530 ui.flush()
529 531 _kernel32.SetConsoleTextAttribute(stdout, attr)
530 532 writefunc(m.group(2), **opts)
531 533 m = re.match(ansire, m.group(3))
532 534 finally:
533 535 # Explicitly reset original attributes
534 536 ui.flush()
535 537 _kernel32.SetConsoleTextAttribute(stdout, origattr)
@@ -1,416 +1,416 b''
1 1 Setup
2 2
3 3 $ cat <<EOF >> $HGRCPATH
4 4 > [ui]
5 5 > color = yes
6 6 > formatted = always
7 7 > paginate = never
8 8 > [color]
9 9 > mode = ansi
10 10 > EOF
11 11 $ hg init repo
12 12 $ cd repo
13 13 $ cat > a <<EOF
14 14 > c
15 15 > c
16 16 > a
17 17 > a
18 18 > b
19 19 > a
20 20 > a
21 21 > c
22 22 > c
23 23 > EOF
24 24 $ hg ci -Am adda
25 adding a
25 \x1b[0;32madding a\x1b[0m (esc)
26 26 $ cat > a <<EOF
27 27 > c
28 28 > c
29 29 > a
30 30 > a
31 31 > dd
32 32 > a
33 33 > a
34 34 > c
35 35 > c
36 36 > EOF
37 37
38 38 default context
39 39
40 40 $ hg diff --nodates
41 41 \x1b[0;1mdiff -r cf9f4ba66af2 a\x1b[0m (esc)
42 42 \x1b[0;31;1m--- a/a\x1b[0m (esc)
43 43 \x1b[0;32;1m+++ b/a\x1b[0m (esc)
44 44 \x1b[0;35m@@ -2,7 +2,7 @@\x1b[0m (esc)
45 45 c
46 46 a
47 47 a
48 48 \x1b[0;31m-b\x1b[0m (esc)
49 49 \x1b[0;32m+dd\x1b[0m (esc)
50 50 a
51 51 a
52 52 c
53 53
54 54 trailing whitespace
55 55
56 56 $ cp a a.orig
57 57 >>> with open('a', 'rb') as f:
58 58 ... data = f.read()
59 59 >>> with open('a', 'wb') as f:
60 60 ... f.write(data.replace('dd', 'dd \r'))
61 61 $ hg diff --nodates
62 62 \x1b[0;1mdiff -r cf9f4ba66af2 a\x1b[0m (esc)
63 63 \x1b[0;31;1m--- a/a\x1b[0m (esc)
64 64 \x1b[0;32;1m+++ b/a\x1b[0m (esc)
65 65 \x1b[0;35m@@ -2,7 +2,7 @@\x1b[0m (esc)
66 66 c
67 67 a
68 68 a
69 69 \x1b[0;31m-b\x1b[0m (esc)
70 70 \x1b[0;32m+dd\x1b[0m\x1b[0;1;41m \x1b[0m\r (esc)
71 71 a
72 72 a
73 73 c
74 74
75 75 $ mv a.orig a
76 76
77 77 (check that 'ui.color=yes' match '--color=auto')
78 78
79 79 $ hg diff --nodates --config ui.formatted=no
80 80 diff -r cf9f4ba66af2 a
81 81 --- a/a
82 82 +++ b/a
83 83 @@ -2,7 +2,7 @@
84 84 c
85 85 a
86 86 a
87 87 -b
88 88 +dd
89 89 a
90 90 a
91 91 c
92 92
93 93 (check that 'ui.color=no' disable color)
94 94
95 95 $ hg diff --nodates --config ui.formatted=yes --config ui.color=no
96 96 diff -r cf9f4ba66af2 a
97 97 --- a/a
98 98 +++ b/a
99 99 @@ -2,7 +2,7 @@
100 100 c
101 101 a
102 102 a
103 103 -b
104 104 +dd
105 105 a
106 106 a
107 107 c
108 108
109 109 (check that 'ui.color=always' force color)
110 110
111 111 $ hg diff --nodates --config ui.formatted=no --config ui.color=always
112 112 \x1b[0;1mdiff -r cf9f4ba66af2 a\x1b[0m (esc)
113 113 \x1b[0;31;1m--- a/a\x1b[0m (esc)
114 114 \x1b[0;32;1m+++ b/a\x1b[0m (esc)
115 115 \x1b[0;35m@@ -2,7 +2,7 @@\x1b[0m (esc)
116 116 c
117 117 a
118 118 a
119 119 \x1b[0;31m-b\x1b[0m (esc)
120 120 \x1b[0;32m+dd\x1b[0m (esc)
121 121 a
122 122 a
123 123 c
124 124
125 125 --unified=2
126 126
127 127 $ hg diff --nodates -U 2
128 128 \x1b[0;1mdiff -r cf9f4ba66af2 a\x1b[0m (esc)
129 129 \x1b[0;31;1m--- a/a\x1b[0m (esc)
130 130 \x1b[0;32;1m+++ b/a\x1b[0m (esc)
131 131 \x1b[0;35m@@ -3,5 +3,5 @@\x1b[0m (esc)
132 132 a
133 133 a
134 134 \x1b[0;31m-b\x1b[0m (esc)
135 135 \x1b[0;32m+dd\x1b[0m (esc)
136 136 a
137 137 a
138 138
139 139 diffstat
140 140
141 141 $ hg diff --stat
142 142 a | 2 \x1b[0;32m+\x1b[0m\x1b[0;31m-\x1b[0m (esc)
143 143 1 files changed, 1 insertions(+), 1 deletions(-)
144 144 $ cat <<EOF >> $HGRCPATH
145 145 > [extensions]
146 146 > record =
147 147 > [ui]
148 148 > interactive = true
149 149 > [diff]
150 150 > git = True
151 151 > EOF
152 152
153 153 #if execbit
154 154
155 155 record
156 156
157 157 $ chmod +x a
158 158 $ hg record -m moda a <<EOF
159 159 > y
160 160 > y
161 161 > EOF
162 162 \x1b[0;1mdiff --git a/a b/a\x1b[0m (esc)
163 163 \x1b[0;36;1mold mode 100644\x1b[0m (esc)
164 164 \x1b[0;36;1mnew mode 100755\x1b[0m (esc)
165 165 1 hunks, 1 lines changed
166 166 \x1b[0;33mexamine changes to 'a'? [Ynesfdaq?]\x1b[0m y (esc)
167 167
168 168 \x1b[0;35m@@ -2,7 +2,7 @@ c\x1b[0m (esc)
169 169 c
170 170 a
171 171 a
172 172 \x1b[0;31m-b\x1b[0m (esc)
173 173 \x1b[0;32m+dd\x1b[0m (esc)
174 174 a
175 175 a
176 176 c
177 177 \x1b[0;33mrecord this change to 'a'? [Ynesfdaq?]\x1b[0m y (esc)
178 178
179 179
180 180 $ echo "[extensions]" >> $HGRCPATH
181 181 $ echo "mq=" >> $HGRCPATH
182 182 $ hg rollback
183 183 repository tip rolled back to revision 0 (undo commit)
184 184 working directory now based on revision 0
185 185
186 186 qrecord
187 187
188 188 $ hg qrecord -m moda patch <<EOF
189 189 > y
190 190 > y
191 191 > EOF
192 192 \x1b[0;1mdiff --git a/a b/a\x1b[0m (esc)
193 193 \x1b[0;36;1mold mode 100644\x1b[0m (esc)
194 194 \x1b[0;36;1mnew mode 100755\x1b[0m (esc)
195 195 1 hunks, 1 lines changed
196 196 \x1b[0;33mexamine changes to 'a'? [Ynesfdaq?]\x1b[0m y (esc)
197 197
198 198 \x1b[0;35m@@ -2,7 +2,7 @@ c\x1b[0m (esc)
199 199 c
200 200 a
201 201 a
202 202 \x1b[0;31m-b\x1b[0m (esc)
203 203 \x1b[0;32m+dd\x1b[0m (esc)
204 204 a
205 205 a
206 206 c
207 207 \x1b[0;33mrecord this change to 'a'? [Ynesfdaq?]\x1b[0m y (esc)
208 208
209 209
210 210 $ hg qpop -a
211 211 popping patch
212 212 patch queue now empty
213 213
214 214 #endif
215 215
216 216 issue3712: test colorization of subrepo diff
217 217
218 218 $ hg init sub
219 219 $ echo b > sub/b
220 220 $ hg -R sub commit -Am 'create sub'
221 adding b
221 \x1b[0;32madding b\x1b[0m (esc)
222 222 $ echo 'sub = sub' > .hgsub
223 223 $ hg add .hgsub
224 224 $ hg commit -m 'add subrepo sub'
225 225 $ echo aa >> a
226 226 $ echo bb >> sub/b
227 227
228 228 $ hg diff -S
229 229 \x1b[0;1mdiff --git a/a b/a\x1b[0m (esc)
230 230 \x1b[0;31;1m--- a/a\x1b[0m (esc)
231 231 \x1b[0;32;1m+++ b/a\x1b[0m (esc)
232 232 \x1b[0;35m@@ -7,3 +7,4 @@\x1b[0m (esc)
233 233 a
234 234 c
235 235 c
236 236 \x1b[0;32m+aa\x1b[0m (esc)
237 237 \x1b[0;1mdiff --git a/sub/b b/sub/b\x1b[0m (esc)
238 238 \x1b[0;31;1m--- a/sub/b\x1b[0m (esc)
239 239 \x1b[0;32;1m+++ b/sub/b\x1b[0m (esc)
240 240 \x1b[0;35m@@ -1,1 +1,2 @@\x1b[0m (esc)
241 241 b
242 242 \x1b[0;32m+bb\x1b[0m (esc)
243 243
244 244 test tabs
245 245
246 246 $ cat >> a <<EOF
247 247 > one tab
248 248 > two tabs
249 249 > end tab
250 250 > mid tab
251 251 > all tabs
252 252 > EOF
253 253 $ hg diff --nodates
254 254 \x1b[0;1mdiff --git a/a b/a\x1b[0m (esc)
255 255 \x1b[0;31;1m--- a/a\x1b[0m (esc)
256 256 \x1b[0;32;1m+++ b/a\x1b[0m (esc)
257 257 \x1b[0;35m@@ -7,3 +7,9 @@\x1b[0m (esc)
258 258 a
259 259 c
260 260 c
261 261 \x1b[0;32m+aa\x1b[0m (esc)
262 262 \x1b[0;32m+\x1b[0m \x1b[0;32mone tab\x1b[0m (esc)
263 263 \x1b[0;32m+\x1b[0m \x1b[0;32mtwo tabs\x1b[0m (esc)
264 264 \x1b[0;32m+end tab\x1b[0m\x1b[0;1;41m \x1b[0m (esc)
265 265 \x1b[0;32m+mid\x1b[0m \x1b[0;32mtab\x1b[0m (esc)
266 266 \x1b[0;32m+\x1b[0m \x1b[0;32mall\x1b[0m \x1b[0;32mtabs\x1b[0m\x1b[0;1;41m \x1b[0m (esc)
267 267 $ echo "[color]" >> $HGRCPATH
268 268 $ echo "diff.tab = bold magenta" >> $HGRCPATH
269 269 $ hg diff --nodates
270 270 \x1b[0;1mdiff --git a/a b/a\x1b[0m (esc)
271 271 \x1b[0;31;1m--- a/a\x1b[0m (esc)
272 272 \x1b[0;32;1m+++ b/a\x1b[0m (esc)
273 273 \x1b[0;35m@@ -7,3 +7,9 @@\x1b[0m (esc)
274 274 a
275 275 c
276 276 c
277 277 \x1b[0;32m+aa\x1b[0m (esc)
278 278 \x1b[0;32m+\x1b[0m\x1b[0;1;35m \x1b[0m\x1b[0;32mone tab\x1b[0m (esc)
279 279 \x1b[0;32m+\x1b[0m\x1b[0;1;35m \x1b[0m\x1b[0;32mtwo tabs\x1b[0m (esc)
280 280 \x1b[0;32m+end tab\x1b[0m\x1b[0;1;41m \x1b[0m (esc)
281 281 \x1b[0;32m+mid\x1b[0m\x1b[0;1;35m \x1b[0m\x1b[0;32mtab\x1b[0m (esc)
282 282 \x1b[0;32m+\x1b[0m\x1b[0;1;35m \x1b[0m\x1b[0;32mall\x1b[0m\x1b[0;1;35m \x1b[0m\x1b[0;32mtabs\x1b[0m\x1b[0;1;41m \x1b[0m (esc)
283 283
284 284 $ cd ..
285 285
286 286 test inline color diff
287 287
288 288 $ hg init inline
289 289 $ cd inline
290 290 $ cat > file1 << EOF
291 291 > this is the first line
292 292 > this is the second line
293 293 > third line starts with space
294 294 > + starts with a plus sign
295 295 > this one with one tab
296 296 > now with full two tabs
297 297 > now tabs everywhere, much fun
298 298 >
299 299 > this line won't change
300 300 >
301 301 > two lines are going to
302 302 > be changed into three!
303 303 >
304 304 > three of those lines will
305 305 > collapse onto one
306 306 > (to see if it works)
307 307 > EOF
308 308 $ hg add file1
309 309 $ hg ci -m 'commit'
310 310
311 311 $ cat > file1 << EOF
312 312 > that is the first paragraph
313 313 > this is the second line
314 314 > third line starts with space
315 315 > - starts with a minus sign
316 316 > this one with two tab
317 317 > now with full three tabs
318 318 > now there are tabs everywhere, much fun
319 319 >
320 320 > this line won't change
321 321 >
322 322 > two lines are going to
323 323 > (entirely magically,
324 324 > assuming this works)
325 325 > be changed into four!
326 326 >
327 327 > three of those lines have
328 328 > collapsed onto one
329 329 > EOF
330 330 $ hg diff --config diff.word-diff=False --color=debug
331 331 [diff.diffline|diff --git a/file1 b/file1]
332 332 [diff.file_a|--- a/file1]
333 333 [diff.file_b|+++ b/file1]
334 334 [diff.hunk|@@ -1,16 +1,17 @@]
335 335 [diff.deleted|-this is the first line]
336 336 [diff.deleted|-this is the second line]
337 337 [diff.deleted|- third line starts with space]
338 338 [diff.deleted|-+ starts with a plus sign]
339 339 [diff.deleted|-][diff.tab| ][diff.deleted|this one with one tab]
340 340 [diff.deleted|-][diff.tab| ][diff.deleted|now with full two tabs]
341 341 [diff.deleted|-][diff.tab| ][diff.deleted|now tabs][diff.tab| ][diff.deleted|everywhere, much fun]
342 342 [diff.inserted|+that is the first paragraph]
343 343 [diff.inserted|+ this is the second line]
344 344 [diff.inserted|+third line starts with space]
345 345 [diff.inserted|+- starts with a minus sign]
346 346 [diff.inserted|+][diff.tab| ][diff.inserted|this one with two tab]
347 347 [diff.inserted|+][diff.tab| ][diff.inserted|now with full three tabs]
348 348 [diff.inserted|+][diff.tab| ][diff.inserted|now there are tabs][diff.tab| ][diff.inserted|everywhere, much fun]
349 349
350 350 this line won't change
351 351
352 352 two lines are going to
353 353 [diff.deleted|-be changed into three!]
354 354 [diff.inserted|+(entirely magically,]
355 355 [diff.inserted|+ assuming this works)]
356 356 [diff.inserted|+be changed into four!]
357 357
358 358 [diff.deleted|-three of those lines will]
359 359 [diff.deleted|-collapse onto one]
360 360 [diff.deleted|-(to see if it works)]
361 361 [diff.inserted|+three of those lines have]
362 362 [diff.inserted|+collapsed onto one]
363 363 $ hg diff --config diff.word-diff=True --color=debug
364 364 [diff.diffline|diff --git a/file1 b/file1]
365 365 [diff.file_a|--- a/file1]
366 366 [diff.file_b|+++ b/file1]
367 367 [diff.hunk|@@ -1,16 +1,17 @@]
368 368 [diff.deleted|-][diff.deleted.changed|this][diff.deleted.unchanged| is the first ][diff.deleted.changed|line]
369 369 [diff.deleted|-][diff.deleted.unchanged|this is the second line]
370 370 [diff.deleted|-][diff.deleted.changed| ][diff.deleted.unchanged|third line starts with space]
371 371 [diff.deleted|-][diff.deleted.changed|+][diff.deleted.unchanged| starts with a ][diff.deleted.changed|plus][diff.deleted.unchanged| sign]
372 372 [diff.deleted|-][diff.tab| ][diff.deleted.unchanged|this one with ][diff.deleted.changed|one][diff.deleted.unchanged| tab]
373 373 [diff.deleted|-][diff.tab| ][diff.deleted.unchanged|now with full ][diff.deleted.changed|two][diff.deleted.unchanged| tabs]
374 374 [diff.deleted|-][diff.tab| ][diff.deleted.unchanged|now ][diff.deleted.unchanged|tabs][diff.tab| ][diff.deleted.unchanged|everywhere, much fun]
375 375 [diff.inserted|+][diff.inserted.changed|that][diff.inserted.unchanged| is the first ][diff.inserted.changed|paragraph]
376 376 [diff.inserted|+][diff.inserted.changed| ][diff.inserted.unchanged|this is the second line]
377 377 [diff.inserted|+][diff.inserted.unchanged|third line starts with space]
378 378 [diff.inserted|+][diff.inserted.changed|-][diff.inserted.unchanged| starts with a ][diff.inserted.changed|minus][diff.inserted.unchanged| sign]
379 379 [diff.inserted|+][diff.tab| ][diff.inserted.unchanged|this one with ][diff.inserted.changed|two][diff.inserted.unchanged| tab]
380 380 [diff.inserted|+][diff.tab| ][diff.inserted.unchanged|now with full ][diff.inserted.changed|three][diff.inserted.unchanged| tabs]
381 381 [diff.inserted|+][diff.tab| ][diff.inserted.unchanged|now ][diff.inserted.changed|there are ][diff.inserted.unchanged|tabs][diff.tab| ][diff.inserted.unchanged|everywhere, much fun]
382 382
383 383 this line won't change
384 384
385 385 two lines are going to
386 386 [diff.deleted|-][diff.deleted.unchanged|be changed into ][diff.deleted.changed|three][diff.deleted.unchanged|!]
387 387 [diff.inserted|+][diff.inserted.changed|(entirely magically,]
388 388 [diff.inserted|+][diff.inserted.changed| assuming this works)]
389 389 [diff.inserted|+][diff.inserted.unchanged|be changed into ][diff.inserted.changed|four][diff.inserted.unchanged|!]
390 390
391 391 [diff.deleted|-][diff.deleted.unchanged|three of those lines ][diff.deleted.changed|will]
392 392 [diff.deleted|-][diff.deleted.changed|collapse][diff.deleted.unchanged| onto one]
393 393 [diff.deleted|-][diff.deleted.changed|(to see if it works)]
394 394 [diff.inserted|+][diff.inserted.unchanged|three of those lines ][diff.inserted.changed|have]
395 395 [diff.inserted|+][diff.inserted.changed|collapsed][diff.inserted.unchanged| onto one]
396 396
397 397 multibyte character shouldn't be broken up in word diff:
398 398
399 399 $ $PYTHON <<'EOF'
400 400 > with open("utf8", "wb") as f:
401 401 > f.write(b"blah \xe3\x82\xa2 blah\n")
402 402 > EOF
403 403 $ hg ci -Am 'add utf8 char' utf8
404 404 $ $PYTHON <<'EOF'
405 405 > with open("utf8", "wb") as f:
406 406 > f.write(b"blah \xe3\x82\xa4 blah\n")
407 407 > EOF
408 408 $ hg ci -m 'slightly change utf8 char' utf8
409 409
410 410 $ hg diff --config diff.word-diff=True --color=debug -c.
411 411 [diff.diffline|diff --git a/utf8 b/utf8]
412 412 [diff.file_a|--- a/utf8]
413 413 [diff.file_b|+++ b/utf8]
414 414 [diff.hunk|@@ -1,1 +1,1 @@]
415 415 [diff.deleted|-][diff.deleted.unchanged|blah ][diff.deleted.changed|\xe3\x82\xa2][diff.deleted.unchanged| blah] (esc)
416 416 [diff.inserted|+][diff.inserted.unchanged|blah ][diff.inserted.changed|\xe3\x82\xa4][diff.inserted.unchanged| blah] (esc)
@@ -1,407 +1,407 b''
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 32 HGPLAIN disables color
33 33 $ HGPLAIN=1 hg status --color=debug
34 34 ? a/1/in_a_1 (glob)
35 35 ? a/in_a (glob)
36 36 ? b/1/in_b_1 (glob)
37 37 ? b/2/in_b_2 (glob)
38 38 ? b/in_b (glob)
39 39 ? in_root
40 40 HGPLAINEXCEPT=color does not disable color
41 41 $ HGPLAINEXCEPT=color hg status --color=debug
42 42 [status.unknown|? ][status.unknown|a/1/in_a_1] (glob)
43 43 [status.unknown|? ][status.unknown|a/in_a] (glob)
44 44 [status.unknown|? ][status.unknown|b/1/in_b_1] (glob)
45 45 [status.unknown|? ][status.unknown|b/2/in_b_2] (glob)
46 46 [status.unknown|? ][status.unknown|b/in_b] (glob)
47 47 [status.unknown|? ][status.unknown|in_root]
48 48
49 49 hg status with template
50 50 $ hg status -T "{label('red', path)}\n" --color=debug
51 51 [red|a/1/in_a_1]
52 52 [red|a/in_a]
53 53 [red|b/1/in_b_1]
54 54 [red|b/2/in_b_2]
55 55 [red|b/in_b]
56 56 [red|in_root]
57 57
58 58 hg status . in repo root:
59 59
60 60 $ hg status .
61 61 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4ma/1/in_a_1\x1b[0m (esc)
62 62 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4ma/in_a\x1b[0m (esc)
63 63 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4mb/1/in_b_1\x1b[0m (esc)
64 64 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4mb/2/in_b_2\x1b[0m (esc)
65 65 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4mb/in_b\x1b[0m (esc)
66 66 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4min_root\x1b[0m (esc)
67 67
68 68 $ hg status --cwd a
69 69 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4ma/1/in_a_1\x1b[0m (esc)
70 70 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4ma/in_a\x1b[0m (esc)
71 71 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4mb/1/in_b_1\x1b[0m (esc)
72 72 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4mb/2/in_b_2\x1b[0m (esc)
73 73 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4mb/in_b\x1b[0m (esc)
74 74 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4min_root\x1b[0m (esc)
75 75 $ hg status --cwd a .
76 76 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4m1/in_a_1\x1b[0m (esc)
77 77 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4min_a\x1b[0m (esc)
78 78 $ hg status --cwd a ..
79 79 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4m1/in_a_1\x1b[0m (esc)
80 80 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4min_a\x1b[0m (esc)
81 81 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4m../b/1/in_b_1\x1b[0m (esc)
82 82 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4m../b/2/in_b_2\x1b[0m (esc)
83 83 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4m../b/in_b\x1b[0m (esc)
84 84 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4m../in_root\x1b[0m (esc)
85 85
86 86 $ hg status --cwd b
87 87 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4ma/1/in_a_1\x1b[0m (esc)
88 88 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4ma/in_a\x1b[0m (esc)
89 89 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4mb/1/in_b_1\x1b[0m (esc)
90 90 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4mb/2/in_b_2\x1b[0m (esc)
91 91 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4mb/in_b\x1b[0m (esc)
92 92 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4min_root\x1b[0m (esc)
93 93 $ hg status --cwd b .
94 94 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4m1/in_b_1\x1b[0m (esc)
95 95 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4m2/in_b_2\x1b[0m (esc)
96 96 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4min_b\x1b[0m (esc)
97 97 $ hg status --cwd b ..
98 98 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4m../a/1/in_a_1\x1b[0m (esc)
99 99 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4m../a/in_a\x1b[0m (esc)
100 100 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4m1/in_b_1\x1b[0m (esc)
101 101 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4m2/in_b_2\x1b[0m (esc)
102 102 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4min_b\x1b[0m (esc)
103 103 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4m../in_root\x1b[0m (esc)
104 104
105 105 $ hg status --cwd a/1
106 106 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4ma/1/in_a_1\x1b[0m (esc)
107 107 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4ma/in_a\x1b[0m (esc)
108 108 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4mb/1/in_b_1\x1b[0m (esc)
109 109 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4mb/2/in_b_2\x1b[0m (esc)
110 110 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4mb/in_b\x1b[0m (esc)
111 111 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4min_root\x1b[0m (esc)
112 112 $ hg status --cwd a/1 .
113 113 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4min_a_1\x1b[0m (esc)
114 114 $ hg status --cwd a/1 ..
115 115 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4min_a_1\x1b[0m (esc)
116 116 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4m../in_a\x1b[0m (esc)
117 117
118 118 $ hg status --cwd b/1
119 119 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4ma/1/in_a_1\x1b[0m (esc)
120 120 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4ma/in_a\x1b[0m (esc)
121 121 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4mb/1/in_b_1\x1b[0m (esc)
122 122 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4mb/2/in_b_2\x1b[0m (esc)
123 123 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4mb/in_b\x1b[0m (esc)
124 124 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4min_root\x1b[0m (esc)
125 125 $ hg status --cwd b/1 .
126 126 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4min_b_1\x1b[0m (esc)
127 127 $ hg status --cwd b/1 ..
128 128 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4min_b_1\x1b[0m (esc)
129 129 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4m../2/in_b_2\x1b[0m (esc)
130 130 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4m../in_b\x1b[0m (esc)
131 131
132 132 $ hg status --cwd b/2
133 133 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4ma/1/in_a_1\x1b[0m (esc)
134 134 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4ma/in_a\x1b[0m (esc)
135 135 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4mb/1/in_b_1\x1b[0m (esc)
136 136 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4mb/2/in_b_2\x1b[0m (esc)
137 137 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4mb/in_b\x1b[0m (esc)
138 138 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4min_root\x1b[0m (esc)
139 139 $ hg status --cwd b/2 .
140 140 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4min_b_2\x1b[0m (esc)
141 141 $ hg status --cwd b/2 ..
142 142 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4m../1/in_b_1\x1b[0m (esc)
143 143 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4min_b_2\x1b[0m (esc)
144 144 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4m../in_b\x1b[0m (esc)
145 145
146 146 Make sure --color=never works
147 147 $ hg status --color=never
148 148 ? a/1/in_a_1
149 149 ? a/in_a
150 150 ? b/1/in_b_1
151 151 ? b/2/in_b_2
152 152 ? b/in_b
153 153 ? in_root
154 154
155 155 Make sure ui.formatted=False works
156 156 $ hg status --color=auto --config ui.formatted=False
157 157 ? a/1/in_a_1
158 158 ? a/in_a
159 159 ? b/1/in_b_1
160 160 ? b/2/in_b_2
161 161 ? b/in_b
162 162 ? in_root
163 163
164 164 $ cd ..
165 165
166 166 $ hg init repo2
167 167 $ cd repo2
168 168 $ touch modified removed deleted ignored
169 169 $ echo "^ignored$" > .hgignore
170 170 $ hg ci -A -m 'initial checkin'
171 adding .hgignore
172 adding deleted
173 adding modified
174 adding removed
171 \x1b[0;32madding .hgignore\x1b[0m (esc)
172 \x1b[0;32madding deleted\x1b[0m (esc)
173 \x1b[0;32madding modified\x1b[0m (esc)
174 \x1b[0;32madding removed\x1b[0m (esc)
175 175 $ hg log --color=debug
176 176 [log.changeset changeset.draft|changeset: 0:389aef86a55e]
177 177 [log.tag|tag: tip]
178 178 [log.user|user: test]
179 179 [log.date|date: Thu Jan 01 00:00:00 1970 +0000]
180 180 [log.summary|summary: initial checkin]
181 181
182 182 $ hg log -Tcompact --color=debug
183 183 [log.changeset changeset.draft|0][tip] [log.node|389aef86a55e] [log.date|1970-01-01 00:00 +0000] [log.user|test]
184 184 [ui.note log.description|initial checkin]
185 185
186 186 Labels on empty strings should not be displayed, labels on custom
187 187 templates should be.
188 188
189 189 $ hg log --color=debug -T '{label("my.label",author)}\n{label("skipped.label","")}'
190 190 [my.label|test]
191 191 $ touch modified added unknown ignored
192 192 $ hg add added
193 193 $ hg remove removed
194 194 $ rm deleted
195 195
196 196 hg status:
197 197
198 198 $ hg status
199 199 \x1b[0;32;1mA \x1b[0m\x1b[0;32;1madded\x1b[0m (esc)
200 200 \x1b[0;31;1mR \x1b[0m\x1b[0;31;1mremoved\x1b[0m (esc)
201 201 \x1b[0;36;1;4m! \x1b[0m\x1b[0;36;1;4mdeleted\x1b[0m (esc)
202 202 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4munknown\x1b[0m (esc)
203 203
204 204 hg status modified added removed deleted unknown never-existed ignored:
205 205
206 206 $ hg status modified added removed deleted unknown never-existed ignored
207 207 never-existed: * (glob)
208 208 \x1b[0;32;1mA \x1b[0m\x1b[0;32;1madded\x1b[0m (esc)
209 209 \x1b[0;31;1mR \x1b[0m\x1b[0;31;1mremoved\x1b[0m (esc)
210 210 \x1b[0;36;1;4m! \x1b[0m\x1b[0;36;1;4mdeleted\x1b[0m (esc)
211 211 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4munknown\x1b[0m (esc)
212 212
213 213 $ hg copy modified copied
214 214
215 215 hg status -C:
216 216
217 217 $ hg status -C
218 218 \x1b[0;32;1mA \x1b[0m\x1b[0;32;1madded\x1b[0m (esc)
219 219 \x1b[0;32;1mA \x1b[0m\x1b[0;32;1mcopied\x1b[0m (esc)
220 220 \x1b[0;0m modified\x1b[0m (esc)
221 221 \x1b[0;31;1mR \x1b[0m\x1b[0;31;1mremoved\x1b[0m (esc)
222 222 \x1b[0;36;1;4m! \x1b[0m\x1b[0;36;1;4mdeleted\x1b[0m (esc)
223 223 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4munknown\x1b[0m (esc)
224 224
225 225 hg status -A:
226 226
227 227 $ hg status -A
228 228 \x1b[0;32;1mA \x1b[0m\x1b[0;32;1madded\x1b[0m (esc)
229 229 \x1b[0;32;1mA \x1b[0m\x1b[0;32;1mcopied\x1b[0m (esc)
230 230 \x1b[0;0m modified\x1b[0m (esc)
231 231 \x1b[0;31;1mR \x1b[0m\x1b[0;31;1mremoved\x1b[0m (esc)
232 232 \x1b[0;36;1;4m! \x1b[0m\x1b[0;36;1;4mdeleted\x1b[0m (esc)
233 233 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4munknown\x1b[0m (esc)
234 234 \x1b[0;30;1mI \x1b[0m\x1b[0;30;1mignored\x1b[0m (esc)
235 235 \x1b[0;0mC \x1b[0m\x1b[0;0m.hgignore\x1b[0m (esc)
236 236 \x1b[0;0mC \x1b[0m\x1b[0;0mmodified\x1b[0m (esc)
237 237
238 238
239 239 hg status -A (with terminfo color):
240 240
241 241 #if tic
242 242
243 243 $ mkdir "$TESTTMP/terminfo"
244 244 $ TERMINFO="$TESTTMP/terminfo" tic "$TESTDIR/hgterm.ti"
245 245 $ TERM=hgterm TERMINFO="$TESTTMP/terminfo" hg status --config color.mode=terminfo -A
246 246 \x1b[30m\x1b[32m\x1b[1mA \x1b[30m\x1b[30m\x1b[32m\x1b[1madded\x1b[30m (esc)
247 247 \x1b[30m\x1b[32m\x1b[1mA \x1b[30m\x1b[30m\x1b[32m\x1b[1mcopied\x1b[30m (esc)
248 248 \x1b[30m\x1b[30m modified\x1b[30m (esc)
249 249 \x1b[30m\x1b[31m\x1b[1mR \x1b[30m\x1b[30m\x1b[31m\x1b[1mremoved\x1b[30m (esc)
250 250 \x1b[30m\x1b[36m\x1b[1m\x1b[4m! \x1b[30m\x1b[30m\x1b[36m\x1b[1m\x1b[4mdeleted\x1b[30m (esc)
251 251 \x1b[30m\x1b[35m\x1b[1m\x1b[4m? \x1b[30m\x1b[30m\x1b[35m\x1b[1m\x1b[4munknown\x1b[30m (esc)
252 252 \x1b[30m\x1b[30m\x1b[1mI \x1b[30m\x1b[30m\x1b[30m\x1b[1mignored\x1b[30m (esc)
253 253 \x1b[30m\x1b[30mC \x1b[30m\x1b[30m\x1b[30m.hgignore\x1b[30m (esc)
254 254 \x1b[30m\x1b[30mC \x1b[30m\x1b[30m\x1b[30mmodified\x1b[30m (esc)
255 255
256 256 The user can define effects with raw terminfo codes:
257 257
258 258 $ cat <<EOF >> $HGRCPATH
259 259 > # Completely bogus code for dim
260 260 > terminfo.dim = \E[88m
261 261 > # We can override what's in the terminfo database, too
262 262 > terminfo.bold = \E[2m
263 263 > EOF
264 264 $ TERM=hgterm TERMINFO="$TESTTMP/terminfo" hg status --config color.mode=terminfo --config color.status.clean=dim -A
265 265 \x1b[30m\x1b[32m\x1b[2mA \x1b[30m\x1b[30m\x1b[32m\x1b[2madded\x1b[30m (esc)
266 266 \x1b[30m\x1b[32m\x1b[2mA \x1b[30m\x1b[30m\x1b[32m\x1b[2mcopied\x1b[30m (esc)
267 267 \x1b[30m\x1b[30m modified\x1b[30m (esc)
268 268 \x1b[30m\x1b[31m\x1b[2mR \x1b[30m\x1b[30m\x1b[31m\x1b[2mremoved\x1b[30m (esc)
269 269 \x1b[30m\x1b[36m\x1b[2m\x1b[4m! \x1b[30m\x1b[30m\x1b[36m\x1b[2m\x1b[4mdeleted\x1b[30m (esc)
270 270 \x1b[30m\x1b[35m\x1b[2m\x1b[4m? \x1b[30m\x1b[30m\x1b[35m\x1b[2m\x1b[4munknown\x1b[30m (esc)
271 271 \x1b[30m\x1b[30m\x1b[2mI \x1b[30m\x1b[30m\x1b[30m\x1b[2mignored\x1b[30m (esc)
272 272 \x1b[30m\x1b[88mC \x1b[30m\x1b[30m\x1b[88m.hgignore\x1b[30m (esc)
273 273 \x1b[30m\x1b[88mC \x1b[30m\x1b[30m\x1b[88mmodified\x1b[30m (esc)
274 274
275 275 #endif
276 276
277 277
278 278 $ echo "^ignoreddir$" > .hgignore
279 279 $ mkdir ignoreddir
280 280 $ touch ignoreddir/file
281 281
282 282 hg status ignoreddir/file:
283 283
284 284 $ hg status ignoreddir/file
285 285
286 286 hg status -i ignoreddir/file:
287 287
288 288 $ hg status -i ignoreddir/file
289 289 \x1b[0;30;1mI \x1b[0m\x1b[0;30;1mignoreddir/file\x1b[0m (esc)
290 290 $ cd ..
291 291
292 292 check 'status -q' and some combinations
293 293
294 294 $ hg init repo3
295 295 $ cd repo3
296 296 $ touch modified removed deleted ignored
297 297 $ echo "^ignored$" > .hgignore
298 298 $ hg commit -A -m 'initial checkin'
299 adding .hgignore
300 adding deleted
301 adding modified
302 adding removed
299 \x1b[0;32madding .hgignore\x1b[0m (esc)
300 \x1b[0;32madding deleted\x1b[0m (esc)
301 \x1b[0;32madding modified\x1b[0m (esc)
302 \x1b[0;32madding removed\x1b[0m (esc)
303 303 $ touch added unknown ignored
304 304 $ hg add added
305 305 $ echo "test" >> modified
306 306 $ hg remove removed
307 307 $ rm deleted
308 308 $ hg copy modified copied
309 309
310 310 test unknown color
311 311
312 312 $ hg --config color.status.modified=periwinkle status
313 313 ignoring unknown color/effect 'periwinkle' (configured in color.status.modified)
314 314 ignoring unknown color/effect 'periwinkle' (configured in color.status.modified)
315 315 ignoring unknown color/effect 'periwinkle' (configured in color.status.modified)
316 316 M modified
317 317 \x1b[0;32;1mA \x1b[0m\x1b[0;32;1madded\x1b[0m (esc)
318 318 \x1b[0;32;1mA \x1b[0m\x1b[0;32;1mcopied\x1b[0m (esc)
319 319 \x1b[0;31;1mR \x1b[0m\x1b[0;31;1mremoved\x1b[0m (esc)
320 320 \x1b[0;36;1;4m! \x1b[0m\x1b[0;36;1;4mdeleted\x1b[0m (esc)
321 321 \x1b[0;35;1;4m? \x1b[0m\x1b[0;35;1;4munknown\x1b[0m (esc)
322 322
323 323 Run status with 2 different flags.
324 324 Check if result is the same or different.
325 325 If result is not as expected, raise error
326 326
327 327 $ assert() {
328 328 > hg status $1 > ../a
329 329 > hg status $2 > ../b
330 330 > if diff ../a ../b > /dev/null; then
331 331 > out=0
332 332 > else
333 333 > out=1
334 334 > fi
335 335 > if [ $3 -eq 0 ]; then
336 336 > df="same"
337 337 > else
338 338 > df="different"
339 339 > fi
340 340 > if [ $out -ne $3 ]; then
341 341 > echo "Error on $1 and $2, should be $df."
342 342 > fi
343 343 > }
344 344
345 345 assert flag1 flag2 [0-same | 1-different]
346 346
347 347 $ assert "-q" "-mard" 0
348 348 $ assert "-A" "-marduicC" 0
349 349 $ assert "-qA" "-mardcC" 0
350 350 $ assert "-qAui" "-A" 0
351 351 $ assert "-qAu" "-marducC" 0
352 352 $ assert "-qAi" "-mardicC" 0
353 353 $ assert "-qu" "-u" 0
354 354 $ assert "-q" "-u" 1
355 355 $ assert "-m" "-a" 1
356 356 $ assert "-r" "-d" 1
357 357 $ cd ..
358 358
359 359 test 'resolve -l'
360 360
361 361 $ hg init repo4
362 362 $ cd repo4
363 363 $ echo "file a" > a
364 364 $ echo "file b" > b
365 365 $ hg add a b
366 366 $ hg commit -m "initial"
367 367 $ echo "file a change 1" > a
368 368 $ echo "file b change 1" > b
369 369 $ hg commit -m "head 1"
370 370 $ hg update 0
371 371 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
372 372 $ echo "file a change 2" > a
373 373 $ echo "file b change 2" > b
374 374 $ hg commit -m "head 2"
375 375 created new head
376 376 $ hg merge
377 377 merging a
378 378 merging b
379 379 warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
380 380 warning: conflicts while merging b! (edit, then use 'hg resolve --mark')
381 381 0 files updated, 0 files merged, 0 files removed, 2 files unresolved
382 382 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
383 383 [1]
384 384 $ hg resolve -m b
385 385
386 386 hg resolve with one unresolved, one resolved:
387 387
388 388 $ hg resolve -l
389 389 \x1b[0;31;1mU \x1b[0m\x1b[0;31;1ma\x1b[0m (esc)
390 390 \x1b[0;32;1mR \x1b[0m\x1b[0;32;1mb\x1b[0m (esc)
391 391
392 392 color coding of error message with current availability of curses
393 393
394 394 $ hg unknowncommand > /dev/null
395 395 hg: unknown command 'unknowncommand'
396 396 (use 'hg help' for a list of commands)
397 397 [255]
398 398
399 399 color coding of error message without curses
400 400
401 401 $ echo 'raise ImportError' > curses.py
402 402 $ PYTHONPATH=`pwd`:$PYTHONPATH hg unknowncommand > /dev/null
403 403 hg: unknown command 'unknowncommand'
404 404 (use 'hg help' for a list of commands)
405 405 [255]
406 406
407 407 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now