##// END OF EJS Templates
color: add support for terminfo-based attributes and color...
Danek Duvall -
r13987:e0f07847 default
parent child Browse files
Show More
@@ -1,363 +1,480 b''
1 1 # color.py color output for the status and qseries commands
2 2 #
3 3 # Copyright (C) 2007 Kevin Christen <kevin.christen@gmail.com>
4 4 #
5 5 # This program is free software; you can redistribute it and/or modify it
6 6 # under the terms of the GNU General Public License as published by the
7 7 # Free Software Foundation; either version 2 of the License, or (at your
8 8 # option) any later version.
9 9 #
10 10 # This program is distributed in the hope that it will be useful, but
11 11 # WITHOUT ANY WARRANTY; without even the implied warranty of
12 12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
13 13 # Public License for more details.
14 14 #
15 15 # You should have received a copy of the GNU General Public License along
16 16 # with this program; if not, write to the Free Software Foundation, Inc.,
17 17 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 18
19 19 '''colorize output from some commands
20 20
21 21 This extension modifies the status and resolve commands to add color
22 22 to their output to reflect file status, the qseries command to add
23 23 color to reflect patch status (applied, unapplied, missing), and to
24 24 diff-related commands to highlight additions, removals, diff headers,
25 25 and trailing whitespace.
26 26
27 27 Other effects in addition to color, like bold and underlined text, are
28 also available. Effects are rendered with the ECMA-48 SGR control
28 also available. By default, the terminfo database is used to find the
29 terminal codes used to change color and effect. If terminfo is not
30 available, then effects are rendered with the ECMA-48 SGR control
29 31 function (aka ANSI escape codes).
30 32
31 33 Default effects may be overridden from your configuration file::
32 34
33 35 [color]
34 36 status.modified = blue bold underline red_background
35 37 status.added = green bold
36 38 status.removed = red bold blue_background
37 39 status.deleted = cyan bold underline
38 40 status.unknown = magenta bold underline
39 41 status.ignored = black bold
40 42
41 43 # 'none' turns off all effects
42 44 status.clean = none
43 45 status.copied = none
44 46
45 47 qseries.applied = blue bold underline
46 48 qseries.unapplied = black bold
47 49 qseries.missing = red bold
48 50
49 51 diff.diffline = bold
50 52 diff.extended = cyan bold
51 53 diff.file_a = red bold
52 54 diff.file_b = green bold
53 55 diff.hunk = magenta
54 56 diff.deleted = red
55 57 diff.inserted = green
56 58 diff.changed = white
57 59 diff.trailingwhitespace = bold red_background
58 60
59 61 resolve.unresolved = red bold
60 62 resolve.resolved = green bold
61 63
62 64 bookmarks.current = green
63 65
64 66 branches.active = none
65 67 branches.closed = black bold
66 68 branches.current = green
67 69 branches.inactive = none
68 70
69 The color extension will try to detect whether to use ANSI codes or
70 Win32 console APIs, unless it is made explicit::
71 The available effects in terminfo mode are 'blink', 'bold', 'dim',
72 'inverse', 'invisible', 'italic', 'standout', and 'underline'; in
73 ECMA-48 mode, the options are 'bold', 'inverse', 'italic', and
74 'underline'. How each is rendered depends on the terminal emulator.
75 Some may not be available for a given terminal type, and will be
76 silently ignored.
77
78 Because there are only eight standard colors, this module allows you
79 to define color names for other color slots which might be available
80 for your terminal type, assuming terminfo mode. For instance::
81
82 color.brightblue = 12
83 color.pink = 207
84 color.orange = 202
85
86 to set 'brightblue' to color slot 12 (useful for 16 color terminals
87 that have brighter colors defined in the upper eight) and, 'pink' and
88 'orange' to colors in 256-color xterm's default color cube. These
89 defined colors may then be used as any of the pre-defined eight,
90 including appending '_background' to set the background to that color.
91
92 The color extension will try to detect whether to use terminfo, ANSI
93 codes or Win32 console APIs, unless it is made explicit; e.g.::
71 94
72 95 [color]
73 96 mode = ansi
74 97
75 Any value other than 'ansi', 'win32', or 'auto' will disable color.
98 Any value other than 'ansi', 'win32', 'terminfo', or 'auto' will
99 disable color.
76 100
77 101 '''
78 102
79 103 import os
80 104
81 105 from mercurial import commands, dispatch, extensions, ui as uimod, util
82 106 from mercurial.i18n import _
83 107
84 108 # start and stop parameters for effects
85 109 _effects = {'none': 0, 'black': 30, 'red': 31, 'green': 32, 'yellow': 33,
86 110 'blue': 34, 'magenta': 35, 'cyan': 36, 'white': 37, 'bold': 1,
87 111 'italic': 3, 'underline': 4, 'inverse': 7,
88 112 'black_background': 40, 'red_background': 41,
89 113 'green_background': 42, 'yellow_background': 43,
90 114 'blue_background': 44, 'purple_background': 45,
91 115 'cyan_background': 46, 'white_background': 47}
92 116
117 def _terminfosetup(ui):
118 '''Initialize terminfo data and the terminal if we're in terminfo mode.'''
119
120 global _terminfo_params
121 # If we failed to load curses, we go ahead and return.
122 if not _terminfo_params:
123 return
124 # Otherwise, see what the config file says.
125 mode = ui.config('color', 'mode', 'auto')
126 if mode not in ('auto', 'terminfo'):
127 return
128
129 _terminfo_params.update(dict((
130 (key[6:], (False, int(val)))
131 for key, val in ui.configitems('color')
132 if key.startswith('color.')
133 )))
134
135 try:
136 curses.setupterm()
137 except curses.error, e:
138 _terminfo_params = {}
139 return
140
141 for key, (b, e) in _terminfo_params.items():
142 if not b:
143 continue
144 if not curses.tigetstr(e):
145 # Most terminals don't support dim, invis, etc, so don't be
146 # noisy and use ui.debug().
147 ui.debug("no terminfo entry for %s\n" % e)
148 del _terminfo_params[key]
149 if not curses.tigetstr('setaf') or not curses.tigetstr('setab'):
150 ui.warn(_("no terminfo entry for setab/setaf: reverting to "
151 "ECMA-48 color\n"))
152 _terminfo_params = {}
153
154 try:
155 import curses
156 # Mapping from effect name to terminfo attribute name or color number.
157 # This will also force-load the curses module.
158 _terminfo_params = {'none': (True, 'sgr0'),
159 'standout': (True, 'smso'),
160 'underline': (True, 'smul'),
161 'reverse': (True, 'rev'),
162 'inverse': (True, 'rev'),
163 'blink': (True, 'blink'),
164 'dim': (True, 'dim'),
165 'bold': (True, 'bold'),
166 'invisible': (True, 'invis'),
167 'italic': (True, 'sitm'),
168 'black': (False, curses.COLOR_BLACK),
169 'red': (False, curses.COLOR_RED),
170 'green': (False, curses.COLOR_GREEN),
171 'yellow': (False, curses.COLOR_YELLOW),
172 'blue': (False, curses.COLOR_BLUE),
173 'magenta': (False, curses.COLOR_MAGENTA),
174 'cyan': (False, curses.COLOR_CYAN),
175 'white': (False, curses.COLOR_WHITE)}
176 except ImportError:
177 _terminfo_params = False
178
93 179 _styles = {'grep.match': 'red bold',
94 180 'bookmarks.current': 'green',
95 181 'branches.active': 'none',
96 182 'branches.closed': 'black bold',
97 183 'branches.current': 'green',
98 184 'branches.inactive': 'none',
99 185 'diff.changed': 'white',
100 186 'diff.deleted': 'red',
101 187 'diff.diffline': 'bold',
102 188 'diff.extended': 'cyan bold',
103 189 'diff.file_a': 'red bold',
104 190 'diff.file_b': 'green bold',
105 191 'diff.hunk': 'magenta',
106 192 'diff.inserted': 'green',
107 193 'diff.trailingwhitespace': 'bold red_background',
108 194 'diffstat.deleted': 'red',
109 195 'diffstat.inserted': 'green',
110 196 'ui.prompt': 'yellow',
111 197 'log.changeset': 'yellow',
112 198 'resolve.resolved': 'green bold',
113 199 'resolve.unresolved': 'red bold',
114 200 'status.added': 'green bold',
115 201 'status.clean': 'none',
116 202 'status.copied': 'none',
117 203 'status.deleted': 'cyan bold underline',
118 204 'status.ignored': 'black bold',
119 205 'status.modified': 'blue bold',
120 206 'status.removed': 'red bold',
121 207 'status.unknown': 'magenta bold underline'}
122 208
123 209
210 def _effect_str(effect):
211 '''Helper function for render_effects().'''
212
213 bg = False
214 if effect.endswith('_background'):
215 bg = True
216 effect = effect[:-11]
217 attr, val = _terminfo_params[effect]
218 if attr:
219 return curses.tigetstr(val)
220 elif bg:
221 return curses.tparm(curses.tigetstr('setab'), val)
222 else:
223 return curses.tparm(curses.tigetstr('setaf'), val)
224
124 225 def render_effects(text, effects):
125 226 'Wrap text in commands to turn on each effect.'
126 227 if not text:
127 228 return text
128 start = [str(_effects[e]) for e in ['none'] + effects.split()]
129 start = '\033[' + ';'.join(start) + 'm'
130 stop = '\033[' + str(_effects['none']) + 'm'
229 if not _terminfo_params:
230 start = [str(_effects[e]) for e in ['none'] + effects.split()]
231 start = '\033[' + ';'.join(start) + 'm'
232 stop = '\033[' + str(_effects['none']) + 'm'
233 else:
234 start = ''.join(_effect_str(effect)
235 for effect in ['none'] + effects.split())
236 stop = _effect_str('none')
131 237 return ''.join([start, text, stop])
132 238
133 239 def extstyles():
134 240 for name, ext in extensions.extensions():
135 241 _styles.update(getattr(ext, 'colortable', {}))
136 242
137 243 def configstyles(ui):
138 244 for status, cfgeffects in ui.configitems('color'):
139 if '.' not in status:
245 if '.' not in status or status.startswith('color.'):
140 246 continue
141 247 cfgeffects = ui.configlist('color', status)
142 248 if cfgeffects:
143 249 good = []
144 250 for e in cfgeffects:
145 if e in _effects:
251 if not _terminfo_params and e in _effects:
252 good.append(e)
253 elif e in _terminfo_params or e[:-11] in _terminfo_params:
146 254 good.append(e)
147 255 else:
148 256 ui.warn(_("ignoring unknown color/effect %r "
149 257 "(configured in color.%s)\n")
150 258 % (e, status))
151 259 _styles[status] = ' '.join(good)
152 260
153 261 class colorui(uimod.ui):
154 262 def popbuffer(self, labeled=False):
155 263 if labeled:
156 264 return ''.join(self.label(a, label) for a, label
157 265 in self._buffers.pop())
158 266 return ''.join(a for a, label in self._buffers.pop())
159 267
160 268 _colormode = 'ansi'
161 269 def write(self, *args, **opts):
162 270 label = opts.get('label', '')
163 271 if self._buffers:
164 272 self._buffers[-1].extend([(str(a), label) for a in args])
165 273 elif self._colormode == 'win32':
166 274 for a in args:
167 275 win32print(a, super(colorui, self).write, **opts)
168 276 else:
169 277 return super(colorui, self).write(
170 278 *[self.label(str(a), label) for a in args], **opts)
171 279
172 280 def write_err(self, *args, **opts):
173 281 label = opts.get('label', '')
174 282 if self._colormode == 'win32':
175 283 for a in args:
176 284 win32print(a, super(colorui, self).write_err, **opts)
177 285 else:
178 286 return super(colorui, self).write_err(
179 287 *[self.label(str(a), label) for a in args], **opts)
180 288
181 289 def label(self, msg, label):
182 290 effects = []
183 291 for l in label.split():
184 292 s = _styles.get(l, '')
185 293 if s:
186 294 effects.append(s)
187 295 effects = ''.join(effects)
188 296 if effects:
189 297 return '\n'.join([render_effects(s, effects)
190 298 for s in msg.split('\n')])
191 299 return msg
192 300
193 301
194 302 def uisetup(ui):
303 global _terminfo_params
195 304 if ui.plain():
196 305 return
197 306 mode = ui.config('color', 'mode', 'auto')
198 307 if mode == 'auto':
199 308 if os.name == 'nt' and 'TERM' not in os.environ:
200 309 # looks line a cmd.exe console, use win32 API or nothing
201 310 mode = w32effects and 'win32' or 'none'
202 311 else:
203 mode = 'ansi'
312 _terminfosetup(ui)
313 if not _terminfo_params:
314 mode = 'ansi'
315 else:
316 mode = 'terminfo'
204 317 if mode == 'win32':
205 318 if w32effects is None:
206 319 # only warn if color.mode is explicitly set to win32
207 320 ui.warn(_('warning: failed to set color mode to %s\n') % mode)
208 321 return
209 322 _effects.update(w32effects)
210 elif mode != 'ansi':
323 elif mode == 'ansi':
324 _terminfo_params = {}
325 elif mode == 'terminfo':
326 _terminfosetup(ui)
327 elif mode not in ('ansi', 'terminfo'):
211 328 return
212 329 def colorcmd(orig, ui_, opts, cmd, cmdfunc):
213 330 coloropt = opts['color']
214 331 auto = coloropt == 'auto'
215 332 always = util.parsebool(coloropt)
216 333 if (always or
217 334 (always is None and
218 335 (auto and (os.environ.get('TERM') != 'dumb' and ui_.formatted())))):
219 336 colorui._colormode = mode
220 337 colorui.__bases__ = (ui_.__class__,)
221 338 ui_.__class__ = colorui
222 339 extstyles()
223 340 configstyles(ui_)
224 341 return orig(ui_, opts, cmd, cmdfunc)
225 342 extensions.wrapfunction(dispatch, '_runcommand', colorcmd)
226 343
227 344 def extsetup(ui):
228 345 commands.globalopts.append(
229 346 ('', 'color', 'auto',
230 347 # i18n: 'always', 'auto', and 'never' are keywords and should
231 348 # not be translated
232 349 _("when to colorize (boolean, always, auto, or never)"),
233 350 _('TYPE')))
234 351
235 352 if os.name != 'nt':
236 353 w32effects = None
237 354 else:
238 355 import re, ctypes
239 356
240 357 _kernel32 = ctypes.windll.kernel32
241 358
242 359 _WORD = ctypes.c_ushort
243 360
244 361 _INVALID_HANDLE_VALUE = -1
245 362
246 363 class _COORD(ctypes.Structure):
247 364 _fields_ = [('X', ctypes.c_short),
248 365 ('Y', ctypes.c_short)]
249 366
250 367 class _SMALL_RECT(ctypes.Structure):
251 368 _fields_ = [('Left', ctypes.c_short),
252 369 ('Top', ctypes.c_short),
253 370 ('Right', ctypes.c_short),
254 371 ('Bottom', ctypes.c_short)]
255 372
256 373 class _CONSOLE_SCREEN_BUFFER_INFO(ctypes.Structure):
257 374 _fields_ = [('dwSize', _COORD),
258 375 ('dwCursorPosition', _COORD),
259 376 ('wAttributes', _WORD),
260 377 ('srWindow', _SMALL_RECT),
261 378 ('dwMaximumWindowSize', _COORD)]
262 379
263 380 _STD_OUTPUT_HANDLE = 0xfffffff5L # (DWORD)-11
264 381 _STD_ERROR_HANDLE = 0xfffffff4L # (DWORD)-12
265 382
266 383 _FOREGROUND_BLUE = 0x0001
267 384 _FOREGROUND_GREEN = 0x0002
268 385 _FOREGROUND_RED = 0x0004
269 386 _FOREGROUND_INTENSITY = 0x0008
270 387
271 388 _BACKGROUND_BLUE = 0x0010
272 389 _BACKGROUND_GREEN = 0x0020
273 390 _BACKGROUND_RED = 0x0040
274 391 _BACKGROUND_INTENSITY = 0x0080
275 392
276 393 _COMMON_LVB_REVERSE_VIDEO = 0x4000
277 394 _COMMON_LVB_UNDERSCORE = 0x8000
278 395
279 396 # http://msdn.microsoft.com/en-us/library/ms682088%28VS.85%29.aspx
280 397 w32effects = {
281 398 'none': -1,
282 399 'black': 0,
283 400 'red': _FOREGROUND_RED,
284 401 'green': _FOREGROUND_GREEN,
285 402 'yellow': _FOREGROUND_RED | _FOREGROUND_GREEN,
286 403 'blue': _FOREGROUND_BLUE,
287 404 'magenta': _FOREGROUND_BLUE | _FOREGROUND_RED,
288 405 'cyan': _FOREGROUND_BLUE | _FOREGROUND_GREEN,
289 406 'white': _FOREGROUND_RED | _FOREGROUND_GREEN | _FOREGROUND_BLUE,
290 407 'bold': _FOREGROUND_INTENSITY,
291 408 'black_background': 0x100, # unused value > 0x0f
292 409 'red_background': _BACKGROUND_RED,
293 410 'green_background': _BACKGROUND_GREEN,
294 411 'yellow_background': _BACKGROUND_RED | _BACKGROUND_GREEN,
295 412 'blue_background': _BACKGROUND_BLUE,
296 413 'purple_background': _BACKGROUND_BLUE | _BACKGROUND_RED,
297 414 'cyan_background': _BACKGROUND_BLUE | _BACKGROUND_GREEN,
298 415 'white_background': (_BACKGROUND_RED | _BACKGROUND_GREEN |
299 416 _BACKGROUND_BLUE),
300 417 'bold_background': _BACKGROUND_INTENSITY,
301 418 'underline': _COMMON_LVB_UNDERSCORE, # double-byte charsets only
302 419 'inverse': _COMMON_LVB_REVERSE_VIDEO, # double-byte charsets only
303 420 }
304 421
305 422 passthrough = set([_FOREGROUND_INTENSITY,
306 423 _BACKGROUND_INTENSITY,
307 424 _COMMON_LVB_UNDERSCORE,
308 425 _COMMON_LVB_REVERSE_VIDEO])
309 426
310 427 stdout = _kernel32.GetStdHandle(
311 428 _STD_OUTPUT_HANDLE) # don't close the handle returned
312 429 if stdout is None or stdout == _INVALID_HANDLE_VALUE:
313 430 w32effects = None
314 431 else:
315 432 csbi = _CONSOLE_SCREEN_BUFFER_INFO()
316 433 if not _kernel32.GetConsoleScreenBufferInfo(
317 434 stdout, ctypes.byref(csbi)):
318 435 # stdout may not support GetConsoleScreenBufferInfo()
319 436 # when called from subprocess or redirected
320 437 w32effects = None
321 438 else:
322 439 origattr = csbi.wAttributes
323 440 ansire = re.compile('\033\[([^m]*)m([^\033]*)(.*)',
324 441 re.MULTILINE | re.DOTALL)
325 442
326 443 def win32print(text, orig, **opts):
327 444 label = opts.get('label', '')
328 445 attr = origattr
329 446
330 447 def mapcolor(val, attr):
331 448 if val == -1:
332 449 return origattr
333 450 elif val in passthrough:
334 451 return attr | val
335 452 elif val > 0x0f:
336 453 return (val & 0x70) | (attr & 0x8f)
337 454 else:
338 455 return (val & 0x07) | (attr & 0xf8)
339 456
340 457 # determine console attributes based on labels
341 458 for l in label.split():
342 459 style = _styles.get(l, '')
343 460 for effect in style.split():
344 461 attr = mapcolor(w32effects[effect], attr)
345 462
346 463 # hack to ensure regexp finds data
347 464 if not text.startswith('\033['):
348 465 text = '\033[m' + text
349 466
350 467 # Look for ANSI-like codes embedded in text
351 468 m = re.match(ansire, text)
352 469
353 470 try:
354 471 while m:
355 472 for sattr in m.group(1).split(';'):
356 473 if sattr:
357 474 attr = mapcolor(int(sattr), attr)
358 475 _kernel32.SetConsoleTextAttribute(stdout, attr)
359 476 orig(m.group(2), **opts)
360 477 m = re.match(ansire, m.group(3))
361 478 finally:
362 479 # Explicity reset original attributes
363 480 _kernel32.SetConsoleTextAttribute(stdout, origattr)
@@ -1,398 +1,400 b''
1 1 $ hg init a
2 2 $ cd a
3 3 $ echo 'root' >root
4 4 $ hg add root
5 5 $ hg commit -d '0 0' -m "Adding root node"
6 6
7 7 $ echo 'a' >a
8 8 $ hg add a
9 9 $ hg branch a
10 10 marked working directory as branch a
11 11 $ hg commit -d '1 0' -m "Adding a branch"
12 12
13 13 $ hg branch q
14 14 marked working directory as branch q
15 15 $ echo 'aa' >a
16 16 $ hg branch -C
17 17 reset working directory to branch a
18 18 $ hg commit -d '2 0' -m "Adding to a branch"
19 19
20 20 $ hg update -C 0
21 21 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
22 22 $ echo 'b' >b
23 23 $ hg add b
24 24 $ hg branch b
25 25 marked working directory as branch b
26 26 $ hg commit -d '2 0' -m "Adding b branch"
27 27
28 28 $ echo 'bh1' >bh1
29 29 $ hg add bh1
30 30 $ hg commit -d '3 0' -m "Adding b branch head 1"
31 31
32 32 $ hg update -C 2
33 33 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
34 34 $ echo 'bh2' >bh2
35 35 $ hg add bh2
36 36 $ hg commit -d '4 0' -m "Adding b branch head 2"
37 37
38 38 $ echo 'c' >c
39 39 $ hg add c
40 40 $ hg branch c
41 41 marked working directory as branch c
42 42 $ hg commit -d '5 0' -m "Adding c branch"
43 43
44 44 $ hg branch tip
45 45 abort: the name 'tip' is reserved
46 46 [255]
47 47 $ hg branch null
48 48 abort: the name 'null' is reserved
49 49 [255]
50 50 $ hg branch .
51 51 abort: the name '.' is reserved
52 52 [255]
53 53
54 54 $ echo 'd' >d
55 55 $ hg add d
56 56 $ hg branch 'a branch name much longer than the default justification used by branches'
57 57 marked working directory as branch a branch name much longer than the default justification used by branches
58 58 $ hg commit -d '6 0' -m "Adding d branch"
59 59
60 60 $ hg branches
61 61 a branch name much longer than the default justification used by branches 7:10ff5895aa57
62 62 b 4:aee39cd168d0
63 63 c 6:589736a22561 (inactive)
64 64 a 5:d8cbc61dbaa6 (inactive)
65 65 default 0:19709c5a4e75 (inactive)
66 66
67 67 -------
68 68
69 69 $ hg branches -a
70 70 a branch name much longer than the default justification used by branches 7:10ff5895aa57
71 71 b 4:aee39cd168d0
72 72
73 73 --- Branch a
74 74
75 75 $ hg log -b a
76 76 changeset: 5:d8cbc61dbaa6
77 77 branch: a
78 78 parent: 2:881fe2b92ad0
79 79 user: test
80 80 date: Thu Jan 01 00:00:04 1970 +0000
81 81 summary: Adding b branch head 2
82 82
83 83 changeset: 2:881fe2b92ad0
84 84 branch: a
85 85 user: test
86 86 date: Thu Jan 01 00:00:02 1970 +0000
87 87 summary: Adding to a branch
88 88
89 89 changeset: 1:dd6b440dd85a
90 90 branch: a
91 91 user: test
92 92 date: Thu Jan 01 00:00:01 1970 +0000
93 93 summary: Adding a branch
94 94
95 95
96 96 ---- Branch b
97 97
98 98 $ hg log -b b
99 99 changeset: 4:aee39cd168d0
100 100 branch: b
101 101 user: test
102 102 date: Thu Jan 01 00:00:03 1970 +0000
103 103 summary: Adding b branch head 1
104 104
105 105 changeset: 3:ac22033332d1
106 106 branch: b
107 107 parent: 0:19709c5a4e75
108 108 user: test
109 109 date: Thu Jan 01 00:00:02 1970 +0000
110 110 summary: Adding b branch
111 111
112 112
113 113 ---- going to test branch closing
114 114
115 115 $ hg branches
116 116 a branch name much longer than the default justification used by branches 7:10ff5895aa57
117 117 b 4:aee39cd168d0
118 118 c 6:589736a22561 (inactive)
119 119 a 5:d8cbc61dbaa6 (inactive)
120 120 default 0:19709c5a4e75 (inactive)
121 121 $ hg up -C b
122 122 2 files updated, 0 files merged, 4 files removed, 0 files unresolved
123 123 $ echo 'xxx1' >> b
124 124 $ hg commit -d '7 0' -m 'adding cset to branch b'
125 125 $ hg up -C aee39cd168d0
126 126 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
127 127 $ echo 'xxx2' >> b
128 128 $ hg commit -d '8 0' -m 'adding head to branch b'
129 129 created new head
130 130 $ echo 'xxx3' >> b
131 131 $ hg commit -d '9 0' -m 'adding another cset to branch b'
132 132 $ hg branches
133 133 b 10:bfbe841b666e
134 134 a branch name much longer than the default justification used by branches 7:10ff5895aa57
135 135 c 6:589736a22561 (inactive)
136 136 a 5:d8cbc61dbaa6 (inactive)
137 137 default 0:19709c5a4e75 (inactive)
138 138 $ hg heads --closed
139 139 changeset: 10:bfbe841b666e
140 140 branch: b
141 141 tag: tip
142 142 user: test
143 143 date: Thu Jan 01 00:00:09 1970 +0000
144 144 summary: adding another cset to branch b
145 145
146 146 changeset: 8:eebb944467c9
147 147 branch: b
148 148 parent: 4:aee39cd168d0
149 149 user: test
150 150 date: Thu Jan 01 00:00:07 1970 +0000
151 151 summary: adding cset to branch b
152 152
153 153 changeset: 7:10ff5895aa57
154 154 branch: a branch name much longer than the default justification used by branches
155 155 user: test
156 156 date: Thu Jan 01 00:00:06 1970 +0000
157 157 summary: Adding d branch
158 158
159 159 changeset: 6:589736a22561
160 160 branch: c
161 161 user: test
162 162 date: Thu Jan 01 00:00:05 1970 +0000
163 163 summary: Adding c branch
164 164
165 165 changeset: 5:d8cbc61dbaa6
166 166 branch: a
167 167 parent: 2:881fe2b92ad0
168 168 user: test
169 169 date: Thu Jan 01 00:00:04 1970 +0000
170 170 summary: Adding b branch head 2
171 171
172 172 changeset: 0:19709c5a4e75
173 173 user: test
174 174 date: Thu Jan 01 00:00:00 1970 +0000
175 175 summary: Adding root node
176 176
177 177 $ hg heads
178 178 changeset: 10:bfbe841b666e
179 179 branch: b
180 180 tag: tip
181 181 user: test
182 182 date: Thu Jan 01 00:00:09 1970 +0000
183 183 summary: adding another cset to branch b
184 184
185 185 changeset: 8:eebb944467c9
186 186 branch: b
187 187 parent: 4:aee39cd168d0
188 188 user: test
189 189 date: Thu Jan 01 00:00:07 1970 +0000
190 190 summary: adding cset to branch b
191 191
192 192 changeset: 7:10ff5895aa57
193 193 branch: a branch name much longer than the default justification used by branches
194 194 user: test
195 195 date: Thu Jan 01 00:00:06 1970 +0000
196 196 summary: Adding d branch
197 197
198 198 changeset: 6:589736a22561
199 199 branch: c
200 200 user: test
201 201 date: Thu Jan 01 00:00:05 1970 +0000
202 202 summary: Adding c branch
203 203
204 204 changeset: 5:d8cbc61dbaa6
205 205 branch: a
206 206 parent: 2:881fe2b92ad0
207 207 user: test
208 208 date: Thu Jan 01 00:00:04 1970 +0000
209 209 summary: Adding b branch head 2
210 210
211 211 changeset: 0:19709c5a4e75
212 212 user: test
213 213 date: Thu Jan 01 00:00:00 1970 +0000
214 214 summary: Adding root node
215 215
216 216 $ hg commit -d '9 0' --close-branch -m 'prune bad branch'
217 217 $ hg branches -a
218 218 b 8:eebb944467c9
219 219 a branch name much longer than the default justification used by branches 7:10ff5895aa57
220 220 $ hg up -C b
221 221 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
222 222 $ hg commit -d '9 0' --close-branch -m 'close this part branch too'
223 223
224 224 --- b branch should be inactive
225 225
226 226 $ hg branches
227 227 a branch name much longer than the default justification used by branches 7:10ff5895aa57
228 228 c 6:589736a22561 (inactive)
229 229 a 5:d8cbc61dbaa6 (inactive)
230 230 default 0:19709c5a4e75 (inactive)
231 231 $ hg branches -c
232 232 a branch name much longer than the default justification used by branches 7:10ff5895aa57
233 233 b 12:2da6583810df (closed)
234 234 c 6:589736a22561 (inactive)
235 235 a 5:d8cbc61dbaa6 (inactive)
236 236 default 0:19709c5a4e75 (inactive)
237 237 $ hg branches -a
238 238 a branch name much longer than the default justification used by branches 7:10ff5895aa57
239 239 $ hg heads b
240 240 no open branch heads found on branches b
241 241 [1]
242 242 $ hg heads --closed b
243 243 changeset: 12:2da6583810df
244 244 branch: b
245 245 tag: tip
246 246 parent: 8:eebb944467c9
247 247 user: test
248 248 date: Thu Jan 01 00:00:09 1970 +0000
249 249 summary: close this part branch too
250 250
251 251 changeset: 11:c84627f3c15d
252 252 branch: b
253 253 user: test
254 254 date: Thu Jan 01 00:00:09 1970 +0000
255 255 summary: prune bad branch
256 256
257 257 $ echo 'xxx4' >> b
258 258 $ hg commit -d '9 0' -m 'reopen branch with a change'
259 259 reopening closed branch head 12
260 260
261 261 --- branch b is back in action
262 262
263 263 $ hg branches -a
264 264 b 13:6ac12926b8c3
265 265 a branch name much longer than the default justification used by branches 7:10ff5895aa57
266 266
267 267 ---- test heads listings
268 268
269 269 $ hg heads
270 270 changeset: 13:6ac12926b8c3
271 271 branch: b
272 272 tag: tip
273 273 user: test
274 274 date: Thu Jan 01 00:00:09 1970 +0000
275 275 summary: reopen branch with a change
276 276
277 277 changeset: 7:10ff5895aa57
278 278 branch: a branch name much longer than the default justification used by branches
279 279 user: test
280 280 date: Thu Jan 01 00:00:06 1970 +0000
281 281 summary: Adding d branch
282 282
283 283 changeset: 6:589736a22561
284 284 branch: c
285 285 user: test
286 286 date: Thu Jan 01 00:00:05 1970 +0000
287 287 summary: Adding c branch
288 288
289 289 changeset: 5:d8cbc61dbaa6
290 290 branch: a
291 291 parent: 2:881fe2b92ad0
292 292 user: test
293 293 date: Thu Jan 01 00:00:04 1970 +0000
294 294 summary: Adding b branch head 2
295 295
296 296 changeset: 0:19709c5a4e75
297 297 user: test
298 298 date: Thu Jan 01 00:00:00 1970 +0000
299 299 summary: Adding root node
300 300
301 301
302 302 branch default
303 303
304 304 $ hg heads default
305 305 changeset: 0:19709c5a4e75
306 306 user: test
307 307 date: Thu Jan 01 00:00:00 1970 +0000
308 308 summary: Adding root node
309 309
310 310
311 311 branch a
312 312
313 313 $ hg heads a
314 314 changeset: 5:d8cbc61dbaa6
315 315 branch: a
316 316 parent: 2:881fe2b92ad0
317 317 user: test
318 318 date: Thu Jan 01 00:00:04 1970 +0000
319 319 summary: Adding b branch head 2
320 320
321 321 $ hg heads --active a
322 322 no open branch heads found on branches a
323 323 [1]
324 324
325 325 branch b
326 326
327 327 $ hg heads b
328 328 changeset: 13:6ac12926b8c3
329 329 branch: b
330 330 tag: tip
331 331 user: test
332 332 date: Thu Jan 01 00:00:09 1970 +0000
333 333 summary: reopen branch with a change
334 334
335 335 $ hg heads --closed b
336 336 changeset: 13:6ac12926b8c3
337 337 branch: b
338 338 tag: tip
339 339 user: test
340 340 date: Thu Jan 01 00:00:09 1970 +0000
341 341 summary: reopen branch with a change
342 342
343 343 changeset: 11:c84627f3c15d
344 344 branch: b
345 345 user: test
346 346 date: Thu Jan 01 00:00:09 1970 +0000
347 347 summary: prune bad branch
348 348
349 349 default branch colors:
350 350
351 351 $ echo "[extensions]" >> $HGRCPATH
352 352 $ echo "color =" >> $HGRCPATH
353 $ echo "[color]" >> $HGRCPATH
354 $ echo "mode = ansi" >> $HGRCPATH
353 355
354 356 $ hg up -C c
355 357 3 files updated, 0 files merged, 2 files removed, 0 files unresolved
356 358 $ hg commit -d '9 0' --close-branch -m 'reclosing this branch'
357 359 $ hg up -C b
358 360 2 files updated, 0 files merged, 3 files removed, 0 files unresolved
359 361 $ hg branches --color=always
360 362 \x1b[0;32mb\x1b[0m \x1b[0;33m 13:6ac12926b8c3\x1b[0m (esc)
361 363 \x1b[0;0ma branch name much longer than the default justification used by branches\x1b[0m \x1b[0;33m7:10ff5895aa57\x1b[0m (esc)
362 364 \x1b[0;0ma\x1b[0m \x1b[0;33m 5:d8cbc61dbaa6\x1b[0m (inactive) (esc)
363 365 \x1b[0;0mdefault\x1b[0m \x1b[0;33m 0:19709c5a4e75\x1b[0m (inactive) (esc)
364 366
365 367 default closed branch color:
366 368
367 369 $ hg branches --color=always --closed
368 370 \x1b[0;32mb\x1b[0m \x1b[0;33m 13:6ac12926b8c3\x1b[0m (esc)
369 371 \x1b[0;0ma branch name much longer than the default justification used by branches\x1b[0m \x1b[0;33m7:10ff5895aa57\x1b[0m (esc)
370 372 \x1b[0;30;1mc\x1b[0m \x1b[0;33m 14:717d2e6fabe1\x1b[0m (closed) (esc)
371 373 \x1b[0;0ma\x1b[0m \x1b[0;33m 5:d8cbc61dbaa6\x1b[0m (inactive) (esc)
372 374 \x1b[0;0mdefault\x1b[0m \x1b[0;33m 0:19709c5a4e75\x1b[0m (inactive) (esc)
373 375
374 376 $ echo "[extensions]" >> $HGRCPATH
375 377 $ echo "color =" >> $HGRCPATH
376 378 $ echo "[color]" >> $HGRCPATH
377 379 $ echo "branches.active = green" >> $HGRCPATH
378 380 $ echo "branches.closed = blue" >> $HGRCPATH
379 381 $ echo "branches.current = red" >> $HGRCPATH
380 382 $ echo "branches.inactive = magenta" >> $HGRCPATH
381 383 $ echo "log.changeset = cyan" >> $HGRCPATH
382 384
383 385 custom branch colors:
384 386
385 387 $ hg branches --color=always
386 388 \x1b[0;31mb\x1b[0m \x1b[0;36m 13:6ac12926b8c3\x1b[0m (esc)
387 389 \x1b[0;32ma branch name much longer than the default justification used by branches\x1b[0m \x1b[0;36m7:10ff5895aa57\x1b[0m (esc)
388 390 \x1b[0;35ma\x1b[0m \x1b[0;36m 5:d8cbc61dbaa6\x1b[0m (inactive) (esc)
389 391 \x1b[0;35mdefault\x1b[0m \x1b[0;36m 0:19709c5a4e75\x1b[0m (inactive) (esc)
390 392
391 393 custom closed branch color:
392 394
393 395 $ hg branches --color=always --closed
394 396 \x1b[0;31mb\x1b[0m \x1b[0;36m 13:6ac12926b8c3\x1b[0m (esc)
395 397 \x1b[0;32ma branch name much longer than the default justification used by branches\x1b[0m \x1b[0;36m7:10ff5895aa57\x1b[0m (esc)
396 398 \x1b[0;34mc\x1b[0m \x1b[0;36m 14:717d2e6fabe1\x1b[0m (closed) (esc)
397 399 \x1b[0;35ma\x1b[0m \x1b[0;36m 5:d8cbc61dbaa6\x1b[0m (inactive) (esc)
398 400 \x1b[0;35mdefault\x1b[0m \x1b[0;36m 0:19709c5a4e75\x1b[0m (inactive) (esc)
@@ -1,125 +1,127 b''
1 1 Setup
2 2
3 $ echo "[color]" >> $HGRCPATH
4 $ echo "mode = ansi" >> $HGRCPATH
3 5 $ echo "[extensions]" >> $HGRCPATH
4 6 $ echo "color=" >> $HGRCPATH
5 7 $ hg init repo
6 8 $ cd repo
7 9 $ cat > a <<EOF
8 10 > c
9 11 > c
10 12 > a
11 13 > a
12 14 > b
13 15 > a
14 16 > a
15 17 > c
16 18 > c
17 19 > EOF
18 20 $ hg ci -Am adda
19 21 adding a
20 22 $ cat > a <<EOF
21 23 > c
22 24 > c
23 25 > a
24 26 > a
25 27 > dd
26 28 > a
27 29 > a
28 30 > c
29 31 > c
30 32 > EOF
31 33
32 34 default context
33 35
34 36 $ hg diff --nodates --color=always
35 37 \x1b[0;1mdiff -r cf9f4ba66af2 a\x1b[0m (esc)
36 38 \x1b[0;31;1m--- a/a\x1b[0m (esc)
37 39 \x1b[0;32;1m+++ b/a\x1b[0m (esc)
38 40 \x1b[0;35m@@ -2,7 +2,7 @@\x1b[0m (esc)
39 41 c
40 42 a
41 43 a
42 44 \x1b[0;31m-b\x1b[0m (esc)
43 45 \x1b[0;32m+dd\x1b[0m (esc)
44 46 a
45 47 a
46 48 c
47 49
48 50 --unified=2
49 51
50 52 $ hg diff --nodates -U 2 --color=always
51 53 \x1b[0;1mdiff -r cf9f4ba66af2 a\x1b[0m (esc)
52 54 \x1b[0;31;1m--- a/a\x1b[0m (esc)
53 55 \x1b[0;32;1m+++ b/a\x1b[0m (esc)
54 56 \x1b[0;35m@@ -3,5 +3,5 @@\x1b[0m (esc)
55 57 a
56 58 a
57 59 \x1b[0;31m-b\x1b[0m (esc)
58 60 \x1b[0;32m+dd\x1b[0m (esc)
59 61 a
60 62 a
61 63
62 64 diffstat
63 65
64 66 $ hg diff --stat --color=always
65 67 a | 2 \x1b[0;32m+\x1b[0m\x1b[0;31m-\x1b[0m (esc)
66 68 1 files changed, 1 insertions(+), 1 deletions(-)
67 69 $ echo "record=" >> $HGRCPATH
68 70 $ echo "[ui]" >> $HGRCPATH
69 71 $ echo "interactive=true" >> $HGRCPATH
70 72 $ echo "[diff]" >> $HGRCPATH
71 73 $ echo "git=True" >> $HGRCPATH
72 74
73 75 record
74 76
75 77 $ chmod 0755 a
76 78 $ hg record --color=always -m moda a <<EOF
77 79 > y
78 80 > y
79 81 > EOF
80 82 \x1b[0;1mdiff --git a/a b/a\x1b[0m (esc)
81 83 \x1b[0;36;1mold mode 100644\x1b[0m (esc)
82 84 \x1b[0;36;1mnew mode 100755\x1b[0m (esc)
83 85 1 hunks, 1 lines changed
84 86 \x1b[0;33mexamine changes to 'a'? [Ynsfdaq?]\x1b[0m (esc)
85 87 \x1b[0;35m@@ -2,7 +2,7 @@\x1b[0m (esc)
86 88 c
87 89 a
88 90 a
89 91 \x1b[0;31m-b\x1b[0m (esc)
90 92 \x1b[0;32m+dd\x1b[0m (esc)
91 93 a
92 94 a
93 95 c
94 96 \x1b[0;33mrecord this change to 'a'? [Ynsfdaq?]\x1b[0m (esc)
95 97 $ echo
96 98
97 99 $ echo "[extensions]" >> $HGRCPATH
98 100 $ echo "mq=" >> $HGRCPATH
99 101 $ hg rollback
100 102 repository tip rolled back to revision 0 (undo commit)
101 103 working directory now based on revision 0
102 104
103 105 qrecord
104 106
105 107 $ hg qrecord --color=always -m moda patch <<EOF
106 108 > y
107 109 > y
108 110 > EOF
109 111 \x1b[0;1mdiff --git a/a b/a\x1b[0m (esc)
110 112 \x1b[0;36;1mold mode 100644\x1b[0m (esc)
111 113 \x1b[0;36;1mnew mode 100755\x1b[0m (esc)
112 114 1 hunks, 1 lines changed
113 115 \x1b[0;33mexamine changes to 'a'? [Ynsfdaq?]\x1b[0m (esc)
114 116 \x1b[0;35m@@ -2,7 +2,7 @@\x1b[0m (esc)
115 117 c
116 118 a
117 119 a
118 120 \x1b[0;31m-b\x1b[0m (esc)
119 121 \x1b[0;32m+dd\x1b[0m (esc)
120 122 a
121 123 a
122 124 c
123 125 \x1b[0;33mrecord this change to 'a'? [Ynsfdaq?]\x1b[0m (esc)
124 126 $ echo
125 127
@@ -1,68 +1,70 b''
1 1 http://mercurial.selenic.com/bts/issue352
2 2
3 3 $ "$TESTDIR/hghave" eol-in-paths || exit 80
4 4
5 5 test issue352
6 6
7 7 $ hg init foo
8 8 $ cd foo
9 9 $ A=`printf 'he\rllo'`
10 10 $ echo foo > "$A"
11 11 $ hg add
12 12 adding he\rllo (esc)
13 13 abort: '\n' and '\r' disallowed in filenames: 'he\rllo'
14 14 [255]
15 15 $ hg ci -A -m m
16 16 adding he\rllo (esc)
17 17 abort: '\n' and '\r' disallowed in filenames: 'he\rllo'
18 18 [255]
19 19 $ rm "$A"
20 20 $ echo foo > "hell
21 21 > o"
22 22 $ hg add
23 23 adding hell
24 24 o
25 25 abort: '\n' and '\r' disallowed in filenames: 'hell\no'
26 26 [255]
27 27 $ hg ci -A -m m
28 28 adding hell
29 29 o
30 30 abort: '\n' and '\r' disallowed in filenames: 'hell\no'
31 31 [255]
32 32 $ echo foo > "$A"
33 33 $ hg debugwalk
34 34 f he\rllo he\rllo (esc)
35 35 f hell
36 36 o hell
37 37 o
38 38
39 39 $ echo bla > quickfox
40 40 $ hg add quickfox
41 41 $ hg ci -m 2
42 42 $ A=`printf 'quick\rfox'`
43 43 $ hg cp quickfox "$A"
44 44 abort: '\n' and '\r' disallowed in filenames: 'quick\rfox'
45 45 [255]
46 46 $ hg mv quickfox "$A"
47 47 abort: '\n' and '\r' disallowed in filenames: 'quick\rfox'
48 48 [255]
49 49
50 50 http://mercurial.selenic.com/bts/issue2036
51 51
52 52 $ cd ..
53 53
54 54 test issue2039
55 55
56 56 $ hg init bar
57 57 $ cd bar
58 58 $ echo "[extensions]" >> $HGRCPATH
59 59 $ echo "color=" >> $HGRCPATH
60 $ echo "[color]" >> $HGRCPATH
61 $ echo "mode = ansi" >> $HGRCPATH
60 62 $ A=`printf 'foo\nbar'`
61 63 $ B=`printf 'foo\nbar.baz'`
62 64 $ touch "$A"
63 65 $ touch "$B"
64 66 $ hg status --color=always
65 67 \x1b[0;35;1;4m? foo\x1b[0m (esc)
66 68 \x1b[0;35;1;4mbar\x1b[0m (esc)
67 69 \x1b[0;35;1;4m? foo\x1b[0m (esc)
68 70 \x1b[0;35;1;4mbar.baz\x1b[0m (esc)
@@ -1,436 +1,436 b''
1 1 $ echo "[extensions]" >> $HGRCPATH
2 2 $ echo "mq=" >> $HGRCPATH
3 3
4 4 $ hg init
5 5 $ hg qinit
6 6
7 7 $ echo x > x
8 8 $ hg ci -Ama
9 9 adding x
10 10
11 11 $ hg qnew a.patch
12 12 $ echo a > a
13 13 $ hg add a
14 14 $ hg qrefresh
15 15
16 16 $ hg qnew b.patch
17 17 $ echo b > b
18 18 $ hg add b
19 19 $ hg qrefresh
20 20
21 21 $ hg qnew c.patch
22 22 $ echo c > c
23 23 $ hg add c
24 24 $ hg qrefresh
25 25
26 26 $ hg qpop -a
27 27 popping c.patch
28 28 popping b.patch
29 29 popping a.patch
30 30 patch queue now empty
31 31
32 32
33 33 should fail
34 34
35 35 $ hg qguard does-not-exist.patch +bleh
36 36 abort: no patch named does-not-exist.patch
37 37 [255]
38 38
39 39
40 40 should fail
41 41
42 42 $ hg qguard +fail
43 43 abort: no patches applied
44 44 [255]
45 45
46 46 $ hg qpush
47 47 applying a.patch
48 48 now at: a.patch
49 49
50 50 should guard a.patch
51 51
52 52 $ hg qguard +a
53 53
54 54 should print +a
55 55
56 56 $ hg qguard
57 57 a.patch: +a
58 58 $ hg qpop
59 59 popping a.patch
60 60 patch queue now empty
61 61
62 62
63 63 should fail
64 64
65 65 $ hg qpush a.patch
66 66 cannot push 'a.patch' - guarded by ['+a']
67 67 [1]
68 68
69 69 $ hg qguard a.patch
70 70 a.patch: +a
71 71
72 72 should push b.patch
73 73
74 74 $ hg qpush
75 75 applying b.patch
76 76 now at: b.patch
77 77
78 78 $ hg qpop
79 79 popping b.patch
80 80 patch queue now empty
81 81
82 82 test selection of an empty guard
83 83
84 84 $ hg qselect ""
85 85 abort: guard cannot be an empty string
86 86 [255]
87 87 $ hg qselect a
88 88 number of unguarded, unapplied patches has changed from 2 to 3
89 89
90 90 should push a.patch
91 91
92 92 $ hg qpush
93 93 applying a.patch
94 94 now at: a.patch
95 95
96 96 $ hg qguard -- c.patch -a
97 97
98 98 should print -a
99 99
100 100 $ hg qguard c.patch
101 101 c.patch: -a
102 102
103 103
104 104 should skip c.patch
105 105
106 106 $ hg qpush -a
107 107 applying b.patch
108 108 skipping c.patch - guarded by '-a'
109 109 now at: b.patch
110 110
111 111 should display b.patch
112 112
113 113 $ hg qtop
114 114 b.patch
115 115
116 116 $ hg qguard -n c.patch
117 117
118 118 should push c.patch
119 119
120 120 $ hg qpush -a
121 121 applying c.patch
122 122 now at: c.patch
123 123
124 124 $ hg qpop -a
125 125 popping c.patch
126 126 popping b.patch
127 127 popping a.patch
128 128 patch queue now empty
129 129 $ hg qselect -n
130 130 guards deactivated
131 131 number of unguarded, unapplied patches has changed from 3 to 2
132 132
133 133 should push all
134 134
135 135 $ hg qpush -a
136 136 applying b.patch
137 137 applying c.patch
138 138 now at: c.patch
139 139
140 140 $ hg qpop -a
141 141 popping c.patch
142 142 popping b.patch
143 143 patch queue now empty
144 144 $ hg qguard a.patch +1
145 145 $ hg qguard b.patch +2
146 146 $ hg qselect 1
147 147 number of unguarded, unapplied patches has changed from 1 to 2
148 148
149 149 should push a.patch, not b.patch
150 150
151 151 $ hg qpush
152 152 applying a.patch
153 153 now at: a.patch
154 154 $ hg qpush
155 155 applying c.patch
156 156 now at: c.patch
157 157 $ hg qpop -a
158 158 popping c.patch
159 159 popping a.patch
160 160 patch queue now empty
161 161
162 162 $ hg qselect 2
163 163
164 164 should push b.patch
165 165
166 166 $ hg qpush
167 167 applying b.patch
168 168 now at: b.patch
169 169 $ hg qpush -a
170 170 applying c.patch
171 171 now at: c.patch
172 172
173 173 Used to be an issue with holes in the patch sequence
174 174 So, put one hole on the base and ask for topmost patch.
175 175
176 176 $ hg qtop
177 177 c.patch
178 178 $ hg qpop -a
179 179 popping c.patch
180 180 popping b.patch
181 181 patch queue now empty
182 182
183 183 $ hg qselect 1 2
184 184 number of unguarded, unapplied patches has changed from 2 to 3
185 185
186 186 should push a.patch, b.patch
187 187
188 188 $ hg qpush
189 189 applying a.patch
190 190 now at: a.patch
191 191 $ hg qpush
192 192 applying b.patch
193 193 now at: b.patch
194 194 $ hg qpop -a
195 195 popping b.patch
196 196 popping a.patch
197 197 patch queue now empty
198 198
199 199 $ hg qguard -- a.patch +1 +2 -3
200 200 $ hg qselect 1 2 3
201 201 number of unguarded, unapplied patches has changed from 3 to 2
202 202
203 203
204 204 list patches and guards
205 205
206 206 $ hg qguard -l
207 207 a.patch: +1 +2 -3
208 208 b.patch: +2
209 209 c.patch: unguarded
210 210
211 211 have at least one patch applied to test coloring
212 212
213 213 $ hg qpush
214 214 applying b.patch
215 215 now at: b.patch
216 216
217 217 list patches and guards with color
218 218
219 219 $ hg --config extensions.color= qguard --config color.mode=ansi \
220 220 > -l --color=always
221 221 \x1b[0;30;1ma.patch\x1b[0m: \x1b[0;33m+1\x1b[0m \x1b[0;33m+2\x1b[0m \x1b[0;31m-3\x1b[0m (esc)
222 222 \x1b[0;34;1;4mb.patch\x1b[0m: \x1b[0;33m+2\x1b[0m (esc)
223 223 \x1b[0;30;1mc.patch\x1b[0m: \x1b[0;32munguarded\x1b[0m (esc)
224 224
225 225 should pop b.patch
226 226
227 227 $ hg qpop
228 228 popping b.patch
229 229 patch queue now empty
230 230
231 231 list series
232 232
233 233 $ hg qseries -v
234 234 0 G a.patch
235 235 1 U b.patch
236 236 2 U c.patch
237 237
238 238 list guards
239 239
240 240 $ hg qselect
241 241 1
242 242 2
243 243 3
244 244
245 245 should push b.patch
246 246
247 247 $ hg qpush
248 248 applying b.patch
249 249 now at: b.patch
250 250
251 251 $ hg qpush -a
252 252 applying c.patch
253 253 now at: c.patch
254 254 $ hg qselect -n --reapply
255 255 guards deactivated
256 256 popping guarded patches
257 257 popping c.patch
258 258 popping b.patch
259 259 patch queue now empty
260 260 reapplying unguarded patches
261 261 applying c.patch
262 262 now at: c.patch
263 263
264 264 guards in series file: +1 +2 -3
265 265
266 266 $ hg qselect -s
267 267 +1
268 268 +2
269 269 -3
270 270
271 271 should show c.patch
272 272
273 273 $ hg qapplied
274 274 c.patch
275 275
276 276 $ hg qrename a.patch new.patch
277 277
278 278 should show :
279 279
280 280
281 281 new.patch: +1 +2 -3
282 282
283 283
284 284 b.patch: +2
285 285
286 286
287 287 c.patch: unguarded
288 288
289 289 $ hg qguard -l
290 290 new.patch: +1 +2 -3
291 291 b.patch: +2
292 292 c.patch: unguarded
293 293
294 294 $ hg qnew d.patch
295 295 $ hg qpop
296 296 popping d.patch
297 297 now at: c.patch
298 298
299 299 should show new.patch and b.patch as Guarded, c.patch as Applied
300 300
301 301
302 302 and d.patch as Unapplied
303 303
304 304 $ hg qseries -v
305 305 0 G new.patch
306 306 1 G b.patch
307 307 2 A c.patch
308 308 3 U d.patch
309 309
310 310 qseries again, but with color
311 311
312 $ hg --config extensions.color= qseries -v --color=always
312 $ hg --config extensions.color= --config color.mode=ansi qseries -v --color=always
313 313 0 G \x1b[0;30;1mnew.patch\x1b[0m (esc)
314 314 1 G \x1b[0;30;1mb.patch\x1b[0m (esc)
315 315 2 A \x1b[0;34;1;4mc.patch\x1b[0m (esc)
316 316 3 U \x1b[0;30;1md.patch\x1b[0m (esc)
317 317
318 318 $ hg qguard d.patch +2
319 319
320 320 new.patch, b.patch: Guarded. c.patch: Applied. d.patch: Guarded.
321 321
322 322 $ hg qseries -v
323 323 0 G new.patch
324 324 1 G b.patch
325 325 2 A c.patch
326 326 3 G d.patch
327 327
328 328 $ qappunappv()
329 329 > {
330 330 > for command in qapplied "qapplied -v" qunapplied "qunapplied -v"; do
331 331 > echo % hg $command
332 332 > hg $command
333 333 > done
334 334 > }
335 335
336 336 $ hg qpop -a
337 337 popping c.patch
338 338 patch queue now empty
339 339 $ hg qguard -l
340 340 new.patch: +1 +2 -3
341 341 b.patch: +2
342 342 c.patch: unguarded
343 343 d.patch: +2
344 344 $ qappunappv
345 345 % hg qapplied
346 346 % hg qapplied -v
347 347 % hg qunapplied
348 348 c.patch
349 349 % hg qunapplied -v
350 350 0 G new.patch
351 351 1 G b.patch
352 352 2 U c.patch
353 353 3 G d.patch
354 354 $ hg qselect 1
355 355 number of unguarded, unapplied patches has changed from 1 to 2
356 356 $ qappunappv
357 357 % hg qapplied
358 358 % hg qapplied -v
359 359 % hg qunapplied
360 360 new.patch
361 361 c.patch
362 362 % hg qunapplied -v
363 363 0 U new.patch
364 364 1 G b.patch
365 365 2 U c.patch
366 366 3 G d.patch
367 367 $ hg qpush -a
368 368 applying new.patch
369 369 skipping b.patch - guarded by ['+2']
370 370 applying c.patch
371 371 skipping d.patch - guarded by ['+2']
372 372 now at: c.patch
373 373 $ qappunappv
374 374 % hg qapplied
375 375 new.patch
376 376 c.patch
377 377 % hg qapplied -v
378 378 0 A new.patch
379 379 1 G b.patch
380 380 2 A c.patch
381 381 % hg qunapplied
382 382 % hg qunapplied -v
383 383 3 G d.patch
384 384 $ hg qselect 2
385 385 number of unguarded, unapplied patches has changed from 0 to 1
386 386 number of guarded, applied patches has changed from 1 to 0
387 387 $ qappunappv
388 388 % hg qapplied
389 389 new.patch
390 390 c.patch
391 391 % hg qapplied -v
392 392 0 A new.patch
393 393 1 U b.patch
394 394 2 A c.patch
395 395 % hg qunapplied
396 396 d.patch
397 397 % hg qunapplied -v
398 398 3 U d.patch
399 399
400 400 $ for patch in `hg qseries`; do
401 401 > echo % hg qapplied $patch
402 402 > hg qapplied $patch
403 403 > echo % hg qunapplied $patch
404 404 > hg qunapplied $patch
405 405 > done
406 406 % hg qapplied new.patch
407 407 new.patch
408 408 % hg qunapplied new.patch
409 409 b.patch
410 410 d.patch
411 411 % hg qapplied b.patch
412 412 new.patch
413 413 % hg qunapplied b.patch
414 414 d.patch
415 415 % hg qapplied c.patch
416 416 new.patch
417 417 c.patch
418 418 % hg qunapplied c.patch
419 419 d.patch
420 420 % hg qapplied d.patch
421 421 new.patch
422 422 c.patch
423 423 % hg qunapplied d.patch
424 424
425 425
426 426 hg qseries -m: only b.patch should be shown
427 427 the guards file was not ignored in the past
428 428
429 429 $ hg qdelete -k b.patch
430 430 $ hg qseries -m
431 431 b.patch
432 432
433 433 hg qseries -m with color
434 434
435 $ hg --config extensions.color= qseries -m --color=always
435 $ hg --config extensions.color= --config color.mode=ansi qseries -m --color=always
436 436 \x1b[0;31;1mb.patch\x1b[0m (esc)
@@ -1,1387 +1,1387 b''
1 1 $ checkundo()
2 2 > {
3 3 > if [ -f .hg/store/undo ]; then
4 4 > echo ".hg/store/undo still exists after $1"
5 5 > fi
6 6 > }
7 7
8 8 $ echo "[extensions]" >> $HGRCPATH
9 9 $ echo "mq=" >> $HGRCPATH
10 10
11 11 $ echo "[mq]" >> $HGRCPATH
12 12 $ echo "plain=true" >> $HGRCPATH
13 13
14 14
15 15 help
16 16
17 17 $ hg help mq
18 18 mq extension - manage a stack of patches
19 19
20 20 This extension lets you work with a stack of patches in a Mercurial
21 21 repository. It manages two stacks of patches - all known patches, and applied
22 22 patches (subset of known patches).
23 23
24 24 Known patches are represented as patch files in the .hg/patches directory.
25 25 Applied patches are both patch files and changesets.
26 26
27 27 Common tasks (use "hg help command" for more details):
28 28
29 29 create new patch qnew
30 30 import existing patch qimport
31 31
32 32 print patch series qseries
33 33 print applied patches qapplied
34 34
35 35 add known patch to applied stack qpush
36 36 remove patch from applied stack qpop
37 37 refresh contents of top applied patch qrefresh
38 38
39 39 By default, mq will automatically use git patches when required to avoid
40 40 losing file mode changes, copy records, binary files or empty files creations
41 41 or deletions. This behaviour can be configured with:
42 42
43 43 [mq]
44 44 git = auto/keep/yes/no
45 45
46 46 If set to 'keep', mq will obey the [diff] section configuration while
47 47 preserving existing git patches upon qrefresh. If set to 'yes' or 'no', mq
48 48 will override the [diff] section and always generate git or regular patches,
49 49 possibly losing data in the second case.
50 50
51 51 You will by default be managing a patch queue named "patches". You can create
52 52 other, independent patch queues with the "hg qqueue" command.
53 53
54 54 list of commands:
55 55
56 56 qapplied print the patches already applied
57 57 qclone clone main and patch repository at same time
58 58 qdelete remove patches from queue
59 59 qdiff diff of the current patch and subsequent modifications
60 60 qfinish move applied patches into repository history
61 61 qfold fold the named patches into the current patch
62 62 qgoto push or pop patches until named patch is at top of stack
63 63 qguard set or print guards for a patch
64 64 qheader print the header of the topmost or specified patch
65 65 qimport import a patch
66 66 qnew create a new patch
67 67 qnext print the name of the next patch
68 68 qpop pop the current patch off the stack
69 69 qprev print the name of the previous patch
70 70 qpush push the next patch onto the stack
71 71 qqueue manage multiple patch queues
72 72 qrefresh update the current patch
73 73 qrename rename a patch
74 74 qselect set or print guarded patches to push
75 75 qseries print the entire series file
76 76 qtop print the name of the current patch
77 77 qunapplied print the patches not yet applied
78 78 strip strip changesets and all their descendants from the repository
79 79
80 80 use "hg -v help mq" to show builtin aliases and global options
81 81
82 82 $ hg init a
83 83 $ cd a
84 84 $ echo a > a
85 85 $ hg ci -Ama
86 86 adding a
87 87
88 88 $ hg clone . ../k
89 89 updating to branch default
90 90 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
91 91
92 92 $ mkdir b
93 93 $ echo z > b/z
94 94 $ hg ci -Ama
95 95 adding b/z
96 96
97 97
98 98 qinit
99 99
100 100 $ hg qinit
101 101
102 102 $ cd ..
103 103 $ hg init b
104 104
105 105
106 106 -R qinit
107 107
108 108 $ hg -R b qinit
109 109
110 110 $ hg init c
111 111
112 112
113 113 qinit -c
114 114
115 115 $ hg --cwd c qinit -c
116 116 $ hg -R c/.hg/patches st
117 117 A .hgignore
118 118 A series
119 119
120 120
121 121 qinit; qinit -c
122 122
123 123 $ hg init d
124 124 $ cd d
125 125 $ hg qinit
126 126 $ hg qinit -c
127 127
128 128 qinit -c should create both files if they don't exist
129 129
130 130 $ cat .hg/patches/.hgignore
131 131 ^\.hg
132 132 ^\.mq
133 133 syntax: glob
134 134 status
135 135 guards
136 136 $ cat .hg/patches/series
137 137 $ hg qinit -c
138 138 abort: repository $TESTTMP/d/.hg/patches already exists!
139 139 [255]
140 140 $ cd ..
141 141
142 142 $ echo '% qinit; <stuff>; qinit -c'
143 143 % qinit; <stuff>; qinit -c
144 144 $ hg init e
145 145 $ cd e
146 146 $ hg qnew A
147 147 $ checkundo qnew
148 148 $ echo foo > foo
149 149 $ hg add foo
150 150 $ hg qrefresh
151 151 $ hg qnew B
152 152 $ echo >> foo
153 153 $ hg qrefresh
154 154 $ echo status >> .hg/patches/.hgignore
155 155 $ echo bleh >> .hg/patches/.hgignore
156 156 $ hg qinit -c
157 157 adding .hg/patches/A
158 158 adding .hg/patches/B
159 159 $ hg -R .hg/patches status
160 160 A .hgignore
161 161 A A
162 162 A B
163 163 A series
164 164
165 165 qinit -c shouldn't touch these files if they already exist
166 166
167 167 $ cat .hg/patches/.hgignore
168 168 status
169 169 bleh
170 170 $ cat .hg/patches/series
171 171 A
172 172 B
173 173
174 174 add an untracked file
175 175
176 176 $ echo >> .hg/patches/flaf
177 177
178 178 status --mq with color (issue2096)
179 179
180 $ hg status --mq --config extensions.color= --color=always
180 $ hg status --mq --config extensions.color= --config color.mode=ansi --color=always
181 181 \x1b[0;32;1mA .hgignore\x1b[0m (esc)
182 182 \x1b[0;32;1mA A\x1b[0m (esc)
183 183 \x1b[0;32;1mA B\x1b[0m (esc)
184 184 \x1b[0;32;1mA series\x1b[0m (esc)
185 185 \x1b[0;35;1;4m? flaf\x1b[0m (esc)
186 186
187 187 try the --mq option on a command provided by an extension
188 188
189 189 $ hg purge --mq --verbose --config extensions.purge=
190 190 Removing file flaf
191 191
192 192 $ cd ..
193 193
194 194 init --mq without repo
195 195
196 196 $ mkdir f
197 197 $ cd f
198 198 $ hg init --mq
199 199 abort: there is no Mercurial repository here (.hg not found)
200 200 [255]
201 201 $ cd ..
202 202
203 203 init --mq with repo path
204 204
205 205 $ hg init g
206 206 $ hg init --mq g
207 207 $ test -d g/.hg/patches/.hg
208 208
209 209 init --mq with nonexistent directory
210 210
211 211 $ hg init --mq nonexistentdir
212 212 abort: repository nonexistentdir not found!
213 213 [255]
214 214
215 215
216 216 init --mq with bundle (non "local")
217 217
218 218 $ hg -R a bundle --all a.bundle >/dev/null
219 219 $ hg init --mq a.bundle
220 220 abort: only a local queue repository may be initialized
221 221 [255]
222 222
223 223 $ cd a
224 224
225 225 $ hg qnew -m 'foo bar' test.patch
226 226
227 227 $ echo '# comment' > .hg/patches/series.tmp
228 228 $ echo >> .hg/patches/series.tmp # empty line
229 229 $ cat .hg/patches/series >> .hg/patches/series.tmp
230 230 $ mv .hg/patches/series.tmp .hg/patches/series
231 231
232 232
233 233 qrefresh
234 234
235 235 $ echo a >> a
236 236 $ hg qrefresh
237 237 $ cat .hg/patches/test.patch
238 238 foo bar
239 239
240 240 diff -r [a-f0-9]* a (re)
241 241 --- a/a\t(?P<date>.*) (re)
242 242 \+\+\+ b/a\t(?P<date2>.*) (re)
243 243 @@ -1,1 +1,2 @@
244 244 a
245 245 +a
246 246
247 247 empty qrefresh
248 248
249 249 $ hg qrefresh -X a
250 250
251 251 revision:
252 252
253 253 $ hg diff -r -2 -r -1
254 254
255 255 patch:
256 256
257 257 $ cat .hg/patches/test.patch
258 258 foo bar
259 259
260 260
261 261 working dir diff:
262 262
263 263 $ hg diff --nodates -q
264 264 --- a/a
265 265 +++ b/a
266 266 @@ -1,1 +1,2 @@
267 267 a
268 268 +a
269 269
270 270 restore things
271 271
272 272 $ hg qrefresh
273 273 $ checkundo qrefresh
274 274
275 275
276 276 qpop
277 277
278 278 $ hg qpop
279 279 popping test.patch
280 280 patch queue now empty
281 281 $ checkundo qpop
282 282
283 283
284 284 qpush with dump of tag cache
285 285 Dump the tag cache to ensure that it has exactly one head after qpush.
286 286
287 287 $ rm -f .hg/cache/tags
288 288 $ hg tags > /dev/null
289 289
290 290 .hg/cache/tags (pre qpush):
291 291
292 292 $ cat .hg/cache/tags
293 293 1 [\da-f]{40} (re)
294 294
295 295 $ hg qpush
296 296 applying test.patch
297 297 now at: test.patch
298 298 $ hg tags > /dev/null
299 299
300 300 .hg/cache/tags (post qpush):
301 301
302 302 $ cat .hg/cache/tags
303 303 2 [\da-f]{40} (re)
304 304
305 305 $ checkundo qpush
306 306 $ cd ..
307 307
308 308
309 309 pop/push outside repo
310 310 $ hg -R a qpop
311 311 popping test.patch
312 312 patch queue now empty
313 313 $ hg -R a qpush
314 314 applying test.patch
315 315 now at: test.patch
316 316
317 317 $ cd a
318 318 $ hg qnew test2.patch
319 319
320 320 qrefresh in subdir
321 321
322 322 $ cd b
323 323 $ echo a > a
324 324 $ hg add a
325 325 $ hg qrefresh
326 326
327 327 pop/push -a in subdir
328 328
329 329 $ hg qpop -a
330 330 popping test2.patch
331 331 popping test.patch
332 332 patch queue now empty
333 333 $ hg --traceback qpush -a
334 334 applying test.patch
335 335 applying test2.patch
336 336 now at: test2.patch
337 337
338 338
339 339 setting columns & formatted tests truncating (issue1912)
340 340
341 341 $ COLUMNS=4 hg qseries --config ui.formatted=true
342 342 test.patch
343 343 test2.patch
344 344 $ COLUMNS=20 hg qseries --config ui.formatted=true -vs
345 345 0 A test.patch: f...
346 346 1 A test2.patch:
347 347 $ hg qpop
348 348 popping test2.patch
349 349 now at: test.patch
350 350 $ hg qseries -vs
351 351 0 A test.patch: foo bar
352 352 1 U test2.patch:
353 353 $ hg sum | grep mq
354 354 mq: 1 applied, 1 unapplied
355 355 $ hg qpush
356 356 applying test2.patch
357 357 now at: test2.patch
358 358 $ hg sum | grep mq
359 359 mq: 2 applied
360 360 $ hg qapplied
361 361 test.patch
362 362 test2.patch
363 363 $ hg qtop
364 364 test2.patch
365 365
366 366
367 367 prev
368 368
369 369 $ hg qapp -1
370 370 test.patch
371 371
372 372 next
373 373
374 374 $ hg qunapp -1
375 375 all patches applied
376 376 [1]
377 377
378 378 $ hg qpop
379 379 popping test2.patch
380 380 now at: test.patch
381 381
382 382 commit should fail
383 383
384 384 $ hg commit
385 385 abort: cannot commit over an applied mq patch
386 386 [255]
387 387
388 388 push should fail
389 389
390 390 $ hg push ../../k
391 391 pushing to ../../k
392 392 abort: source has mq patches applied
393 393 [255]
394 394
395 395
396 396 import should fail
397 397
398 398 $ hg st .
399 399 $ echo foo >> ../a
400 400 $ hg diff > ../../import.diff
401 401 $ hg revert --no-backup ../a
402 402 $ hg import ../../import.diff
403 403 abort: cannot import over an applied patch
404 404 [255]
405 405 $ hg st
406 406
407 407 import --no-commit should succeed
408 408
409 409 $ hg import --no-commit ../../import.diff
410 410 applying ../../import.diff
411 411 $ hg st
412 412 M a
413 413 $ hg revert --no-backup ../a
414 414
415 415
416 416 qunapplied
417 417
418 418 $ hg qunapplied
419 419 test2.patch
420 420
421 421
422 422 qpush/qpop with index
423 423
424 424 $ hg qnew test1b.patch
425 425 $ echo 1b > 1b
426 426 $ hg add 1b
427 427 $ hg qrefresh
428 428 $ hg qpush 2
429 429 applying test2.patch
430 430 now at: test2.patch
431 431 $ hg qpop 0
432 432 popping test2.patch
433 433 popping test1b.patch
434 434 now at: test.patch
435 435 $ hg qpush test.patch+1
436 436 applying test1b.patch
437 437 now at: test1b.patch
438 438 $ hg qpush test.patch+2
439 439 applying test2.patch
440 440 now at: test2.patch
441 441 $ hg qpop test2.patch-1
442 442 popping test2.patch
443 443 now at: test1b.patch
444 444 $ hg qpop test2.patch-2
445 445 popping test1b.patch
446 446 now at: test.patch
447 447 $ hg qpush test1b.patch+1
448 448 applying test1b.patch
449 449 applying test2.patch
450 450 now at: test2.patch
451 451
452 452
453 453 qpush --move
454 454
455 455 $ hg qpop -a
456 456 popping test2.patch
457 457 popping test1b.patch
458 458 popping test.patch
459 459 patch queue now empty
460 460 $ hg qguard test1b.patch -- -negguard
461 461 $ hg qguard test2.patch -- +posguard
462 462 $ hg qpush --move test2.patch # can't move guarded patch
463 463 cannot push 'test2.patch' - guarded by ['+posguard']
464 464 [1]
465 465 $ hg qselect posguard
466 466 number of unguarded, unapplied patches has changed from 2 to 3
467 467 $ hg qpush --move test2.patch # move to front
468 468 applying test2.patch
469 469 now at: test2.patch
470 470 $ hg qpush --move test1b.patch # negative guard unselected
471 471 applying test1b.patch
472 472 now at: test1b.patch
473 473 $ hg qpush --move test.patch # noop move
474 474 applying test.patch
475 475 now at: test.patch
476 476 $ hg qseries -v
477 477 0 A test2.patch
478 478 1 A test1b.patch
479 479 2 A test.patch
480 480 $ hg qpop -a
481 481 popping test.patch
482 482 popping test1b.patch
483 483 popping test2.patch
484 484 patch queue now empty
485 485
486 486 cleaning up
487 487
488 488 $ hg qselect --none
489 489 guards deactivated
490 490 number of unguarded, unapplied patches has changed from 3 to 2
491 491 $ hg qguard --none test1b.patch
492 492 $ hg qguard --none test2.patch
493 493 $ hg qpush --move test.patch
494 494 applying test.patch
495 495 now at: test.patch
496 496 $ hg qpush --move test1b.patch
497 497 applying test1b.patch
498 498 now at: test1b.patch
499 499 $ hg qpush --move bogus # nonexistent patch
500 500 abort: patch bogus not in series
501 501 [255]
502 502 $ hg qpush --move # no patch
503 503 abort: please specify the patch to move
504 504 [255]
505 505 $ hg qpush --move test.patch # already applied
506 506 abort: cannot push to a previous patch: test.patch
507 507 [255]
508 508 $ hg qpush
509 509 applying test2.patch
510 510 now at: test2.patch
511 511
512 512
513 513 series after move
514 514
515 515 $ cat `hg root`/.hg/patches/series
516 516 test.patch
517 517 test1b.patch
518 518 test2.patch
519 519 # comment
520 520
521 521
522 522
523 523 pop, qapplied, qunapplied
524 524
525 525 $ hg qseries -v
526 526 0 A test.patch
527 527 1 A test1b.patch
528 528 2 A test2.patch
529 529
530 530 qapplied -1 test.patch
531 531
532 532 $ hg qapplied -1 test.patch
533 533 only one patch applied
534 534 [1]
535 535
536 536 qapplied -1 test1b.patch
537 537
538 538 $ hg qapplied -1 test1b.patch
539 539 test.patch
540 540
541 541 qapplied -1 test2.patch
542 542
543 543 $ hg qapplied -1 test2.patch
544 544 test1b.patch
545 545
546 546 qapplied -1
547 547
548 548 $ hg qapplied -1
549 549 test1b.patch
550 550
551 551 qapplied
552 552
553 553 $ hg qapplied
554 554 test.patch
555 555 test1b.patch
556 556 test2.patch
557 557
558 558 qapplied test1b.patch
559 559
560 560 $ hg qapplied test1b.patch
561 561 test.patch
562 562 test1b.patch
563 563
564 564 qunapplied -1
565 565
566 566 $ hg qunapplied -1
567 567 all patches applied
568 568 [1]
569 569
570 570 qunapplied
571 571
572 572 $ hg qunapplied
573 573
574 574 popping
575 575
576 576 $ hg qpop
577 577 popping test2.patch
578 578 now at: test1b.patch
579 579
580 580 qunapplied -1
581 581
582 582 $ hg qunapplied -1
583 583 test2.patch
584 584
585 585 qunapplied
586 586
587 587 $ hg qunapplied
588 588 test2.patch
589 589
590 590 qunapplied test2.patch
591 591
592 592 $ hg qunapplied test2.patch
593 593
594 594 qunapplied -1 test2.patch
595 595
596 596 $ hg qunapplied -1 test2.patch
597 597 all patches applied
598 598 [1]
599 599
600 600 popping -a
601 601
602 602 $ hg qpop -a
603 603 popping test1b.patch
604 604 popping test.patch
605 605 patch queue now empty
606 606
607 607 qapplied
608 608
609 609 $ hg qapplied
610 610
611 611 qapplied -1
612 612
613 613 $ hg qapplied -1
614 614 no patches applied
615 615 [1]
616 616 $ hg qpush
617 617 applying test.patch
618 618 now at: test.patch
619 619
620 620
621 621 push should succeed
622 622
623 623 $ hg qpop -a
624 624 popping test.patch
625 625 patch queue now empty
626 626 $ hg push ../../k
627 627 pushing to ../../k
628 628 searching for changes
629 629 adding changesets
630 630 adding manifests
631 631 adding file changes
632 632 added 1 changesets with 1 changes to 1 files
633 633
634 634
635 635 we want to start with some patches applied
636 636
637 637 $ hg qpush -a
638 638 applying test.patch
639 639 applying test1b.patch
640 640 applying test2.patch
641 641 now at: test2.patch
642 642
643 643 % pops all patches and succeeds
644 644
645 645 $ hg qpop -a
646 646 popping test2.patch
647 647 popping test1b.patch
648 648 popping test.patch
649 649 patch queue now empty
650 650
651 651 % does nothing and succeeds
652 652
653 653 $ hg qpop -a
654 654 no patches applied
655 655
656 656 % fails - nothing else to pop
657 657
658 658 $ hg qpop
659 659 no patches applied
660 660 [1]
661 661
662 662 % pushes a patch and succeeds
663 663
664 664 $ hg qpush
665 665 applying test.patch
666 666 now at: test.patch
667 667
668 668 % pops a patch and succeeds
669 669
670 670 $ hg qpop
671 671 popping test.patch
672 672 patch queue now empty
673 673
674 674 % pushes up to test1b.patch and succeeds
675 675
676 676 $ hg qpush test1b.patch
677 677 applying test.patch
678 678 applying test1b.patch
679 679 now at: test1b.patch
680 680
681 681 % does nothing and succeeds
682 682
683 683 $ hg qpush test1b.patch
684 684 qpush: test1b.patch is already at the top
685 685
686 686 % does nothing and succeeds
687 687
688 688 $ hg qpop test1b.patch
689 689 qpop: test1b.patch is already at the top
690 690
691 691 % fails - can't push to this patch
692 692
693 693 $ hg qpush test.patch
694 694 abort: cannot push to a previous patch: test.patch
695 695 [255]
696 696
697 697 % fails - can't pop to this patch
698 698
699 699 $ hg qpop test2.patch
700 700 abort: patch test2.patch is not applied
701 701 [255]
702 702
703 703 % pops up to test.patch and succeeds
704 704
705 705 $ hg qpop test.patch
706 706 popping test1b.patch
707 707 now at: test.patch
708 708
709 709 % pushes all patches and succeeds
710 710
711 711 $ hg qpush -a
712 712 applying test1b.patch
713 713 applying test2.patch
714 714 now at: test2.patch
715 715
716 716 % does nothing and succeeds
717 717
718 718 $ hg qpush -a
719 719 all patches are currently applied
720 720
721 721 % fails - nothing else to push
722 722
723 723 $ hg qpush
724 724 patch series already fully applied
725 725 [1]
726 726
727 727 % does nothing and succeeds
728 728
729 729 $ hg qpush test2.patch
730 730 qpush: test2.patch is already at the top
731 731
732 732 strip
733 733
734 734 $ cd ../../b
735 735 $ echo x>x
736 736 $ hg ci -Ama
737 737 adding x
738 738 $ hg strip tip
739 739 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
740 740 saved backup bundle to $TESTTMP/b/.hg/strip-backup/*-backup.hg (glob)
741 741 $ hg unbundle .hg/strip-backup/*
742 742 adding changesets
743 743 adding manifests
744 744 adding file changes
745 745 added 1 changesets with 1 changes to 1 files
746 746 (run 'hg update' to get a working copy)
747 747
748 748
749 749 strip with local changes, should complain
750 750
751 751 $ hg up
752 752 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
753 753 $ echo y>y
754 754 $ hg add y
755 755 $ hg strip tip
756 756 abort: local changes found
757 757 [255]
758 758
759 759 --force strip with local changes
760 760
761 761 $ hg strip -f tip
762 762 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
763 763 saved backup bundle to $TESTTMP/b/.hg/strip-backup/*-backup.hg (glob)
764 764
765 765
766 766 cd b; hg qrefresh
767 767
768 768 $ hg init refresh
769 769 $ cd refresh
770 770 $ echo a > a
771 771 $ hg ci -Ama
772 772 adding a
773 773 $ hg qnew -mfoo foo
774 774 $ echo a >> a
775 775 $ hg qrefresh
776 776 $ mkdir b
777 777 $ cd b
778 778 $ echo f > f
779 779 $ hg add f
780 780 $ hg qrefresh
781 781 $ cat ../.hg/patches/foo
782 782 foo
783 783
784 784 diff -r cb9a9f314b8b a
785 785 --- a/a\t(?P<date>.*) (re)
786 786 \+\+\+ b/a\t(?P<date>.*) (re)
787 787 @@ -1,1 +1,2 @@
788 788 a
789 789 +a
790 790 diff -r cb9a9f314b8b b/f
791 791 --- /dev/null\t(?P<date>.*) (re)
792 792 \+\+\+ b/b/f\t(?P<date>.*) (re)
793 793 @@ -0,0 +1,1 @@
794 794 +f
795 795
796 796 hg qrefresh .
797 797
798 798 $ hg qrefresh .
799 799 $ cat ../.hg/patches/foo
800 800 foo
801 801
802 802 diff -r cb9a9f314b8b b/f
803 803 --- /dev/null\t(?P<date>.*) (re)
804 804 \+\+\+ b/b/f\t(?P<date>.*) (re)
805 805 @@ -0,0 +1,1 @@
806 806 +f
807 807 $ hg status
808 808 M a
809 809
810 810
811 811 qpush failure
812 812
813 813 $ cd ..
814 814 $ hg qrefresh
815 815 $ hg qnew -mbar bar
816 816 $ echo foo > foo
817 817 $ echo bar > bar
818 818 $ hg add foo bar
819 819 $ hg qrefresh
820 820 $ hg qpop -a
821 821 popping bar
822 822 popping foo
823 823 patch queue now empty
824 824 $ echo bar > foo
825 825 $ hg qpush -a
826 826 applying foo
827 827 applying bar
828 828 file foo already exists
829 829 1 out of 1 hunks FAILED -- saving rejects to file foo.rej
830 830 patch failed, unable to continue (try -v)
831 831 patch failed, rejects left in working dir
832 832 errors during apply, please fix and refresh bar
833 833 [2]
834 834 $ hg st
835 835 ? foo
836 836 ? foo.rej
837 837
838 838
839 839 mq tags
840 840
841 841 $ hg log --template '{rev} {tags}\n' -r qparent:qtip
842 842 0 qparent
843 843 1 foo qbase
844 844 2 bar qtip tip
845 845
846 846
847 847 bad node in status
848 848
849 849 $ hg qpop
850 850 popping bar
851 851 now at: foo
852 852 $ hg strip -qn tip
853 853 $ hg tip
854 854 changeset: 0:cb9a9f314b8b
855 855 tag: tip
856 856 user: test
857 857 date: Thu Jan 01 00:00:00 1970 +0000
858 858 summary: a
859 859
860 860 $ hg branches
861 861 default 0:cb9a9f314b8b
862 862 $ hg qpop
863 863 no patches applied
864 864 [1]
865 865
866 866 $ cat >>$HGRCPATH <<EOF
867 867 > [diff]
868 868 > git = True
869 869 > EOF
870 870 $ cd ..
871 871 $ hg init git
872 872 $ cd git
873 873 $ hg qinit
874 874
875 875 $ hg qnew -m'new file' new
876 876 $ echo foo > new
877 877 $ chmod +x new
878 878 $ hg add new
879 879 $ hg qrefresh
880 880 $ cat .hg/patches/new
881 881 new file
882 882
883 883 diff --git a/new b/new
884 884 new file mode 100755
885 885 --- /dev/null
886 886 +++ b/new
887 887 @@ -0,0 +1,1 @@
888 888 +foo
889 889
890 890 $ hg qnew -m'copy file' copy
891 891 $ hg cp new copy
892 892 $ hg qrefresh
893 893 $ cat .hg/patches/copy
894 894 copy file
895 895
896 896 diff --git a/new b/copy
897 897 copy from new
898 898 copy to copy
899 899
900 900 $ hg qpop
901 901 popping copy
902 902 now at: new
903 903 $ hg qpush
904 904 applying copy
905 905 now at: copy
906 906 $ hg qdiff
907 907 diff --git a/new b/copy
908 908 copy from new
909 909 copy to copy
910 910 $ cat >>$HGRCPATH <<EOF
911 911 > [diff]
912 912 > git = False
913 913 > EOF
914 914 $ hg qdiff --git
915 915 diff --git a/new b/copy
916 916 copy from new
917 917 copy to copy
918 918 $ cd ..
919 919
920 920 empty lines in status
921 921
922 922 $ hg init emptystatus
923 923 $ cd emptystatus
924 924 $ hg qinit
925 925 $ printf '\n\n' > .hg/patches/status
926 926 $ hg qser
927 927 $ cd ..
928 928
929 929 bad line in status (without ":")
930 930
931 931 $ hg init badstatus
932 932 $ cd badstatus
933 933 $ hg qinit
934 934 $ printf 'babar has no colon in this line\n' > .hg/patches/status
935 935 $ hg qser
936 936 malformated mq status line: ['babar has no colon in this line']
937 937 $ cd ..
938 938
939 939
940 940 test file addition in slow path
941 941
942 942 $ hg init slow
943 943 $ cd slow
944 944 $ hg qinit
945 945 $ echo foo > foo
946 946 $ hg add foo
947 947 $ hg ci -m 'add foo'
948 948 $ hg qnew bar
949 949 $ echo bar > bar
950 950 $ hg add bar
951 951 $ hg mv foo baz
952 952 $ hg qrefresh --git
953 953 $ hg up -C 0
954 954 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
955 955 $ echo >> foo
956 956 $ hg ci -m 'change foo'
957 957 created new head
958 958 $ hg up -C 1
959 959 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
960 960 $ hg qrefresh --git
961 961 $ cat .hg/patches/bar
962 962 diff --git a/bar b/bar
963 963 new file mode 100644
964 964 --- /dev/null
965 965 +++ b/bar
966 966 @@ -0,0 +1,1 @@
967 967 +bar
968 968 diff --git a/foo b/baz
969 969 rename from foo
970 970 rename to baz
971 971 $ hg log -v --template '{rev} {file_copies}\n' -r .
972 972 2 baz (foo)
973 973 $ hg qrefresh --git
974 974 $ cat .hg/patches/bar
975 975 diff --git a/bar b/bar
976 976 new file mode 100644
977 977 --- /dev/null
978 978 +++ b/bar
979 979 @@ -0,0 +1,1 @@
980 980 +bar
981 981 diff --git a/foo b/baz
982 982 rename from foo
983 983 rename to baz
984 984 $ hg log -v --template '{rev} {file_copies}\n' -r .
985 985 2 baz (foo)
986 986 $ hg qrefresh
987 987 $ grep 'diff --git' .hg/patches/bar
988 988 diff --git a/bar b/bar
989 989 diff --git a/foo b/baz
990 990
991 991
992 992 test file move chains in the slow path
993 993
994 994 $ hg up -C 1
995 995 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
996 996 $ echo >> foo
997 997 $ hg ci -m 'change foo again'
998 998 $ hg up -C 2
999 999 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
1000 1000 $ hg mv bar quux
1001 1001 $ hg mv baz bleh
1002 1002 $ hg qrefresh --git
1003 1003 $ cat .hg/patches/bar
1004 1004 diff --git a/foo b/bleh
1005 1005 rename from foo
1006 1006 rename to bleh
1007 1007 diff --git a/quux b/quux
1008 1008 new file mode 100644
1009 1009 --- /dev/null
1010 1010 +++ b/quux
1011 1011 @@ -0,0 +1,1 @@
1012 1012 +bar
1013 1013 $ hg log -v --template '{rev} {file_copies}\n' -r .
1014 1014 3 bleh (foo)
1015 1015 $ hg mv quux fred
1016 1016 $ hg mv bleh barney
1017 1017 $ hg qrefresh --git
1018 1018 $ cat .hg/patches/bar
1019 1019 diff --git a/foo b/barney
1020 1020 rename from foo
1021 1021 rename to barney
1022 1022 diff --git a/fred b/fred
1023 1023 new file mode 100644
1024 1024 --- /dev/null
1025 1025 +++ b/fred
1026 1026 @@ -0,0 +1,1 @@
1027 1027 +bar
1028 1028 $ hg log -v --template '{rev} {file_copies}\n' -r .
1029 1029 3 barney (foo)
1030 1030
1031 1031
1032 1032 refresh omitting an added file
1033 1033
1034 1034 $ hg qnew baz
1035 1035 $ echo newfile > newfile
1036 1036 $ hg add newfile
1037 1037 $ hg qrefresh
1038 1038 $ hg st -A newfile
1039 1039 C newfile
1040 1040 $ hg qrefresh -X newfile
1041 1041 $ hg st -A newfile
1042 1042 A newfile
1043 1043 $ hg revert newfile
1044 1044 $ rm newfile
1045 1045 $ hg qpop
1046 1046 popping baz
1047 1047 now at: bar
1048 1048 $ hg qdel baz
1049 1049
1050 1050
1051 1051 create a git patch
1052 1052
1053 1053 $ echo a > alexander
1054 1054 $ hg add alexander
1055 1055 $ hg qnew -f --git addalexander
1056 1056 $ grep diff .hg/patches/addalexander
1057 1057 diff --git a/alexander b/alexander
1058 1058
1059 1059
1060 1060 create a git binary patch
1061 1061
1062 1062 $ cat > writebin.py <<EOF
1063 1063 > import sys
1064 1064 > path = sys.argv[1]
1065 1065 > open(path, 'wb').write('BIN\x00ARY')
1066 1066 > EOF
1067 1067 $ python writebin.py bucephalus
1068 1068
1069 1069 $ python "$TESTDIR/md5sum.py" bucephalus
1070 1070 8ba2a2f3e77b55d03051ff9c24ad65e7 bucephalus
1071 1071 $ hg add bucephalus
1072 1072 $ hg qnew -f --git addbucephalus
1073 1073 $ grep diff .hg/patches/addbucephalus
1074 1074 diff --git a/bucephalus b/bucephalus
1075 1075
1076 1076
1077 1077 check binary patches can be popped and pushed
1078 1078
1079 1079 $ hg qpop
1080 1080 popping addbucephalus
1081 1081 now at: addalexander
1082 1082 $ test -f bucephalus && echo % bucephalus should not be there
1083 1083 [1]
1084 1084 $ hg qpush
1085 1085 applying addbucephalus
1086 1086 now at: addbucephalus
1087 1087 $ test -f bucephalus
1088 1088 $ python "$TESTDIR/md5sum.py" bucephalus
1089 1089 8ba2a2f3e77b55d03051ff9c24ad65e7 bucephalus
1090 1090
1091 1091
1092 1092
1093 1093 strip again
1094 1094
1095 1095 $ cd ..
1096 1096 $ hg init strip
1097 1097 $ cd strip
1098 1098 $ touch foo
1099 1099 $ hg add foo
1100 1100 $ hg ci -m 'add foo'
1101 1101 $ echo >> foo
1102 1102 $ hg ci -m 'change foo 1'
1103 1103 $ hg up -C 0
1104 1104 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1105 1105 $ echo 1 >> foo
1106 1106 $ hg ci -m 'change foo 2'
1107 1107 created new head
1108 1108 $ HGMERGE=true hg merge
1109 1109 merging foo
1110 1110 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
1111 1111 (branch merge, don't forget to commit)
1112 1112 $ hg ci -m merge
1113 1113 $ hg log
1114 1114 changeset: 3:99615015637b
1115 1115 tag: tip
1116 1116 parent: 2:20cbbe65cff7
1117 1117 parent: 1:d2871fc282d4
1118 1118 user: test
1119 1119 date: Thu Jan 01 00:00:00 1970 +0000
1120 1120 summary: merge
1121 1121
1122 1122 changeset: 2:20cbbe65cff7
1123 1123 parent: 0:53245c60e682
1124 1124 user: test
1125 1125 date: Thu Jan 01 00:00:00 1970 +0000
1126 1126 summary: change foo 2
1127 1127
1128 1128 changeset: 1:d2871fc282d4
1129 1129 user: test
1130 1130 date: Thu Jan 01 00:00:00 1970 +0000
1131 1131 summary: change foo 1
1132 1132
1133 1133 changeset: 0:53245c60e682
1134 1134 user: test
1135 1135 date: Thu Jan 01 00:00:00 1970 +0000
1136 1136 summary: add foo
1137 1137
1138 1138 $ hg strip 1
1139 1139 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1140 1140 saved backup bundle to $TESTTMP/b/strip/.hg/strip-backup/*-backup.hg (glob)
1141 1141 $ checkundo strip
1142 1142 $ hg log
1143 1143 changeset: 1:20cbbe65cff7
1144 1144 tag: tip
1145 1145 user: test
1146 1146 date: Thu Jan 01 00:00:00 1970 +0000
1147 1147 summary: change foo 2
1148 1148
1149 1149 changeset: 0:53245c60e682
1150 1150 user: test
1151 1151 date: Thu Jan 01 00:00:00 1970 +0000
1152 1152 summary: add foo
1153 1153
1154 1154 $ cd ..
1155 1155
1156 1156
1157 1157 qclone
1158 1158
1159 1159 $ qlog()
1160 1160 > {
1161 1161 > echo 'main repo:'
1162 1162 > hg log --template ' rev {rev}: {desc}\n'
1163 1163 > echo 'patch repo:'
1164 1164 > hg -R .hg/patches log --template ' rev {rev}: {desc}\n'
1165 1165 > }
1166 1166 $ hg init qclonesource
1167 1167 $ cd qclonesource
1168 1168 $ echo foo > foo
1169 1169 $ hg add foo
1170 1170 $ hg ci -m 'add foo'
1171 1171 $ hg qinit
1172 1172 $ hg qnew patch1
1173 1173 $ echo bar >> foo
1174 1174 $ hg qrefresh -m 'change foo'
1175 1175 $ cd ..
1176 1176
1177 1177
1178 1178 repo with unversioned patch dir
1179 1179
1180 1180 $ hg qclone qclonesource failure
1181 1181 abort: versioned patch repository not found (see init --mq)
1182 1182 [255]
1183 1183
1184 1184 $ cd qclonesource
1185 1185 $ hg qinit -c
1186 1186 adding .hg/patches/patch1
1187 1187 $ hg qci -m checkpoint
1188 1188 $ qlog
1189 1189 main repo:
1190 1190 rev 1: change foo
1191 1191 rev 0: add foo
1192 1192 patch repo:
1193 1193 rev 0: checkpoint
1194 1194 $ cd ..
1195 1195
1196 1196
1197 1197 repo with patches applied
1198 1198
1199 1199 $ hg qclone qclonesource qclonedest
1200 1200 updating to branch default
1201 1201 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
1202 1202 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1203 1203 $ cd qclonedest
1204 1204 $ qlog
1205 1205 main repo:
1206 1206 rev 0: add foo
1207 1207 patch repo:
1208 1208 rev 0: checkpoint
1209 1209 $ cd ..
1210 1210
1211 1211
1212 1212 repo with patches unapplied
1213 1213
1214 1214 $ cd qclonesource
1215 1215 $ hg qpop -a
1216 1216 popping patch1
1217 1217 patch queue now empty
1218 1218 $ qlog
1219 1219 main repo:
1220 1220 rev 0: add foo
1221 1221 patch repo:
1222 1222 rev 0: checkpoint
1223 1223 $ cd ..
1224 1224 $ hg qclone qclonesource qclonedest2
1225 1225 updating to branch default
1226 1226 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
1227 1227 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1228 1228 $ cd qclonedest2
1229 1229 $ qlog
1230 1230 main repo:
1231 1231 rev 0: add foo
1232 1232 patch repo:
1233 1233 rev 0: checkpoint
1234 1234 $ cd ..
1235 1235
1236 1236
1237 1237 Issue1033: test applying on an empty file
1238 1238
1239 1239 $ hg init empty
1240 1240 $ cd empty
1241 1241 $ touch a
1242 1242 $ hg ci -Am addempty
1243 1243 adding a
1244 1244 $ echo a > a
1245 1245 $ hg qnew -f -e changea
1246 1246 $ hg qpop
1247 1247 popping changea
1248 1248 patch queue now empty
1249 1249 $ hg qpush
1250 1250 applying changea
1251 1251 now at: changea
1252 1252 $ cd ..
1253 1253
1254 1254
1255 1255 test qpush with --force, issue1087
1256 1256
1257 1257 $ hg init forcepush
1258 1258 $ cd forcepush
1259 1259 $ echo hello > hello.txt
1260 1260 $ echo bye > bye.txt
1261 1261 $ hg ci -Ama
1262 1262 adding bye.txt
1263 1263 adding hello.txt
1264 1264 $ hg qnew -d '0 0' empty
1265 1265 $ hg qpop
1266 1266 popping empty
1267 1267 patch queue now empty
1268 1268 $ echo world >> hello.txt
1269 1269
1270 1270
1271 1271 qpush should fail, local changes
1272 1272
1273 1273 $ hg qpush
1274 1274 abort: local changes found, refresh first
1275 1275 [255]
1276 1276
1277 1277
1278 1278 apply force, should not discard changes with empty patch
1279 1279
1280 1280 $ hg qpush -f
1281 1281 applying empty
1282 1282 patch empty is empty
1283 1283 now at: empty
1284 1284 $ hg diff --config diff.nodates=True
1285 1285 diff -r bf5fc3f07a0a hello.txt
1286 1286 --- a/hello.txt
1287 1287 +++ b/hello.txt
1288 1288 @@ -1,1 +1,2 @@
1289 1289 hello
1290 1290 +world
1291 1291 $ hg qdiff --config diff.nodates=True
1292 1292 diff -r 9ecee4f634e3 hello.txt
1293 1293 --- a/hello.txt
1294 1294 +++ b/hello.txt
1295 1295 @@ -1,1 +1,2 @@
1296 1296 hello
1297 1297 +world
1298 1298 $ hg log -l1 -p
1299 1299 changeset: 1:bf5fc3f07a0a
1300 1300 tag: empty
1301 1301 tag: qbase
1302 1302 tag: qtip
1303 1303 tag: tip
1304 1304 user: test
1305 1305 date: Thu Jan 01 00:00:00 1970 +0000
1306 1306 summary: imported patch empty
1307 1307
1308 1308
1309 1309 $ hg qref -d '0 0'
1310 1310 $ hg qpop
1311 1311 popping empty
1312 1312 patch queue now empty
1313 1313 $ echo universe >> hello.txt
1314 1314 $ echo universe >> bye.txt
1315 1315
1316 1316
1317 1317 qpush should fail, local changes
1318 1318
1319 1319 $ hg qpush
1320 1320 abort: local changes found, refresh first
1321 1321 [255]
1322 1322
1323 1323
1324 1324 apply force, should discard changes in hello, but not bye
1325 1325
1326 1326 $ hg qpush -f
1327 1327 applying empty
1328 1328 now at: empty
1329 1329 $ hg st
1330 1330 M bye.txt
1331 1331 $ hg diff --config diff.nodates=True
1332 1332 diff -r ba252371dbc1 bye.txt
1333 1333 --- a/bye.txt
1334 1334 +++ b/bye.txt
1335 1335 @@ -1,1 +1,2 @@
1336 1336 bye
1337 1337 +universe
1338 1338 $ hg qdiff --config diff.nodates=True
1339 1339 diff -r 9ecee4f634e3 bye.txt
1340 1340 --- a/bye.txt
1341 1341 +++ b/bye.txt
1342 1342 @@ -1,1 +1,2 @@
1343 1343 bye
1344 1344 +universe
1345 1345 diff -r 9ecee4f634e3 hello.txt
1346 1346 --- a/hello.txt
1347 1347 +++ b/hello.txt
1348 1348 @@ -1,1 +1,3 @@
1349 1349 hello
1350 1350 +world
1351 1351 +universe
1352 1352
1353 1353
1354 1354 test popping revisions not in working dir ancestry
1355 1355
1356 1356 $ hg qseries -v
1357 1357 0 A empty
1358 1358 $ hg up qparent
1359 1359 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1360 1360 $ hg qpop
1361 1361 popping empty
1362 1362 patch queue now empty
1363 1363
1364 1364 $ cd ..
1365 1365 $ hg init deletion-order
1366 1366 $ cd deletion-order
1367 1367
1368 1368 $ touch a
1369 1369 $ hg ci -Aqm0
1370 1370
1371 1371 $ hg qnew rename-dir
1372 1372 $ hg rm a
1373 1373 $ hg qrefresh
1374 1374
1375 1375 $ mkdir a b
1376 1376 $ touch a/a b/b
1377 1377 $ hg add -q a b
1378 1378 $ hg qrefresh
1379 1379
1380 1380
1381 1381 test popping must remove files added in subdirectories first
1382 1382
1383 1383 $ hg qpop
1384 1384 popping rename-dir
1385 1385 patch queue now empty
1386 1386 $ cd ..
1387 1387
@@ -1,279 +1,292 b''
1 1 $ echo "[extensions]" >> $HGRCPATH
2 2 $ echo "color=" >> $HGRCPATH
3 3 $ echo "[color]" >> $HGRCPATH
4 4 $ echo "mode=ansi" >> $HGRCPATH
5 5
6 6 $ hg init repo1
7 7 $ cd repo1
8 8 $ mkdir a b a/1 b/1 b/2
9 9 $ touch in_root a/in_a b/in_b a/1/in_a_1 b/1/in_b_1 b/2/in_b_2
10 10
11 11 hg status in repo root:
12 12
13 13 $ hg status --color=always
14 14 \x1b[0;35;1;4m? a/1/in_a_1\x1b[0m (esc)
15 15 \x1b[0;35;1;4m? a/in_a\x1b[0m (esc)
16 16 \x1b[0;35;1;4m? b/1/in_b_1\x1b[0m (esc)
17 17 \x1b[0;35;1;4m? b/2/in_b_2\x1b[0m (esc)
18 18 \x1b[0;35;1;4m? b/in_b\x1b[0m (esc)
19 19 \x1b[0;35;1;4m? in_root\x1b[0m (esc)
20 20
21 21 hg status . in repo root:
22 22
23 23 $ hg status --color=always .
24 24 \x1b[0;35;1;4m? a/1/in_a_1\x1b[0m (esc)
25 25 \x1b[0;35;1;4m? a/in_a\x1b[0m (esc)
26 26 \x1b[0;35;1;4m? b/1/in_b_1\x1b[0m (esc)
27 27 \x1b[0;35;1;4m? b/2/in_b_2\x1b[0m (esc)
28 28 \x1b[0;35;1;4m? b/in_b\x1b[0m (esc)
29 29 \x1b[0;35;1;4m? in_root\x1b[0m (esc)
30 30
31 31 $ hg status --color=always --cwd a
32 32 \x1b[0;35;1;4m? a/1/in_a_1\x1b[0m (esc)
33 33 \x1b[0;35;1;4m? a/in_a\x1b[0m (esc)
34 34 \x1b[0;35;1;4m? b/1/in_b_1\x1b[0m (esc)
35 35 \x1b[0;35;1;4m? b/2/in_b_2\x1b[0m (esc)
36 36 \x1b[0;35;1;4m? b/in_b\x1b[0m (esc)
37 37 \x1b[0;35;1;4m? in_root\x1b[0m (esc)
38 38 $ hg status --color=always --cwd a .
39 39 \x1b[0;35;1;4m? 1/in_a_1\x1b[0m (esc)
40 40 \x1b[0;35;1;4m? in_a\x1b[0m (esc)
41 41 $ hg status --color=always --cwd a ..
42 42 \x1b[0;35;1;4m? 1/in_a_1\x1b[0m (esc)
43 43 \x1b[0;35;1;4m? in_a\x1b[0m (esc)
44 44 \x1b[0;35;1;4m? ../b/1/in_b_1\x1b[0m (esc)
45 45 \x1b[0;35;1;4m? ../b/2/in_b_2\x1b[0m (esc)
46 46 \x1b[0;35;1;4m? ../b/in_b\x1b[0m (esc)
47 47 \x1b[0;35;1;4m? ../in_root\x1b[0m (esc)
48 48
49 49 $ hg status --color=always --cwd b
50 50 \x1b[0;35;1;4m? a/1/in_a_1\x1b[0m (esc)
51 51 \x1b[0;35;1;4m? a/in_a\x1b[0m (esc)
52 52 \x1b[0;35;1;4m? b/1/in_b_1\x1b[0m (esc)
53 53 \x1b[0;35;1;4m? b/2/in_b_2\x1b[0m (esc)
54 54 \x1b[0;35;1;4m? b/in_b\x1b[0m (esc)
55 55 \x1b[0;35;1;4m? in_root\x1b[0m (esc)
56 56 $ hg status --color=always --cwd b .
57 57 \x1b[0;35;1;4m? 1/in_b_1\x1b[0m (esc)
58 58 \x1b[0;35;1;4m? 2/in_b_2\x1b[0m (esc)
59 59 \x1b[0;35;1;4m? in_b\x1b[0m (esc)
60 60 $ hg status --color=always --cwd b ..
61 61 \x1b[0;35;1;4m? ../a/1/in_a_1\x1b[0m (esc)
62 62 \x1b[0;35;1;4m? ../a/in_a\x1b[0m (esc)
63 63 \x1b[0;35;1;4m? 1/in_b_1\x1b[0m (esc)
64 64 \x1b[0;35;1;4m? 2/in_b_2\x1b[0m (esc)
65 65 \x1b[0;35;1;4m? in_b\x1b[0m (esc)
66 66 \x1b[0;35;1;4m? ../in_root\x1b[0m (esc)
67 67
68 68 $ hg status --color=always --cwd a/1
69 69 \x1b[0;35;1;4m? a/1/in_a_1\x1b[0m (esc)
70 70 \x1b[0;35;1;4m? a/in_a\x1b[0m (esc)
71 71 \x1b[0;35;1;4m? b/1/in_b_1\x1b[0m (esc)
72 72 \x1b[0;35;1;4m? b/2/in_b_2\x1b[0m (esc)
73 73 \x1b[0;35;1;4m? b/in_b\x1b[0m (esc)
74 74 \x1b[0;35;1;4m? in_root\x1b[0m (esc)
75 75 $ hg status --color=always --cwd a/1 .
76 76 \x1b[0;35;1;4m? in_a_1\x1b[0m (esc)
77 77 $ hg status --color=always --cwd a/1 ..
78 78 \x1b[0;35;1;4m? in_a_1\x1b[0m (esc)
79 79 \x1b[0;35;1;4m? ../in_a\x1b[0m (esc)
80 80
81 81 $ hg status --color=always --cwd b/1
82 82 \x1b[0;35;1;4m? a/1/in_a_1\x1b[0m (esc)
83 83 \x1b[0;35;1;4m? a/in_a\x1b[0m (esc)
84 84 \x1b[0;35;1;4m? b/1/in_b_1\x1b[0m (esc)
85 85 \x1b[0;35;1;4m? b/2/in_b_2\x1b[0m (esc)
86 86 \x1b[0;35;1;4m? b/in_b\x1b[0m (esc)
87 87 \x1b[0;35;1;4m? in_root\x1b[0m (esc)
88 88 $ hg status --color=always --cwd b/1 .
89 89 \x1b[0;35;1;4m? in_b_1\x1b[0m (esc)
90 90 $ hg status --color=always --cwd b/1 ..
91 91 \x1b[0;35;1;4m? in_b_1\x1b[0m (esc)
92 92 \x1b[0;35;1;4m? ../2/in_b_2\x1b[0m (esc)
93 93 \x1b[0;35;1;4m? ../in_b\x1b[0m (esc)
94 94
95 95 $ hg status --color=always --cwd b/2
96 96 \x1b[0;35;1;4m? a/1/in_a_1\x1b[0m (esc)
97 97 \x1b[0;35;1;4m? a/in_a\x1b[0m (esc)
98 98 \x1b[0;35;1;4m? b/1/in_b_1\x1b[0m (esc)
99 99 \x1b[0;35;1;4m? b/2/in_b_2\x1b[0m (esc)
100 100 \x1b[0;35;1;4m? b/in_b\x1b[0m (esc)
101 101 \x1b[0;35;1;4m? in_root\x1b[0m (esc)
102 102 $ hg status --color=always --cwd b/2 .
103 103 \x1b[0;35;1;4m? in_b_2\x1b[0m (esc)
104 104 $ hg status --color=always --cwd b/2 ..
105 105 \x1b[0;35;1;4m? ../1/in_b_1\x1b[0m (esc)
106 106 \x1b[0;35;1;4m? in_b_2\x1b[0m (esc)
107 107 \x1b[0;35;1;4m? ../in_b\x1b[0m (esc)
108 108 $ cd ..
109 109
110 110 $ hg init repo2
111 111 $ cd repo2
112 112 $ touch modified removed deleted ignored
113 113 $ echo "^ignored$" > .hgignore
114 114 $ hg ci -A -m 'initial checkin'
115 115 adding .hgignore
116 116 adding deleted
117 117 adding modified
118 118 adding removed
119 119 $ touch modified added unknown ignored
120 120 $ hg add added
121 121 $ hg remove removed
122 122 $ rm deleted
123 123
124 124 hg status:
125 125
126 126 $ hg status --color=always
127 127 \x1b[0;32;1mA added\x1b[0m (esc)
128 128 \x1b[0;31;1mR removed\x1b[0m (esc)
129 129 \x1b[0;36;1;4m! deleted\x1b[0m (esc)
130 130 \x1b[0;35;1;4m? unknown\x1b[0m (esc)
131 131
132 132 hg status modified added removed deleted unknown never-existed ignored:
133 133
134 134 $ hg status --color=always modified added removed deleted unknown never-existed ignored
135 135 never-existed: No such file or directory
136 136 \x1b[0;32;1mA added\x1b[0m (esc)
137 137 \x1b[0;31;1mR removed\x1b[0m (esc)
138 138 \x1b[0;36;1;4m! deleted\x1b[0m (esc)
139 139 \x1b[0;35;1;4m? unknown\x1b[0m (esc)
140 140
141 141 $ hg copy modified copied
142 142
143 143 hg status -C:
144 144
145 145 $ hg status --color=always -C
146 146 \x1b[0;32;1mA added\x1b[0m (esc)
147 147 \x1b[0;32;1mA copied\x1b[0m (esc)
148 148 \x1b[0;0m modified\x1b[0m (esc)
149 149 \x1b[0;31;1mR removed\x1b[0m (esc)
150 150 \x1b[0;36;1;4m! deleted\x1b[0m (esc)
151 151 \x1b[0;35;1;4m? unknown\x1b[0m (esc)
152 152
153 153 hg status -A:
154 154
155 155 $ hg status --color=always -A
156 156 \x1b[0;32;1mA added\x1b[0m (esc)
157 157 \x1b[0;32;1mA copied\x1b[0m (esc)
158 158 \x1b[0;0m modified\x1b[0m (esc)
159 159 \x1b[0;31;1mR removed\x1b[0m (esc)
160 160 \x1b[0;36;1;4m! deleted\x1b[0m (esc)
161 161 \x1b[0;35;1;4m? unknown\x1b[0m (esc)
162 162 \x1b[0;30;1mI ignored\x1b[0m (esc)
163 163 \x1b[0;0mC .hgignore\x1b[0m (esc)
164 164 \x1b[0;0mC modified\x1b[0m (esc)
165 165
166 hg status -A (with terminfo color):
167
168 $ TERM=xterm hg status --config color.mode=terminfo --color=always -A
169 \x1b(B\x1b[m\x1b[32m\x1b[1mA added\x1b(B\x1b[m (esc)
170 \x1b(B\x1b[m\x1b[32m\x1b[1mA copied\x1b(B\x1b[m (esc)
171 \x1b(B\x1b[m\x1b(B\x1b[m modified\x1b(B\x1b[m (esc)
172 \x1b(B\x1b[m\x1b[31m\x1b[1mR removed\x1b(B\x1b[m (esc)
173 \x1b(B\x1b[m\x1b[36m\x1b[1m\x1b[4m! deleted\x1b(B\x1b[m (esc)
174 \x1b(B\x1b[m\x1b[35m\x1b[1m\x1b[4m? unknown\x1b(B\x1b[m (esc)
175 \x1b(B\x1b[m\x1b[30m\x1b[1mI ignored\x1b(B\x1b[m (esc)
176 \x1b(B\x1b[m\x1b(B\x1b[mC .hgignore\x1b(B\x1b[m (esc)
177 \x1b(B\x1b[m\x1b(B\x1b[mC modified\x1b(B\x1b[m (esc)
178
166 179
167 180 $ echo "^ignoreddir$" > .hgignore
168 181 $ mkdir ignoreddir
169 182 $ touch ignoreddir/file
170 183
171 184 hg status ignoreddir/file:
172 185
173 186 $ hg status --color=always ignoreddir/file
174 187
175 188 hg status -i ignoreddir/file:
176 189
177 190 $ hg status --color=always -i ignoreddir/file
178 191 \x1b[0;30;1mI ignoreddir/file\x1b[0m (esc)
179 192 $ cd ..
180 193
181 194 check 'status -q' and some combinations
182 195
183 196 $ hg init repo3
184 197 $ cd repo3
185 198 $ touch modified removed deleted ignored
186 199 $ echo "^ignored$" > .hgignore
187 200 $ hg commit -A -m 'initial checkin'
188 201 adding .hgignore
189 202 adding deleted
190 203 adding modified
191 204 adding removed
192 205 $ touch added unknown ignored
193 206 $ hg add added
194 207 $ echo "test" >> modified
195 208 $ hg remove removed
196 209 $ rm deleted
197 210 $ hg copy modified copied
198 211
199 212 test unknown color
200 213
201 214 $ hg --config color.status.modified=periwinkle status --color=always
202 215 ignoring unknown color/effect 'periwinkle' (configured in color.status.modified)
203 216 M modified
204 217 \x1b[0;32;1mA added\x1b[0m (esc)
205 218 \x1b[0;32;1mA copied\x1b[0m (esc)
206 219 \x1b[0;31;1mR removed\x1b[0m (esc)
207 220 \x1b[0;36;1;4m! deleted\x1b[0m (esc)
208 221 \x1b[0;35;1;4m? unknown\x1b[0m (esc)
209 222
210 223 Run status with 2 different flags.
211 224 Check if result is the same or different.
212 225 If result is not as expected, raise error
213 226
214 227 $ assert() {
215 228 > hg status --color=always $1 > ../a
216 229 > hg status --color=always $2 > ../b
217 230 > if diff ../a ../b > /dev/null; then
218 231 > out=0
219 232 > else
220 233 > out=1
221 234 > fi
222 235 > if [ $3 -eq 0 ]; then
223 236 > df="same"
224 237 > else
225 238 > df="different"
226 239 > fi
227 240 > if [ $out -ne $3 ]; then
228 241 > echo "Error on $1 and $2, should be $df."
229 242 > fi
230 243 > }
231 244
232 245 assert flag1 flag2 [0-same | 1-different]
233 246
234 247 $ assert "-q" "-mard" 0
235 248 $ assert "-A" "-marduicC" 0
236 249 $ assert "-qA" "-mardcC" 0
237 250 $ assert "-qAui" "-A" 0
238 251 $ assert "-qAu" "-marducC" 0
239 252 $ assert "-qAi" "-mardicC" 0
240 253 $ assert "-qu" "-u" 0
241 254 $ assert "-q" "-u" 1
242 255 $ assert "-m" "-a" 1
243 256 $ assert "-r" "-d" 1
244 257 $ cd ..
245 258
246 259 test 'resolve -l'
247 260
248 261 $ hg init repo4
249 262 $ cd repo4
250 263 $ echo "file a" > a
251 264 $ echo "file b" > b
252 265 $ hg add a b
253 266 $ hg commit -m "initial"
254 267 $ echo "file a change 1" > a
255 268 $ echo "file b change 1" > b
256 269 $ hg commit -m "head 1"
257 270 $ hg update 0
258 271 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
259 272 $ echo "file a change 2" > a
260 273 $ echo "file b change 2" > b
261 274 $ hg commit -m "head 2"
262 275 created new head
263 276 $ hg merge
264 277 merging a
265 278 warning: conflicts during merge.
266 279 merging a failed!
267 280 merging b
268 281 warning: conflicts during merge.
269 282 merging b failed!
270 283 0 files updated, 0 files merged, 0 files removed, 2 files unresolved
271 284 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
272 285 [1]
273 286 $ hg resolve -m b
274 287
275 288 hg resolve with one unresolved, one resolved:
276 289
277 290 $ hg resolve --color=always -l
278 291 \x1b[0;31;1mU a\x1b[0m (esc)
279 292 \x1b[0;32;1mR b\x1b[0m (esc)
General Comments 0
You need to be logged in to leave comments. Login now