##// END OF EJS Templates
color: enable branches support...
Jeremy Whitlock -
r11969:52ec5c81 default
parent child Browse files
Show More
@@ -1,287 +1,296 b''
1 # color.py color output for the status and qseries commands
1 # color.py color output for the status and qseries commands
2 #
2 #
3 # Copyright (C) 2007 Kevin Christen <kevin.christen@gmail.com>
3 # Copyright (C) 2007 Kevin Christen <kevin.christen@gmail.com>
4 #
4 #
5 # This program is free software; you can redistribute it and/or modify it
5 # This program is free software; you can redistribute it and/or modify it
6 # under the terms of the GNU General Public License as published by the
6 # under the terms of the GNU General Public License as published by the
7 # Free Software Foundation; either version 2 of the License, or (at your
7 # Free Software Foundation; either version 2 of the License, or (at your
8 # option) any later version.
8 # option) any later version.
9 #
9 #
10 # This program is distributed in the hope that it will be useful, but
10 # This program is distributed in the hope that it will be useful, but
11 # WITHOUT ANY WARRANTY; without even the implied warranty of
11 # WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
13 # Public License for more details.
13 # Public License for more details.
14 #
14 #
15 # You should have received a copy of the GNU General Public License along
15 # You should have received a copy of the GNU General Public License along
16 # with this program; if not, write to the Free Software Foundation, Inc.,
16 # with this program; if not, write to the Free Software Foundation, Inc.,
17 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18
18
19 '''colorize output from some commands
19 '''colorize output from some commands
20
20
21 This extension modifies the status and resolve commands to add color to their
21 This extension modifies the status and resolve commands to add color to their
22 output to reflect file status, the qseries command to add color to reflect
22 output to reflect file status, the qseries command to add color to reflect
23 patch status (applied, unapplied, missing), and to diff-related
23 patch status (applied, unapplied, missing), and to diff-related
24 commands to highlight additions, removals, diff headers, and trailing
24 commands to highlight additions, removals, diff headers, and trailing
25 whitespace.
25 whitespace.
26
26
27 Other effects in addition to color, like bold and underlined text, are
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. Effects are rendered with the ECMA-48 SGR control
29 function (aka ANSI escape codes). This module also provides the
29 function (aka ANSI escape codes). This module also provides the
30 render_text function, which can be used to add effects to any text.
30 render_text function, which can be used to add effects to any text.
31
31
32 Default effects may be overridden from the .hgrc file::
32 Default effects may be overridden from the .hgrc file::
33
33
34 [color]
34 [color]
35 status.modified = blue bold underline red_background
35 status.modified = blue bold underline red_background
36 status.added = green bold
36 status.added = green bold
37 status.removed = red bold blue_background
37 status.removed = red bold blue_background
38 status.deleted = cyan bold underline
38 status.deleted = cyan bold underline
39 status.unknown = magenta bold underline
39 status.unknown = magenta bold underline
40 status.ignored = black bold
40 status.ignored = black bold
41
41
42 # 'none' turns off all effects
42 # 'none' turns off all effects
43 status.clean = none
43 status.clean = none
44 status.copied = none
44 status.copied = none
45
45
46 qseries.applied = blue bold underline
46 qseries.applied = blue bold underline
47 qseries.unapplied = black bold
47 qseries.unapplied = black bold
48 qseries.missing = red bold
48 qseries.missing = red bold
49
49
50 diff.diffline = bold
50 diff.diffline = bold
51 diff.extended = cyan bold
51 diff.extended = cyan bold
52 diff.file_a = red bold
52 diff.file_a = red bold
53 diff.file_b = green bold
53 diff.file_b = green bold
54 diff.hunk = magenta
54 diff.hunk = magenta
55 diff.deleted = red
55 diff.deleted = red
56 diff.inserted = green
56 diff.inserted = green
57 diff.changed = white
57 diff.changed = white
58 diff.trailingwhitespace = bold red_background
58 diff.trailingwhitespace = bold red_background
59
59
60 resolve.unresolved = red bold
60 resolve.unresolved = red bold
61 resolve.resolved = green bold
61 resolve.resolved = green bold
62
62
63 bookmarks.current = green
63 bookmarks.current = green
64
64
65 branches.active = none
66 branches.closed = black bold
67 branches.current = green
68 branches.inactive = none
69
65 The color extension will try to detect whether to use ANSI codes or
70 The color extension will try to detect whether to use ANSI codes or
66 Win32 console APIs, unless it is made explicit::
71 Win32 console APIs, unless it is made explicit::
67
72
68 [color]
73 [color]
69 mode = ansi
74 mode = ansi
70
75
71 Any value other than 'ansi', 'win32', or 'auto' will disable color.
76 Any value other than 'ansi', 'win32', or 'auto' will disable color.
72
77
73 '''
78 '''
74
79
75 import os, sys
80 import os, sys
76
81
77 from mercurial import commands, dispatch, extensions, ui as uimod
82 from mercurial import commands, dispatch, extensions, ui as uimod
78 from mercurial.i18n import _
83 from mercurial.i18n import _
79
84
80 # start and stop parameters for effects
85 # start and stop parameters for effects
81 _effects = {'none': 0, 'black': 30, 'red': 31, 'green': 32, 'yellow': 33,
86 _effects = {'none': 0, 'black': 30, 'red': 31, 'green': 32, 'yellow': 33,
82 'blue': 34, 'magenta': 35, 'cyan': 36, 'white': 37, 'bold': 1,
87 'blue': 34, 'magenta': 35, 'cyan': 36, 'white': 37, 'bold': 1,
83 'italic': 3, 'underline': 4, 'inverse': 7,
88 'italic': 3, 'underline': 4, 'inverse': 7,
84 'black_background': 40, 'red_background': 41,
89 'black_background': 40, 'red_background': 41,
85 'green_background': 42, 'yellow_background': 43,
90 'green_background': 42, 'yellow_background': 43,
86 'blue_background': 44, 'purple_background': 45,
91 'blue_background': 44, 'purple_background': 45,
87 'cyan_background': 46, 'white_background': 47}
92 'cyan_background': 46, 'white_background': 47}
88
93
89 _styles = {'grep.match': 'red bold',
94 _styles = {'grep.match': 'red bold',
95 'branches.active': 'none',
96 'branches.closed': 'black bold',
97 'branches.current': 'green',
98 'branches.inactive': 'none',
90 'diff.changed': 'white',
99 'diff.changed': 'white',
91 'diff.deleted': 'red',
100 'diff.deleted': 'red',
92 'diff.diffline': 'bold',
101 'diff.diffline': 'bold',
93 'diff.extended': 'cyan bold',
102 'diff.extended': 'cyan bold',
94 'diff.file_a': 'red bold',
103 'diff.file_a': 'red bold',
95 'diff.file_b': 'green bold',
104 'diff.file_b': 'green bold',
96 'diff.hunk': 'magenta',
105 'diff.hunk': 'magenta',
97 'diff.inserted': 'green',
106 'diff.inserted': 'green',
98 'diff.trailingwhitespace': 'bold red_background',
107 'diff.trailingwhitespace': 'bold red_background',
99 'diffstat.deleted': 'red',
108 'diffstat.deleted': 'red',
100 'diffstat.inserted': 'green',
109 'diffstat.inserted': 'green',
101 'log.changeset': 'yellow',
110 'log.changeset': 'yellow',
102 'resolve.resolved': 'green bold',
111 'resolve.resolved': 'green bold',
103 'resolve.unresolved': 'red bold',
112 'resolve.unresolved': 'red bold',
104 'status.added': 'green bold',
113 'status.added': 'green bold',
105 'status.clean': 'none',
114 'status.clean': 'none',
106 'status.copied': 'none',
115 'status.copied': 'none',
107 'status.deleted': 'cyan bold underline',
116 'status.deleted': 'cyan bold underline',
108 'status.ignored': 'black bold',
117 'status.ignored': 'black bold',
109 'status.modified': 'blue bold',
118 'status.modified': 'blue bold',
110 'status.removed': 'red bold',
119 'status.removed': 'red bold',
111 'status.unknown': 'magenta bold underline'}
120 'status.unknown': 'magenta bold underline'}
112
121
113
122
114 def render_effects(text, effects):
123 def render_effects(text, effects):
115 'Wrap text in commands to turn on each effect.'
124 'Wrap text in commands to turn on each effect.'
116 if not text:
125 if not text:
117 return text
126 return text
118 start = [str(_effects[e]) for e in ['none'] + effects.split()]
127 start = [str(_effects[e]) for e in ['none'] + effects.split()]
119 start = '\033[' + ';'.join(start) + 'm'
128 start = '\033[' + ';'.join(start) + 'm'
120 stop = '\033[' + str(_effects['none']) + 'm'
129 stop = '\033[' + str(_effects['none']) + 'm'
121 return ''.join([start, text, stop])
130 return ''.join([start, text, stop])
122
131
123 def extstyles():
132 def extstyles():
124 for name, ext in extensions.extensions():
133 for name, ext in extensions.extensions():
125 _styles.update(getattr(ext, 'colortable', {}))
134 _styles.update(getattr(ext, 'colortable', {}))
126
135
127 def configstyles(ui):
136 def configstyles(ui):
128 for status, cfgeffects in ui.configitems('color'):
137 for status, cfgeffects in ui.configitems('color'):
129 if '.' not in status:
138 if '.' not in status:
130 continue
139 continue
131 cfgeffects = ui.configlist('color', status)
140 cfgeffects = ui.configlist('color', status)
132 if cfgeffects:
141 if cfgeffects:
133 good = []
142 good = []
134 for e in cfgeffects:
143 for e in cfgeffects:
135 if e in _effects:
144 if e in _effects:
136 good.append(e)
145 good.append(e)
137 else:
146 else:
138 ui.warn(_("ignoring unknown color/effect %r "
147 ui.warn(_("ignoring unknown color/effect %r "
139 "(configured in color.%s)\n")
148 "(configured in color.%s)\n")
140 % (e, status))
149 % (e, status))
141 _styles[status] = ' '.join(good)
150 _styles[status] = ' '.join(good)
142
151
143 class colorui(uimod.ui):
152 class colorui(uimod.ui):
144 def popbuffer(self, labeled=False):
153 def popbuffer(self, labeled=False):
145 if labeled:
154 if labeled:
146 return ''.join(self.label(a, label) for a, label
155 return ''.join(self.label(a, label) for a, label
147 in self._buffers.pop())
156 in self._buffers.pop())
148 return ''.join(a for a, label in self._buffers.pop())
157 return ''.join(a for a, label in self._buffers.pop())
149
158
150 _colormode = 'ansi'
159 _colormode = 'ansi'
151 def write(self, *args, **opts):
160 def write(self, *args, **opts):
152 label = opts.get('label', '')
161 label = opts.get('label', '')
153 if self._buffers:
162 if self._buffers:
154 self._buffers[-1].extend([(str(a), label) for a in args])
163 self._buffers[-1].extend([(str(a), label) for a in args])
155 elif self._colormode == 'win32':
164 elif self._colormode == 'win32':
156 for a in args:
165 for a in args:
157 win32print(a, super(colorui, self).write, **opts)
166 win32print(a, super(colorui, self).write, **opts)
158 else:
167 else:
159 return super(colorui, self).write(
168 return super(colorui, self).write(
160 *[self.label(str(a), label) for a in args], **opts)
169 *[self.label(str(a), label) for a in args], **opts)
161
170
162 def write_err(self, *args, **opts):
171 def write_err(self, *args, **opts):
163 label = opts.get('label', '')
172 label = opts.get('label', '')
164 if self._colormode == 'win32':
173 if self._colormode == 'win32':
165 for a in args:
174 for a in args:
166 win32print(a, super(colorui, self).write_err, **opts)
175 win32print(a, super(colorui, self).write_err, **opts)
167 else:
176 else:
168 return super(colorui, self).write_err(
177 return super(colorui, self).write_err(
169 *[self.label(str(a), label) for a in args], **opts)
178 *[self.label(str(a), label) for a in args], **opts)
170
179
171 def label(self, msg, label):
180 def label(self, msg, label):
172 effects = []
181 effects = []
173 for l in label.split():
182 for l in label.split():
174 s = _styles.get(l, '')
183 s = _styles.get(l, '')
175 if s:
184 if s:
176 effects.append(s)
185 effects.append(s)
177 effects = ''.join(effects)
186 effects = ''.join(effects)
178 if effects:
187 if effects:
179 return '\n'.join([render_effects(s, effects)
188 return '\n'.join([render_effects(s, effects)
180 for s in msg.split('\n')])
189 for s in msg.split('\n')])
181 return msg
190 return msg
182
191
183
192
184 def uisetup(ui):
193 def uisetup(ui):
185 if ui.plain():
194 if ui.plain():
186 return
195 return
187 mode = ui.config('color', 'mode', 'auto')
196 mode = ui.config('color', 'mode', 'auto')
188 if mode == 'auto':
197 if mode == 'auto':
189 if os.name == 'nt' and 'TERM' not in os.environ:
198 if os.name == 'nt' and 'TERM' not in os.environ:
190 # looks line a cmd.exe console, use win32 API or nothing
199 # looks line a cmd.exe console, use win32 API or nothing
191 mode = w32effects and 'win32' or 'none'
200 mode = w32effects and 'win32' or 'none'
192 else:
201 else:
193 mode = 'ansi'
202 mode = 'ansi'
194 if mode == 'win32':
203 if mode == 'win32':
195 if w32effects is None:
204 if w32effects is None:
196 # only warn if color.mode is explicitly set to win32
205 # only warn if color.mode is explicitly set to win32
197 ui.warn(_('win32console not found, please install pywin32\n'))
206 ui.warn(_('win32console not found, please install pywin32\n'))
198 return
207 return
199 _effects.update(w32effects)
208 _effects.update(w32effects)
200 elif mode != 'ansi':
209 elif mode != 'ansi':
201 return
210 return
202 def colorcmd(orig, ui_, opts, cmd, cmdfunc):
211 def colorcmd(orig, ui_, opts, cmd, cmdfunc):
203 if (opts['color'] == 'always' or
212 if (opts['color'] == 'always' or
204 (opts['color'] == 'auto' and (os.environ.get('TERM') != 'dumb'
213 (opts['color'] == 'auto' and (os.environ.get('TERM') != 'dumb'
205 and ui_.formatted()))):
214 and ui_.formatted()))):
206 colorui._colormode = mode
215 colorui._colormode = mode
207 colorui.__bases__ = (ui_.__class__,)
216 colorui.__bases__ = (ui_.__class__,)
208 ui_.__class__ = colorui
217 ui_.__class__ = colorui
209 extstyles()
218 extstyles()
210 configstyles(ui_)
219 configstyles(ui_)
211 return orig(ui_, opts, cmd, cmdfunc)
220 return orig(ui_, opts, cmd, cmdfunc)
212 extensions.wrapfunction(dispatch, '_runcommand', colorcmd)
221 extensions.wrapfunction(dispatch, '_runcommand', colorcmd)
213
222
214 commands.globalopts.append(('', 'color', 'auto',
223 commands.globalopts.append(('', 'color', 'auto',
215 _("when to colorize (always, auto, or never)"),
224 _("when to colorize (always, auto, or never)"),
216 _('TYPE')))
225 _('TYPE')))
217
226
218 try:
227 try:
219 import re, pywintypes, win32console as win32c
228 import re, pywintypes, win32console as win32c
220
229
221 # http://msdn.microsoft.com/en-us/library/ms682088%28VS.85%29.aspx
230 # http://msdn.microsoft.com/en-us/library/ms682088%28VS.85%29.aspx
222 w32effects = {
231 w32effects = {
223 'none': 0,
232 'none': 0,
224 'black': 0,
233 'black': 0,
225 'red': win32c.FOREGROUND_RED,
234 'red': win32c.FOREGROUND_RED,
226 'green': win32c.FOREGROUND_GREEN,
235 'green': win32c.FOREGROUND_GREEN,
227 'yellow': win32c.FOREGROUND_RED | win32c.FOREGROUND_GREEN,
236 'yellow': win32c.FOREGROUND_RED | win32c.FOREGROUND_GREEN,
228 'blue': win32c.FOREGROUND_BLUE,
237 'blue': win32c.FOREGROUND_BLUE,
229 'magenta': win32c.FOREGROUND_BLUE | win32c.FOREGROUND_RED,
238 'magenta': win32c.FOREGROUND_BLUE | win32c.FOREGROUND_RED,
230 'cyan': win32c.FOREGROUND_BLUE | win32c.FOREGROUND_GREEN,
239 'cyan': win32c.FOREGROUND_BLUE | win32c.FOREGROUND_GREEN,
231 'white': (win32c.FOREGROUND_RED | win32c.FOREGROUND_GREEN |
240 'white': (win32c.FOREGROUND_RED | win32c.FOREGROUND_GREEN |
232 win32c.FOREGROUND_BLUE),
241 win32c.FOREGROUND_BLUE),
233 'bold': win32c.FOREGROUND_INTENSITY,
242 'bold': win32c.FOREGROUND_INTENSITY,
234 'black_background': 0,
243 'black_background': 0,
235 'red_background': win32c.BACKGROUND_RED,
244 'red_background': win32c.BACKGROUND_RED,
236 'green_background': win32c.BACKGROUND_GREEN,
245 'green_background': win32c.BACKGROUND_GREEN,
237 'yellow_background': win32c.BACKGROUND_RED | win32c.BACKGROUND_GREEN,
246 'yellow_background': win32c.BACKGROUND_RED | win32c.BACKGROUND_GREEN,
238 'blue_background': win32c.BACKGROUND_BLUE,
247 'blue_background': win32c.BACKGROUND_BLUE,
239 'purple_background': win32c.BACKGROUND_BLUE | win32c.BACKGROUND_RED,
248 'purple_background': win32c.BACKGROUND_BLUE | win32c.BACKGROUND_RED,
240 'cyan_background': win32c.BACKGROUND_BLUE | win32c.BACKGROUND_GREEN,
249 'cyan_background': win32c.BACKGROUND_BLUE | win32c.BACKGROUND_GREEN,
241 'white_background': (win32c.BACKGROUND_RED | win32c.BACKGROUND_GREEN |
250 'white_background': (win32c.BACKGROUND_RED | win32c.BACKGROUND_GREEN |
242 win32c.BACKGROUND_BLUE),
251 win32c.BACKGROUND_BLUE),
243 'bold_background': win32c.BACKGROUND_INTENSITY,
252 'bold_background': win32c.BACKGROUND_INTENSITY,
244 'underline': win32c.COMMON_LVB_UNDERSCORE, # double-byte charsets only
253 'underline': win32c.COMMON_LVB_UNDERSCORE, # double-byte charsets only
245 'inverse': win32c.COMMON_LVB_REVERSE_VIDEO, # double-byte charsets only
254 'inverse': win32c.COMMON_LVB_REVERSE_VIDEO, # double-byte charsets only
246 }
255 }
247
256
248 stdout = win32c.GetStdHandle(win32c.STD_OUTPUT_HANDLE)
257 stdout = win32c.GetStdHandle(win32c.STD_OUTPUT_HANDLE)
249 try:
258 try:
250 origattr = stdout.GetConsoleScreenBufferInfo()['Attributes']
259 origattr = stdout.GetConsoleScreenBufferInfo()['Attributes']
251 except pywintypes.error:
260 except pywintypes.error:
252 # stdout may be defined but not support
261 # stdout may be defined but not support
253 # GetConsoleScreenBufferInfo(), when called from subprocess or
262 # GetConsoleScreenBufferInfo(), when called from subprocess or
254 # redirected.
263 # redirected.
255 raise ImportError()
264 raise ImportError()
256 ansire = re.compile('\033\[([^m]*)m([^\033]*)(.*)', re.MULTILINE | re.DOTALL)
265 ansire = re.compile('\033\[([^m]*)m([^\033]*)(.*)', re.MULTILINE | re.DOTALL)
257
266
258 def win32print(text, orig, **opts):
267 def win32print(text, orig, **opts):
259 label = opts.get('label', '')
268 label = opts.get('label', '')
260 attr = 0
269 attr = 0
261
270
262 # determine console attributes based on labels
271 # determine console attributes based on labels
263 for l in label.split():
272 for l in label.split():
264 style = _styles.get(l, '')
273 style = _styles.get(l, '')
265 for effect in style.split():
274 for effect in style.split():
266 attr |= w32effects[effect]
275 attr |= w32effects[effect]
267
276
268 # hack to ensure regexp finds data
277 # hack to ensure regexp finds data
269 if not text.startswith('\033['):
278 if not text.startswith('\033['):
270 text = '\033[m' + text
279 text = '\033[m' + text
271
280
272 # Look for ANSI-like codes embedded in text
281 # Look for ANSI-like codes embedded in text
273 m = re.match(ansire, text)
282 m = re.match(ansire, text)
274 while m:
283 while m:
275 for sattr in m.group(1).split(';'):
284 for sattr in m.group(1).split(';'):
276 if sattr:
285 if sattr:
277 val = int(sattr)
286 val = int(sattr)
278 attr = val and attr|val or 0
287 attr = val and attr|val or 0
279 stdout.SetConsoleTextAttribute(attr or origattr)
288 stdout.SetConsoleTextAttribute(attr or origattr)
280 orig(m.group(2), **opts)
289 orig(m.group(2), **opts)
281 m = re.match(ansire, m.group(3))
290 m = re.match(ansire, m.group(3))
282
291
283 # Explicity reset original attributes
292 # Explicity reset original attributes
284 stdout.SetConsoleTextAttribute(origattr)
293 stdout.SetConsoleTextAttribute(origattr)
285
294
286 except ImportError:
295 except ImportError:
287 w32effects = None
296 w32effects = None
@@ -1,4468 +1,4474 b''
1 # commands.py - command processing for mercurial
1 # commands.py - command processing for mercurial
2 #
2 #
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 from node import hex, nullid, nullrev, short
8 from node import hex, nullid, nullrev, short
9 from lock import release
9 from lock import release
10 from i18n import _, gettext
10 from i18n import _, gettext
11 import os, re, sys, difflib, time, tempfile
11 import os, re, sys, difflib, time, tempfile
12 import hg, util, revlog, bundlerepo, extensions, copies, error
12 import hg, util, revlog, bundlerepo, extensions, copies, error
13 import patch, help, mdiff, url, encoding, templatekw, discovery
13 import patch, help, mdiff, url, encoding, templatekw, discovery
14 import archival, changegroup, cmdutil, sshserver, hbisect, hgweb, hgweb.server
14 import archival, changegroup, cmdutil, sshserver, hbisect, hgweb, hgweb.server
15 import merge as mergemod
15 import merge as mergemod
16 import minirst, revset
16 import minirst, revset
17 import dagparser
17 import dagparser
18
18
19 # Commands start here, listed alphabetically
19 # Commands start here, listed alphabetically
20
20
21 def add(ui, repo, *pats, **opts):
21 def add(ui, repo, *pats, **opts):
22 """add the specified files on the next commit
22 """add the specified files on the next commit
23
23
24 Schedule files to be version controlled and added to the
24 Schedule files to be version controlled and added to the
25 repository.
25 repository.
26
26
27 The files will be added to the repository at the next commit. To
27 The files will be added to the repository at the next commit. To
28 undo an add before that, see :hg:`forget`.
28 undo an add before that, see :hg:`forget`.
29
29
30 If no names are given, add all files to the repository.
30 If no names are given, add all files to the repository.
31
31
32 .. container:: verbose
32 .. container:: verbose
33
33
34 An example showing how new (unknown) files are added
34 An example showing how new (unknown) files are added
35 automatically by :hg:`add`::
35 automatically by :hg:`add`::
36
36
37 $ ls
37 $ ls
38 foo.c
38 foo.c
39 $ hg status
39 $ hg status
40 ? foo.c
40 ? foo.c
41 $ hg add
41 $ hg add
42 adding foo.c
42 adding foo.c
43 $ hg status
43 $ hg status
44 A foo.c
44 A foo.c
45
45
46 Returns 0 if all files are successfully added.
46 Returns 0 if all files are successfully added.
47 """
47 """
48
48
49 bad = []
49 bad = []
50 names = []
50 names = []
51 m = cmdutil.match(repo, pats, opts)
51 m = cmdutil.match(repo, pats, opts)
52 oldbad = m.bad
52 oldbad = m.bad
53 m.bad = lambda x, y: bad.append(x) or oldbad(x, y)
53 m.bad = lambda x, y: bad.append(x) or oldbad(x, y)
54
54
55 for f in repo.walk(m):
55 for f in repo.walk(m):
56 exact = m.exact(f)
56 exact = m.exact(f)
57 if exact or f not in repo.dirstate:
57 if exact or f not in repo.dirstate:
58 names.append(f)
58 names.append(f)
59 if ui.verbose or not exact:
59 if ui.verbose or not exact:
60 ui.status(_('adding %s\n') % m.rel(f))
60 ui.status(_('adding %s\n') % m.rel(f))
61 if not opts.get('dry_run'):
61 if not opts.get('dry_run'):
62 bad += [f for f in repo[None].add(names) if f in m.files()]
62 bad += [f for f in repo[None].add(names) if f in m.files()]
63 return bad and 1 or 0
63 return bad and 1 or 0
64
64
65 def addremove(ui, repo, *pats, **opts):
65 def addremove(ui, repo, *pats, **opts):
66 """add all new files, delete all missing files
66 """add all new files, delete all missing files
67
67
68 Add all new files and remove all missing files from the
68 Add all new files and remove all missing files from the
69 repository.
69 repository.
70
70
71 New files are ignored if they match any of the patterns in
71 New files are ignored if they match any of the patterns in
72 .hgignore. As with add, these changes take effect at the next
72 .hgignore. As with add, these changes take effect at the next
73 commit.
73 commit.
74
74
75 Use the -s/--similarity option to detect renamed files. With a
75 Use the -s/--similarity option to detect renamed files. With a
76 parameter greater than 0, this compares every removed file with
76 parameter greater than 0, this compares every removed file with
77 every added file and records those similar enough as renames. This
77 every added file and records those similar enough as renames. This
78 option takes a percentage between 0 (disabled) and 100 (files must
78 option takes a percentage between 0 (disabled) and 100 (files must
79 be identical) as its parameter. Detecting renamed files this way
79 be identical) as its parameter. Detecting renamed files this way
80 can be expensive. After using this option, :hg:`status -C` can be
80 can be expensive. After using this option, :hg:`status -C` can be
81 used to check which files were identified as moved or renamed.
81 used to check which files were identified as moved or renamed.
82
82
83 Returns 0 if all files are successfully added.
83 Returns 0 if all files are successfully added.
84 """
84 """
85 try:
85 try:
86 sim = float(opts.get('similarity') or 100)
86 sim = float(opts.get('similarity') or 100)
87 except ValueError:
87 except ValueError:
88 raise util.Abort(_('similarity must be a number'))
88 raise util.Abort(_('similarity must be a number'))
89 if sim < 0 or sim > 100:
89 if sim < 0 or sim > 100:
90 raise util.Abort(_('similarity must be between 0 and 100'))
90 raise util.Abort(_('similarity must be between 0 and 100'))
91 return cmdutil.addremove(repo, pats, opts, similarity=sim / 100.0)
91 return cmdutil.addremove(repo, pats, opts, similarity=sim / 100.0)
92
92
93 def annotate(ui, repo, *pats, **opts):
93 def annotate(ui, repo, *pats, **opts):
94 """show changeset information by line for each file
94 """show changeset information by line for each file
95
95
96 List changes in files, showing the revision id responsible for
96 List changes in files, showing the revision id responsible for
97 each line
97 each line
98
98
99 This command is useful for discovering when a change was made and
99 This command is useful for discovering when a change was made and
100 by whom.
100 by whom.
101
101
102 Without the -a/--text option, annotate will avoid processing files
102 Without the -a/--text option, annotate will avoid processing files
103 it detects as binary. With -a, annotate will annotate the file
103 it detects as binary. With -a, annotate will annotate the file
104 anyway, although the results will probably be neither useful
104 anyway, although the results will probably be neither useful
105 nor desirable.
105 nor desirable.
106
106
107 Returns 0 on success.
107 Returns 0 on success.
108 """
108 """
109 if opts.get('follow'):
109 if opts.get('follow'):
110 # --follow is deprecated and now just an alias for -f/--file
110 # --follow is deprecated and now just an alias for -f/--file
111 # to mimic the behavior of Mercurial before version 1.5
111 # to mimic the behavior of Mercurial before version 1.5
112 opts['file'] = 1
112 opts['file'] = 1
113
113
114 datefunc = ui.quiet and util.shortdate or util.datestr
114 datefunc = ui.quiet and util.shortdate or util.datestr
115 getdate = util.cachefunc(lambda x: datefunc(x[0].date()))
115 getdate = util.cachefunc(lambda x: datefunc(x[0].date()))
116
116
117 if not pats:
117 if not pats:
118 raise util.Abort(_('at least one filename or pattern is required'))
118 raise util.Abort(_('at least one filename or pattern is required'))
119
119
120 opmap = [('user', lambda x: ui.shortuser(x[0].user())),
120 opmap = [('user', lambda x: ui.shortuser(x[0].user())),
121 ('number', lambda x: str(x[0].rev())),
121 ('number', lambda x: str(x[0].rev())),
122 ('changeset', lambda x: short(x[0].node())),
122 ('changeset', lambda x: short(x[0].node())),
123 ('date', getdate),
123 ('date', getdate),
124 ('file', lambda x: x[0].path()),
124 ('file', lambda x: x[0].path()),
125 ]
125 ]
126
126
127 if (not opts.get('user') and not opts.get('changeset')
127 if (not opts.get('user') and not opts.get('changeset')
128 and not opts.get('date') and not opts.get('file')):
128 and not opts.get('date') and not opts.get('file')):
129 opts['number'] = 1
129 opts['number'] = 1
130
130
131 linenumber = opts.get('line_number') is not None
131 linenumber = opts.get('line_number') is not None
132 if linenumber and (not opts.get('changeset')) and (not opts.get('number')):
132 if linenumber and (not opts.get('changeset')) and (not opts.get('number')):
133 raise util.Abort(_('at least one of -n/-c is required for -l'))
133 raise util.Abort(_('at least one of -n/-c is required for -l'))
134
134
135 funcmap = [func for op, func in opmap if opts.get(op)]
135 funcmap = [func for op, func in opmap if opts.get(op)]
136 if linenumber:
136 if linenumber:
137 lastfunc = funcmap[-1]
137 lastfunc = funcmap[-1]
138 funcmap[-1] = lambda x: "%s:%s" % (lastfunc(x), x[1])
138 funcmap[-1] = lambda x: "%s:%s" % (lastfunc(x), x[1])
139
139
140 ctx = repo[opts.get('rev')]
140 ctx = repo[opts.get('rev')]
141 m = cmdutil.match(repo, pats, opts)
141 m = cmdutil.match(repo, pats, opts)
142 follow = not opts.get('no_follow')
142 follow = not opts.get('no_follow')
143 for abs in ctx.walk(m):
143 for abs in ctx.walk(m):
144 fctx = ctx[abs]
144 fctx = ctx[abs]
145 if not opts.get('text') and util.binary(fctx.data()):
145 if not opts.get('text') and util.binary(fctx.data()):
146 ui.write(_("%s: binary file\n") % ((pats and m.rel(abs)) or abs))
146 ui.write(_("%s: binary file\n") % ((pats and m.rel(abs)) or abs))
147 continue
147 continue
148
148
149 lines = fctx.annotate(follow=follow, linenumber=linenumber)
149 lines = fctx.annotate(follow=follow, linenumber=linenumber)
150 pieces = []
150 pieces = []
151
151
152 for f in funcmap:
152 for f in funcmap:
153 l = [f(n) for n, dummy in lines]
153 l = [f(n) for n, dummy in lines]
154 if l:
154 if l:
155 sized = [(x, encoding.colwidth(x)) for x in l]
155 sized = [(x, encoding.colwidth(x)) for x in l]
156 ml = max([w for x, w in sized])
156 ml = max([w for x, w in sized])
157 pieces.append(["%s%s" % (' ' * (ml - w), x) for x, w in sized])
157 pieces.append(["%s%s" % (' ' * (ml - w), x) for x, w in sized])
158
158
159 if pieces:
159 if pieces:
160 for p, l in zip(zip(*pieces), lines):
160 for p, l in zip(zip(*pieces), lines):
161 ui.write("%s: %s" % (" ".join(p), l[1]))
161 ui.write("%s: %s" % (" ".join(p), l[1]))
162
162
163 def archive(ui, repo, dest, **opts):
163 def archive(ui, repo, dest, **opts):
164 '''create an unversioned archive of a repository revision
164 '''create an unversioned archive of a repository revision
165
165
166 By default, the revision used is the parent of the working
166 By default, the revision used is the parent of the working
167 directory; use -r/--rev to specify a different revision.
167 directory; use -r/--rev to specify a different revision.
168
168
169 The archive type is automatically detected based on file
169 The archive type is automatically detected based on file
170 extension (or override using -t/--type).
170 extension (or override using -t/--type).
171
171
172 Valid types are:
172 Valid types are:
173
173
174 :``files``: a directory full of files (default)
174 :``files``: a directory full of files (default)
175 :``tar``: tar archive, uncompressed
175 :``tar``: tar archive, uncompressed
176 :``tbz2``: tar archive, compressed using bzip2
176 :``tbz2``: tar archive, compressed using bzip2
177 :``tgz``: tar archive, compressed using gzip
177 :``tgz``: tar archive, compressed using gzip
178 :``uzip``: zip archive, uncompressed
178 :``uzip``: zip archive, uncompressed
179 :``zip``: zip archive, compressed using deflate
179 :``zip``: zip archive, compressed using deflate
180
180
181 The exact name of the destination archive or directory is given
181 The exact name of the destination archive or directory is given
182 using a format string; see :hg:`help export` for details.
182 using a format string; see :hg:`help export` for details.
183
183
184 Each member added to an archive file has a directory prefix
184 Each member added to an archive file has a directory prefix
185 prepended. Use -p/--prefix to specify a format string for the
185 prepended. Use -p/--prefix to specify a format string for the
186 prefix. The default is the basename of the archive, with suffixes
186 prefix. The default is the basename of the archive, with suffixes
187 removed.
187 removed.
188
188
189 Returns 0 on success.
189 Returns 0 on success.
190 '''
190 '''
191
191
192 ctx = repo[opts.get('rev')]
192 ctx = repo[opts.get('rev')]
193 if not ctx:
193 if not ctx:
194 raise util.Abort(_('no working directory: please specify a revision'))
194 raise util.Abort(_('no working directory: please specify a revision'))
195 node = ctx.node()
195 node = ctx.node()
196 dest = cmdutil.make_filename(repo, dest, node)
196 dest = cmdutil.make_filename(repo, dest, node)
197 if os.path.realpath(dest) == repo.root:
197 if os.path.realpath(dest) == repo.root:
198 raise util.Abort(_('repository root cannot be destination'))
198 raise util.Abort(_('repository root cannot be destination'))
199
199
200 kind = opts.get('type') or archival.guesskind(dest) or 'files'
200 kind = opts.get('type') or archival.guesskind(dest) or 'files'
201 prefix = opts.get('prefix')
201 prefix = opts.get('prefix')
202
202
203 if dest == '-':
203 if dest == '-':
204 if kind == 'files':
204 if kind == 'files':
205 raise util.Abort(_('cannot archive plain files to stdout'))
205 raise util.Abort(_('cannot archive plain files to stdout'))
206 dest = sys.stdout
206 dest = sys.stdout
207 if not prefix:
207 if not prefix:
208 prefix = os.path.basename(repo.root) + '-%h'
208 prefix = os.path.basename(repo.root) + '-%h'
209
209
210 prefix = cmdutil.make_filename(repo, prefix, node)
210 prefix = cmdutil.make_filename(repo, prefix, node)
211 matchfn = cmdutil.match(repo, [], opts)
211 matchfn = cmdutil.match(repo, [], opts)
212 archival.archive(repo, dest, node, kind, not opts.get('no_decode'),
212 archival.archive(repo, dest, node, kind, not opts.get('no_decode'),
213 matchfn, prefix)
213 matchfn, prefix)
214
214
215 def backout(ui, repo, node=None, rev=None, **opts):
215 def backout(ui, repo, node=None, rev=None, **opts):
216 '''reverse effect of earlier changeset
216 '''reverse effect of earlier changeset
217
217
218 Commit the backed out changes as a new changeset. The new
218 Commit the backed out changes as a new changeset. The new
219 changeset is a child of the backed out changeset.
219 changeset is a child of the backed out changeset.
220
220
221 If you backout a changeset other than the tip, a new head is
221 If you backout a changeset other than the tip, a new head is
222 created. This head will be the new tip and you should merge this
222 created. This head will be the new tip and you should merge this
223 backout changeset with another head.
223 backout changeset with another head.
224
224
225 The --merge option remembers the parent of the working directory
225 The --merge option remembers the parent of the working directory
226 before starting the backout, then merges the new head with that
226 before starting the backout, then merges the new head with that
227 changeset afterwards. This saves you from doing the merge by hand.
227 changeset afterwards. This saves you from doing the merge by hand.
228 The result of this merge is not committed, as with a normal merge.
228 The result of this merge is not committed, as with a normal merge.
229
229
230 See :hg:`help dates` for a list of formats valid for -d/--date.
230 See :hg:`help dates` for a list of formats valid for -d/--date.
231
231
232 Returns 0 on success.
232 Returns 0 on success.
233 '''
233 '''
234 if rev and node:
234 if rev and node:
235 raise util.Abort(_("please specify just one revision"))
235 raise util.Abort(_("please specify just one revision"))
236
236
237 if not rev:
237 if not rev:
238 rev = node
238 rev = node
239
239
240 if not rev:
240 if not rev:
241 raise util.Abort(_("please specify a revision to backout"))
241 raise util.Abort(_("please specify a revision to backout"))
242
242
243 date = opts.get('date')
243 date = opts.get('date')
244 if date:
244 if date:
245 opts['date'] = util.parsedate(date)
245 opts['date'] = util.parsedate(date)
246
246
247 cmdutil.bail_if_changed(repo)
247 cmdutil.bail_if_changed(repo)
248 node = repo.lookup(rev)
248 node = repo.lookup(rev)
249
249
250 op1, op2 = repo.dirstate.parents()
250 op1, op2 = repo.dirstate.parents()
251 a = repo.changelog.ancestor(op1, node)
251 a = repo.changelog.ancestor(op1, node)
252 if a != node:
252 if a != node:
253 raise util.Abort(_('cannot backout change on a different branch'))
253 raise util.Abort(_('cannot backout change on a different branch'))
254
254
255 p1, p2 = repo.changelog.parents(node)
255 p1, p2 = repo.changelog.parents(node)
256 if p1 == nullid:
256 if p1 == nullid:
257 raise util.Abort(_('cannot backout a change with no parents'))
257 raise util.Abort(_('cannot backout a change with no parents'))
258 if p2 != nullid:
258 if p2 != nullid:
259 if not opts.get('parent'):
259 if not opts.get('parent'):
260 raise util.Abort(_('cannot backout a merge changeset without '
260 raise util.Abort(_('cannot backout a merge changeset without '
261 '--parent'))
261 '--parent'))
262 p = repo.lookup(opts['parent'])
262 p = repo.lookup(opts['parent'])
263 if p not in (p1, p2):
263 if p not in (p1, p2):
264 raise util.Abort(_('%s is not a parent of %s') %
264 raise util.Abort(_('%s is not a parent of %s') %
265 (short(p), short(node)))
265 (short(p), short(node)))
266 parent = p
266 parent = p
267 else:
267 else:
268 if opts.get('parent'):
268 if opts.get('parent'):
269 raise util.Abort(_('cannot use --parent on non-merge changeset'))
269 raise util.Abort(_('cannot use --parent on non-merge changeset'))
270 parent = p1
270 parent = p1
271
271
272 # the backout should appear on the same branch
272 # the backout should appear on the same branch
273 branch = repo.dirstate.branch()
273 branch = repo.dirstate.branch()
274 hg.clean(repo, node, show_stats=False)
274 hg.clean(repo, node, show_stats=False)
275 repo.dirstate.setbranch(branch)
275 repo.dirstate.setbranch(branch)
276 revert_opts = opts.copy()
276 revert_opts = opts.copy()
277 revert_opts['date'] = None
277 revert_opts['date'] = None
278 revert_opts['all'] = True
278 revert_opts['all'] = True
279 revert_opts['rev'] = hex(parent)
279 revert_opts['rev'] = hex(parent)
280 revert_opts['no_backup'] = None
280 revert_opts['no_backup'] = None
281 revert(ui, repo, **revert_opts)
281 revert(ui, repo, **revert_opts)
282 commit_opts = opts.copy()
282 commit_opts = opts.copy()
283 commit_opts['addremove'] = False
283 commit_opts['addremove'] = False
284 if not commit_opts['message'] and not commit_opts['logfile']:
284 if not commit_opts['message'] and not commit_opts['logfile']:
285 # we don't translate commit messages
285 # we don't translate commit messages
286 commit_opts['message'] = "Backed out changeset %s" % short(node)
286 commit_opts['message'] = "Backed out changeset %s" % short(node)
287 commit_opts['force_editor'] = True
287 commit_opts['force_editor'] = True
288 commit(ui, repo, **commit_opts)
288 commit(ui, repo, **commit_opts)
289 def nice(node):
289 def nice(node):
290 return '%d:%s' % (repo.changelog.rev(node), short(node))
290 return '%d:%s' % (repo.changelog.rev(node), short(node))
291 ui.status(_('changeset %s backs out changeset %s\n') %
291 ui.status(_('changeset %s backs out changeset %s\n') %
292 (nice(repo.changelog.tip()), nice(node)))
292 (nice(repo.changelog.tip()), nice(node)))
293 if op1 != node:
293 if op1 != node:
294 hg.clean(repo, op1, show_stats=False)
294 hg.clean(repo, op1, show_stats=False)
295 if opts.get('merge'):
295 if opts.get('merge'):
296 ui.status(_('merging with changeset %s\n')
296 ui.status(_('merging with changeset %s\n')
297 % nice(repo.changelog.tip()))
297 % nice(repo.changelog.tip()))
298 hg.merge(repo, hex(repo.changelog.tip()))
298 hg.merge(repo, hex(repo.changelog.tip()))
299 else:
299 else:
300 ui.status(_('the backout changeset is a new head - '
300 ui.status(_('the backout changeset is a new head - '
301 'do not forget to merge\n'))
301 'do not forget to merge\n'))
302 ui.status(_('(use "backout --merge" '
302 ui.status(_('(use "backout --merge" '
303 'if you want to auto-merge)\n'))
303 'if you want to auto-merge)\n'))
304
304
305 def bisect(ui, repo, rev=None, extra=None, command=None,
305 def bisect(ui, repo, rev=None, extra=None, command=None,
306 reset=None, good=None, bad=None, skip=None, noupdate=None):
306 reset=None, good=None, bad=None, skip=None, noupdate=None):
307 """subdivision search of changesets
307 """subdivision search of changesets
308
308
309 This command helps to find changesets which introduce problems. To
309 This command helps to find changesets which introduce problems. To
310 use, mark the earliest changeset you know exhibits the problem as
310 use, mark the earliest changeset you know exhibits the problem as
311 bad, then mark the latest changeset which is free from the problem
311 bad, then mark the latest changeset which is free from the problem
312 as good. Bisect will update your working directory to a revision
312 as good. Bisect will update your working directory to a revision
313 for testing (unless the -U/--noupdate option is specified). Once
313 for testing (unless the -U/--noupdate option is specified). Once
314 you have performed tests, mark the working directory as good or
314 you have performed tests, mark the working directory as good or
315 bad, and bisect will either update to another candidate changeset
315 bad, and bisect will either update to another candidate changeset
316 or announce that it has found the bad revision.
316 or announce that it has found the bad revision.
317
317
318 As a shortcut, you can also use the revision argument to mark a
318 As a shortcut, you can also use the revision argument to mark a
319 revision as good or bad without checking it out first.
319 revision as good or bad without checking it out first.
320
320
321 If you supply a command, it will be used for automatic bisection.
321 If you supply a command, it will be used for automatic bisection.
322 Its exit status will be used to mark revisions as good or bad:
322 Its exit status will be used to mark revisions as good or bad:
323 status 0 means good, 125 means to skip the revision, 127
323 status 0 means good, 125 means to skip the revision, 127
324 (command not found) will abort the bisection, and any other
324 (command not found) will abort the bisection, and any other
325 non-zero exit status means the revision is bad.
325 non-zero exit status means the revision is bad.
326
326
327 Returns 0 on success.
327 Returns 0 on success.
328 """
328 """
329 def print_result(nodes, good):
329 def print_result(nodes, good):
330 displayer = cmdutil.show_changeset(ui, repo, {})
330 displayer = cmdutil.show_changeset(ui, repo, {})
331 if len(nodes) == 1:
331 if len(nodes) == 1:
332 # narrowed it down to a single revision
332 # narrowed it down to a single revision
333 if good:
333 if good:
334 ui.write(_("The first good revision is:\n"))
334 ui.write(_("The first good revision is:\n"))
335 else:
335 else:
336 ui.write(_("The first bad revision is:\n"))
336 ui.write(_("The first bad revision is:\n"))
337 displayer.show(repo[nodes[0]])
337 displayer.show(repo[nodes[0]])
338 else:
338 else:
339 # multiple possible revisions
339 # multiple possible revisions
340 if good:
340 if good:
341 ui.write(_("Due to skipped revisions, the first "
341 ui.write(_("Due to skipped revisions, the first "
342 "good revision could be any of:\n"))
342 "good revision could be any of:\n"))
343 else:
343 else:
344 ui.write(_("Due to skipped revisions, the first "
344 ui.write(_("Due to skipped revisions, the first "
345 "bad revision could be any of:\n"))
345 "bad revision could be any of:\n"))
346 for n in nodes:
346 for n in nodes:
347 displayer.show(repo[n])
347 displayer.show(repo[n])
348 displayer.close()
348 displayer.close()
349
349
350 def check_state(state, interactive=True):
350 def check_state(state, interactive=True):
351 if not state['good'] or not state['bad']:
351 if not state['good'] or not state['bad']:
352 if (good or bad or skip or reset) and interactive:
352 if (good or bad or skip or reset) and interactive:
353 return
353 return
354 if not state['good']:
354 if not state['good']:
355 raise util.Abort(_('cannot bisect (no known good revisions)'))
355 raise util.Abort(_('cannot bisect (no known good revisions)'))
356 else:
356 else:
357 raise util.Abort(_('cannot bisect (no known bad revisions)'))
357 raise util.Abort(_('cannot bisect (no known bad revisions)'))
358 return True
358 return True
359
359
360 # backward compatibility
360 # backward compatibility
361 if rev in "good bad reset init".split():
361 if rev in "good bad reset init".split():
362 ui.warn(_("(use of 'hg bisect <cmd>' is deprecated)\n"))
362 ui.warn(_("(use of 'hg bisect <cmd>' is deprecated)\n"))
363 cmd, rev, extra = rev, extra, None
363 cmd, rev, extra = rev, extra, None
364 if cmd == "good":
364 if cmd == "good":
365 good = True
365 good = True
366 elif cmd == "bad":
366 elif cmd == "bad":
367 bad = True
367 bad = True
368 else:
368 else:
369 reset = True
369 reset = True
370 elif extra or good + bad + skip + reset + bool(command) > 1:
370 elif extra or good + bad + skip + reset + bool(command) > 1:
371 raise util.Abort(_('incompatible arguments'))
371 raise util.Abort(_('incompatible arguments'))
372
372
373 if reset:
373 if reset:
374 p = repo.join("bisect.state")
374 p = repo.join("bisect.state")
375 if os.path.exists(p):
375 if os.path.exists(p):
376 os.unlink(p)
376 os.unlink(p)
377 return
377 return
378
378
379 state = hbisect.load_state(repo)
379 state = hbisect.load_state(repo)
380
380
381 if command:
381 if command:
382 changesets = 1
382 changesets = 1
383 try:
383 try:
384 while changesets:
384 while changesets:
385 # update state
385 # update state
386 status = util.system(command)
386 status = util.system(command)
387 if status == 125:
387 if status == 125:
388 transition = "skip"
388 transition = "skip"
389 elif status == 0:
389 elif status == 0:
390 transition = "good"
390 transition = "good"
391 # status < 0 means process was killed
391 # status < 0 means process was killed
392 elif status == 127:
392 elif status == 127:
393 raise util.Abort(_("failed to execute %s") % command)
393 raise util.Abort(_("failed to execute %s") % command)
394 elif status < 0:
394 elif status < 0:
395 raise util.Abort(_("%s killed") % command)
395 raise util.Abort(_("%s killed") % command)
396 else:
396 else:
397 transition = "bad"
397 transition = "bad"
398 ctx = repo[rev or '.']
398 ctx = repo[rev or '.']
399 state[transition].append(ctx.node())
399 state[transition].append(ctx.node())
400 ui.status(_('Changeset %d:%s: %s\n') % (ctx, ctx, transition))
400 ui.status(_('Changeset %d:%s: %s\n') % (ctx, ctx, transition))
401 check_state(state, interactive=False)
401 check_state(state, interactive=False)
402 # bisect
402 # bisect
403 nodes, changesets, good = hbisect.bisect(repo.changelog, state)
403 nodes, changesets, good = hbisect.bisect(repo.changelog, state)
404 # update to next check
404 # update to next check
405 cmdutil.bail_if_changed(repo)
405 cmdutil.bail_if_changed(repo)
406 hg.clean(repo, nodes[0], show_stats=False)
406 hg.clean(repo, nodes[0], show_stats=False)
407 finally:
407 finally:
408 hbisect.save_state(repo, state)
408 hbisect.save_state(repo, state)
409 print_result(nodes, good)
409 print_result(nodes, good)
410 return
410 return
411
411
412 # update state
412 # update state
413 node = repo.lookup(rev or '.')
413 node = repo.lookup(rev or '.')
414 if good or bad or skip:
414 if good or bad or skip:
415 if good:
415 if good:
416 state['good'].append(node)
416 state['good'].append(node)
417 elif bad:
417 elif bad:
418 state['bad'].append(node)
418 state['bad'].append(node)
419 elif skip:
419 elif skip:
420 state['skip'].append(node)
420 state['skip'].append(node)
421 hbisect.save_state(repo, state)
421 hbisect.save_state(repo, state)
422
422
423 if not check_state(state):
423 if not check_state(state):
424 return
424 return
425
425
426 # actually bisect
426 # actually bisect
427 nodes, changesets, good = hbisect.bisect(repo.changelog, state)
427 nodes, changesets, good = hbisect.bisect(repo.changelog, state)
428 if changesets == 0:
428 if changesets == 0:
429 print_result(nodes, good)
429 print_result(nodes, good)
430 else:
430 else:
431 assert len(nodes) == 1 # only a single node can be tested next
431 assert len(nodes) == 1 # only a single node can be tested next
432 node = nodes[0]
432 node = nodes[0]
433 # compute the approximate number of remaining tests
433 # compute the approximate number of remaining tests
434 tests, size = 0, 2
434 tests, size = 0, 2
435 while size <= changesets:
435 while size <= changesets:
436 tests, size = tests + 1, size * 2
436 tests, size = tests + 1, size * 2
437 rev = repo.changelog.rev(node)
437 rev = repo.changelog.rev(node)
438 ui.write(_("Testing changeset %d:%s "
438 ui.write(_("Testing changeset %d:%s "
439 "(%d changesets remaining, ~%d tests)\n")
439 "(%d changesets remaining, ~%d tests)\n")
440 % (rev, short(node), changesets, tests))
440 % (rev, short(node), changesets, tests))
441 if not noupdate:
441 if not noupdate:
442 cmdutil.bail_if_changed(repo)
442 cmdutil.bail_if_changed(repo)
443 return hg.clean(repo, node)
443 return hg.clean(repo, node)
444
444
445 def branch(ui, repo, label=None, **opts):
445 def branch(ui, repo, label=None, **opts):
446 """set or show the current branch name
446 """set or show the current branch name
447
447
448 With no argument, show the current branch name. With one argument,
448 With no argument, show the current branch name. With one argument,
449 set the working directory branch name (the branch will not exist
449 set the working directory branch name (the branch will not exist
450 in the repository until the next commit). Standard practice
450 in the repository until the next commit). Standard practice
451 recommends that primary development take place on the 'default'
451 recommends that primary development take place on the 'default'
452 branch.
452 branch.
453
453
454 Unless -f/--force is specified, branch will not let you set a
454 Unless -f/--force is specified, branch will not let you set a
455 branch name that already exists, even if it's inactive.
455 branch name that already exists, even if it's inactive.
456
456
457 Use -C/--clean to reset the working directory branch to that of
457 Use -C/--clean to reset the working directory branch to that of
458 the parent of the working directory, negating a previous branch
458 the parent of the working directory, negating a previous branch
459 change.
459 change.
460
460
461 Use the command :hg:`update` to switch to an existing branch. Use
461 Use the command :hg:`update` to switch to an existing branch. Use
462 :hg:`commit --close-branch` to mark this branch as closed.
462 :hg:`commit --close-branch` to mark this branch as closed.
463
463
464 Returns 0 on success.
464 Returns 0 on success.
465 """
465 """
466
466
467 if opts.get('clean'):
467 if opts.get('clean'):
468 label = repo[None].parents()[0].branch()
468 label = repo[None].parents()[0].branch()
469 repo.dirstate.setbranch(label)
469 repo.dirstate.setbranch(label)
470 ui.status(_('reset working directory to branch %s\n') % label)
470 ui.status(_('reset working directory to branch %s\n') % label)
471 elif label:
471 elif label:
472 utflabel = encoding.fromlocal(label)
472 utflabel = encoding.fromlocal(label)
473 if not opts.get('force') and utflabel in repo.branchtags():
473 if not opts.get('force') and utflabel in repo.branchtags():
474 if label not in [p.branch() for p in repo.parents()]:
474 if label not in [p.branch() for p in repo.parents()]:
475 raise util.Abort(_('a branch of the same name already exists'
475 raise util.Abort(_('a branch of the same name already exists'
476 " (use 'hg update' to switch to it)"))
476 " (use 'hg update' to switch to it)"))
477 repo.dirstate.setbranch(utflabel)
477 repo.dirstate.setbranch(utflabel)
478 ui.status(_('marked working directory as branch %s\n') % label)
478 ui.status(_('marked working directory as branch %s\n') % label)
479 else:
479 else:
480 ui.write("%s\n" % encoding.tolocal(repo.dirstate.branch()))
480 ui.write("%s\n" % encoding.tolocal(repo.dirstate.branch()))
481
481
482 def branches(ui, repo, active=False, closed=False):
482 def branches(ui, repo, active=False, closed=False):
483 """list repository named branches
483 """list repository named branches
484
484
485 List the repository's named branches, indicating which ones are
485 List the repository's named branches, indicating which ones are
486 inactive. If -c/--closed is specified, also list branches which have
486 inactive. If -c/--closed is specified, also list branches which have
487 been marked closed (see :hg:`commit --close-branch`).
487 been marked closed (see :hg:`commit --close-branch`).
488
488
489 If -a/--active is specified, only show active branches. A branch
489 If -a/--active is specified, only show active branches. A branch
490 is considered active if it contains repository heads.
490 is considered active if it contains repository heads.
491
491
492 Use the command :hg:`update` to switch to an existing branch.
492 Use the command :hg:`update` to switch to an existing branch.
493
493
494 Returns 0.
494 Returns 0.
495 """
495 """
496
496
497 hexfunc = ui.debugflag and hex or short
497 hexfunc = ui.debugflag and hex or short
498 activebranches = [repo[n].branch() for n in repo.heads()]
498 activebranches = [repo[n].branch() for n in repo.heads()]
499 def testactive(tag, node):
499 def testactive(tag, node):
500 realhead = tag in activebranches
500 realhead = tag in activebranches
501 open = node in repo.branchheads(tag, closed=False)
501 open = node in repo.branchheads(tag, closed=False)
502 return realhead and open
502 return realhead and open
503 branches = sorted([(testactive(tag, node), repo.changelog.rev(node), tag)
503 branches = sorted([(testactive(tag, node), repo.changelog.rev(node), tag)
504 for tag, node in repo.branchtags().items()],
504 for tag, node in repo.branchtags().items()],
505 reverse=True)
505 reverse=True)
506
506
507 for isactive, node, tag in branches:
507 for isactive, node, tag in branches:
508 if (not active) or isactive:
508 if (not active) or isactive:
509 encodedtag = encoding.tolocal(tag)
509 encodedtag = encoding.tolocal(tag)
510 if ui.quiet:
510 if ui.quiet:
511 ui.write("%s\n" % encodedtag)
511 ui.write("%s\n" % encodedtag)
512 else:
512 else:
513 hn = repo.lookup(node)
513 hn = repo.lookup(node)
514 if isactive:
514 if isactive:
515 label = 'branches.active'
515 notice = ''
516 notice = ''
516 elif hn not in repo.branchheads(tag, closed=False):
517 elif hn not in repo.branchheads(tag, closed=False):
517 if not closed:
518 if not closed:
518 continue
519 continue
520 label = 'branches.closed'
519 notice = _(' (closed)')
521 notice = _(' (closed)')
520 else:
522 else:
523 label = 'branches.inactive'
521 notice = _(' (inactive)')
524 notice = _(' (inactive)')
525 if tag == repo.dirstate.branch():
526 label = 'branches.current'
522 rev = str(node).rjust(31 - encoding.colwidth(encodedtag))
527 rev = str(node).rjust(31 - encoding.colwidth(encodedtag))
523 data = encodedtag, rev, hexfunc(hn), notice
528 rev = ui.label('%s:%s' % (rev, hexfunc(hn)), 'log.changeset')
524 ui.write("%s %s:%s%s\n" % data)
529 encodedtag = ui.label(encodedtag, label)
530 ui.write("%s %s%s\n" % (encodedtag, rev, notice))
525
531
526 def bundle(ui, repo, fname, dest=None, **opts):
532 def bundle(ui, repo, fname, dest=None, **opts):
527 """create a changegroup file
533 """create a changegroup file
528
534
529 Generate a compressed changegroup file collecting changesets not
535 Generate a compressed changegroup file collecting changesets not
530 known to be in another repository.
536 known to be in another repository.
531
537
532 If you omit the destination repository, then hg assumes the
538 If you omit the destination repository, then hg assumes the
533 destination will have all the nodes you specify with --base
539 destination will have all the nodes you specify with --base
534 parameters. To create a bundle containing all changesets, use
540 parameters. To create a bundle containing all changesets, use
535 -a/--all (or --base null).
541 -a/--all (or --base null).
536
542
537 You can change compression method with the -t/--type option.
543 You can change compression method with the -t/--type option.
538 The available compression methods are: none, bzip2, and
544 The available compression methods are: none, bzip2, and
539 gzip (by default, bundles are compressed using bzip2).
545 gzip (by default, bundles are compressed using bzip2).
540
546
541 The bundle file can then be transferred using conventional means
547 The bundle file can then be transferred using conventional means
542 and applied to another repository with the unbundle or pull
548 and applied to another repository with the unbundle or pull
543 command. This is useful when direct push and pull are not
549 command. This is useful when direct push and pull are not
544 available or when exporting an entire repository is undesirable.
550 available or when exporting an entire repository is undesirable.
545
551
546 Applying bundles preserves all changeset contents including
552 Applying bundles preserves all changeset contents including
547 permissions, copy/rename information, and revision history.
553 permissions, copy/rename information, and revision history.
548
554
549 Returns 0 on success, 1 if no changes found.
555 Returns 0 on success, 1 if no changes found.
550 """
556 """
551 revs = opts.get('rev') or None
557 revs = opts.get('rev') or None
552 if opts.get('all'):
558 if opts.get('all'):
553 base = ['null']
559 base = ['null']
554 else:
560 else:
555 base = opts.get('base')
561 base = opts.get('base')
556 if base:
562 if base:
557 if dest:
563 if dest:
558 raise util.Abort(_("--base is incompatible with specifying "
564 raise util.Abort(_("--base is incompatible with specifying "
559 "a destination"))
565 "a destination"))
560 base = [repo.lookup(rev) for rev in base]
566 base = [repo.lookup(rev) for rev in base]
561 # create the right base
567 # create the right base
562 # XXX: nodesbetween / changegroup* should be "fixed" instead
568 # XXX: nodesbetween / changegroup* should be "fixed" instead
563 o = []
569 o = []
564 has = set((nullid,))
570 has = set((nullid,))
565 for n in base:
571 for n in base:
566 has.update(repo.changelog.reachable(n))
572 has.update(repo.changelog.reachable(n))
567 if revs:
573 if revs:
568 revs = [repo.lookup(rev) for rev in revs]
574 revs = [repo.lookup(rev) for rev in revs]
569 visit = revs[:]
575 visit = revs[:]
570 has.difference_update(visit)
576 has.difference_update(visit)
571 else:
577 else:
572 visit = repo.changelog.heads()
578 visit = repo.changelog.heads()
573 seen = {}
579 seen = {}
574 while visit:
580 while visit:
575 n = visit.pop(0)
581 n = visit.pop(0)
576 parents = [p for p in repo.changelog.parents(n) if p not in has]
582 parents = [p for p in repo.changelog.parents(n) if p not in has]
577 if len(parents) == 0:
583 if len(parents) == 0:
578 if n not in has:
584 if n not in has:
579 o.append(n)
585 o.append(n)
580 else:
586 else:
581 for p in parents:
587 for p in parents:
582 if p not in seen:
588 if p not in seen:
583 seen[p] = 1
589 seen[p] = 1
584 visit.append(p)
590 visit.append(p)
585 else:
591 else:
586 dest = ui.expandpath(dest or 'default-push', dest or 'default')
592 dest = ui.expandpath(dest or 'default-push', dest or 'default')
587 dest, branches = hg.parseurl(dest, opts.get('branch'))
593 dest, branches = hg.parseurl(dest, opts.get('branch'))
588 other = hg.repository(hg.remoteui(repo, opts), dest)
594 other = hg.repository(hg.remoteui(repo, opts), dest)
589 revs, checkout = hg.addbranchrevs(repo, other, branches, revs)
595 revs, checkout = hg.addbranchrevs(repo, other, branches, revs)
590 if revs:
596 if revs:
591 revs = [repo.lookup(rev) for rev in revs]
597 revs = [repo.lookup(rev) for rev in revs]
592 o = discovery.findoutgoing(repo, other, force=opts.get('force'))
598 o = discovery.findoutgoing(repo, other, force=opts.get('force'))
593
599
594 if not o:
600 if not o:
595 ui.status(_("no changes found\n"))
601 ui.status(_("no changes found\n"))
596 return 1
602 return 1
597
603
598 if revs:
604 if revs:
599 cg = repo.changegroupsubset(o, revs, 'bundle')
605 cg = repo.changegroupsubset(o, revs, 'bundle')
600 else:
606 else:
601 cg = repo.changegroup(o, 'bundle')
607 cg = repo.changegroup(o, 'bundle')
602
608
603 bundletype = opts.get('type', 'bzip2').lower()
609 bundletype = opts.get('type', 'bzip2').lower()
604 btypes = {'none': 'HG10UN', 'bzip2': 'HG10BZ', 'gzip': 'HG10GZ'}
610 btypes = {'none': 'HG10UN', 'bzip2': 'HG10BZ', 'gzip': 'HG10GZ'}
605 bundletype = btypes.get(bundletype)
611 bundletype = btypes.get(bundletype)
606 if bundletype not in changegroup.bundletypes:
612 if bundletype not in changegroup.bundletypes:
607 raise util.Abort(_('unknown bundle type specified with --type'))
613 raise util.Abort(_('unknown bundle type specified with --type'))
608
614
609 changegroup.writebundle(cg, fname, bundletype)
615 changegroup.writebundle(cg, fname, bundletype)
610
616
611 def cat(ui, repo, file1, *pats, **opts):
617 def cat(ui, repo, file1, *pats, **opts):
612 """output the current or given revision of files
618 """output the current or given revision of files
613
619
614 Print the specified files as they were at the given revision. If
620 Print the specified files as they were at the given revision. If
615 no revision is given, the parent of the working directory is used,
621 no revision is given, the parent of the working directory is used,
616 or tip if no revision is checked out.
622 or tip if no revision is checked out.
617
623
618 Output may be to a file, in which case the name of the file is
624 Output may be to a file, in which case the name of the file is
619 given using a format string. The formatting rules are the same as
625 given using a format string. The formatting rules are the same as
620 for the export command, with the following additions:
626 for the export command, with the following additions:
621
627
622 :``%s``: basename of file being printed
628 :``%s``: basename of file being printed
623 :``%d``: dirname of file being printed, or '.' if in repository root
629 :``%d``: dirname of file being printed, or '.' if in repository root
624 :``%p``: root-relative path name of file being printed
630 :``%p``: root-relative path name of file being printed
625
631
626 Returns 0 on success.
632 Returns 0 on success.
627 """
633 """
628 ctx = repo[opts.get('rev')]
634 ctx = repo[opts.get('rev')]
629 err = 1
635 err = 1
630 m = cmdutil.match(repo, (file1,) + pats, opts)
636 m = cmdutil.match(repo, (file1,) + pats, opts)
631 for abs in ctx.walk(m):
637 for abs in ctx.walk(m):
632 fp = cmdutil.make_file(repo, opts.get('output'), ctx.node(), pathname=abs)
638 fp = cmdutil.make_file(repo, opts.get('output'), ctx.node(), pathname=abs)
633 data = ctx[abs].data()
639 data = ctx[abs].data()
634 if opts.get('decode'):
640 if opts.get('decode'):
635 data = repo.wwritedata(abs, data)
641 data = repo.wwritedata(abs, data)
636 fp.write(data)
642 fp.write(data)
637 err = 0
643 err = 0
638 return err
644 return err
639
645
640 def clone(ui, source, dest=None, **opts):
646 def clone(ui, source, dest=None, **opts):
641 """make a copy of an existing repository
647 """make a copy of an existing repository
642
648
643 Create a copy of an existing repository in a new directory.
649 Create a copy of an existing repository in a new directory.
644
650
645 If no destination directory name is specified, it defaults to the
651 If no destination directory name is specified, it defaults to the
646 basename of the source.
652 basename of the source.
647
653
648 The location of the source is added to the new repository's
654 The location of the source is added to the new repository's
649 .hg/hgrc file, as the default to be used for future pulls.
655 .hg/hgrc file, as the default to be used for future pulls.
650
656
651 See :hg:`help urls` for valid source format details.
657 See :hg:`help urls` for valid source format details.
652
658
653 It is possible to specify an ``ssh://`` URL as the destination, but no
659 It is possible to specify an ``ssh://`` URL as the destination, but no
654 .hg/hgrc and working directory will be created on the remote side.
660 .hg/hgrc and working directory will be created on the remote side.
655 Please see :hg:`help urls` for important details about ``ssh://`` URLs.
661 Please see :hg:`help urls` for important details about ``ssh://`` URLs.
656
662
657 A set of changesets (tags, or branch names) to pull may be specified
663 A set of changesets (tags, or branch names) to pull may be specified
658 by listing each changeset (tag, or branch name) with -r/--rev.
664 by listing each changeset (tag, or branch name) with -r/--rev.
659 If -r/--rev is used, the cloned repository will contain only a subset
665 If -r/--rev is used, the cloned repository will contain only a subset
660 of the changesets of the source repository. Only the set of changesets
666 of the changesets of the source repository. Only the set of changesets
661 defined by all -r/--rev options (including all their ancestors)
667 defined by all -r/--rev options (including all their ancestors)
662 will be pulled into the destination repository.
668 will be pulled into the destination repository.
663 No subsequent changesets (including subsequent tags) will be present
669 No subsequent changesets (including subsequent tags) will be present
664 in the destination.
670 in the destination.
665
671
666 Using -r/--rev (or 'clone src#rev dest') implies --pull, even for
672 Using -r/--rev (or 'clone src#rev dest') implies --pull, even for
667 local source repositories.
673 local source repositories.
668
674
669 For efficiency, hardlinks are used for cloning whenever the source
675 For efficiency, hardlinks are used for cloning whenever the source
670 and destination are on the same filesystem (note this applies only
676 and destination are on the same filesystem (note this applies only
671 to the repository data, not to the working directory). Some
677 to the repository data, not to the working directory). Some
672 filesystems, such as AFS, implement hardlinking incorrectly, but
678 filesystems, such as AFS, implement hardlinking incorrectly, but
673 do not report errors. In these cases, use the --pull option to
679 do not report errors. In these cases, use the --pull option to
674 avoid hardlinking.
680 avoid hardlinking.
675
681
676 In some cases, you can clone repositories and the working directory
682 In some cases, you can clone repositories and the working directory
677 using full hardlinks with ::
683 using full hardlinks with ::
678
684
679 $ cp -al REPO REPOCLONE
685 $ cp -al REPO REPOCLONE
680
686
681 This is the fastest way to clone, but it is not always safe. The
687 This is the fastest way to clone, but it is not always safe. The
682 operation is not atomic (making sure REPO is not modified during
688 operation is not atomic (making sure REPO is not modified during
683 the operation is up to you) and you have to make sure your editor
689 the operation is up to you) and you have to make sure your editor
684 breaks hardlinks (Emacs and most Linux Kernel tools do so). Also,
690 breaks hardlinks (Emacs and most Linux Kernel tools do so). Also,
685 this is not compatible with certain extensions that place their
691 this is not compatible with certain extensions that place their
686 metadata under the .hg directory, such as mq.
692 metadata under the .hg directory, such as mq.
687
693
688 Mercurial will update the working directory to the first applicable
694 Mercurial will update the working directory to the first applicable
689 revision from this list:
695 revision from this list:
690
696
691 a) null if -U or the source repository has no changesets
697 a) null if -U or the source repository has no changesets
692 b) if -u . and the source repository is local, the first parent of
698 b) if -u . and the source repository is local, the first parent of
693 the source repository's working directory
699 the source repository's working directory
694 c) the changeset specified with -u (if a branch name, this means the
700 c) the changeset specified with -u (if a branch name, this means the
695 latest head of that branch)
701 latest head of that branch)
696 d) the changeset specified with -r
702 d) the changeset specified with -r
697 e) the tipmost head specified with -b
703 e) the tipmost head specified with -b
698 f) the tipmost head specified with the url#branch source syntax
704 f) the tipmost head specified with the url#branch source syntax
699 g) the tipmost head of the default branch
705 g) the tipmost head of the default branch
700 h) tip
706 h) tip
701
707
702 Returns 0 on success.
708 Returns 0 on success.
703 """
709 """
704 if opts.get('noupdate') and opts.get('updaterev'):
710 if opts.get('noupdate') and opts.get('updaterev'):
705 raise util.Abort(_("cannot specify both --noupdate and --updaterev"))
711 raise util.Abort(_("cannot specify both --noupdate and --updaterev"))
706
712
707 r = hg.clone(hg.remoteui(ui, opts), source, dest,
713 r = hg.clone(hg.remoteui(ui, opts), source, dest,
708 pull=opts.get('pull'),
714 pull=opts.get('pull'),
709 stream=opts.get('uncompressed'),
715 stream=opts.get('uncompressed'),
710 rev=opts.get('rev'),
716 rev=opts.get('rev'),
711 update=opts.get('updaterev') or not opts.get('noupdate'),
717 update=opts.get('updaterev') or not opts.get('noupdate'),
712 branch=opts.get('branch'))
718 branch=opts.get('branch'))
713
719
714 return r is None
720 return r is None
715
721
716 def commit(ui, repo, *pats, **opts):
722 def commit(ui, repo, *pats, **opts):
717 """commit the specified files or all outstanding changes
723 """commit the specified files or all outstanding changes
718
724
719 Commit changes to the given files into the repository. Unlike a
725 Commit changes to the given files into the repository. Unlike a
720 centralized RCS, this operation is a local operation. See
726 centralized RCS, this operation is a local operation. See
721 :hg:`push` for a way to actively distribute your changes.
727 :hg:`push` for a way to actively distribute your changes.
722
728
723 If a list of files is omitted, all changes reported by :hg:`status`
729 If a list of files is omitted, all changes reported by :hg:`status`
724 will be committed.
730 will be committed.
725
731
726 If you are committing the result of a merge, do not provide any
732 If you are committing the result of a merge, do not provide any
727 filenames or -I/-X filters.
733 filenames or -I/-X filters.
728
734
729 If no commit message is specified, Mercurial starts your
735 If no commit message is specified, Mercurial starts your
730 configured editor where you can enter a message. In case your
736 configured editor where you can enter a message. In case your
731 commit fails, you will find a backup of your message in
737 commit fails, you will find a backup of your message in
732 ``.hg/last-message.txt``.
738 ``.hg/last-message.txt``.
733
739
734 See :hg:`help dates` for a list of formats valid for -d/--date.
740 See :hg:`help dates` for a list of formats valid for -d/--date.
735
741
736 Returns 0 on success, 1 if nothing changed.
742 Returns 0 on success, 1 if nothing changed.
737 """
743 """
738 extra = {}
744 extra = {}
739 if opts.get('close_branch'):
745 if opts.get('close_branch'):
740 if repo['.'].node() not in repo.branchheads():
746 if repo['.'].node() not in repo.branchheads():
741 # The topo heads set is included in the branch heads set of the
747 # The topo heads set is included in the branch heads set of the
742 # current branch, so it's sufficient to test branchheads
748 # current branch, so it's sufficient to test branchheads
743 raise util.Abort(_('can only close branch heads'))
749 raise util.Abort(_('can only close branch heads'))
744 extra['close'] = 1
750 extra['close'] = 1
745 e = cmdutil.commiteditor
751 e = cmdutil.commiteditor
746 if opts.get('force_editor'):
752 if opts.get('force_editor'):
747 e = cmdutil.commitforceeditor
753 e = cmdutil.commitforceeditor
748
754
749 def commitfunc(ui, repo, message, match, opts):
755 def commitfunc(ui, repo, message, match, opts):
750 return repo.commit(message, opts.get('user'), opts.get('date'), match,
756 return repo.commit(message, opts.get('user'), opts.get('date'), match,
751 editor=e, extra=extra)
757 editor=e, extra=extra)
752
758
753 branch = repo[None].branch()
759 branch = repo[None].branch()
754 bheads = repo.branchheads(branch)
760 bheads = repo.branchheads(branch)
755
761
756 node = cmdutil.commit(ui, repo, commitfunc, pats, opts)
762 node = cmdutil.commit(ui, repo, commitfunc, pats, opts)
757 if not node:
763 if not node:
758 ui.status(_("nothing changed\n"))
764 ui.status(_("nothing changed\n"))
759 return 1
765 return 1
760
766
761 ctx = repo[node]
767 ctx = repo[node]
762 parents = ctx.parents()
768 parents = ctx.parents()
763
769
764 if bheads and not [x for x in parents
770 if bheads and not [x for x in parents
765 if x.node() in bheads and x.branch() == branch]:
771 if x.node() in bheads and x.branch() == branch]:
766 ui.status(_('created new head\n'))
772 ui.status(_('created new head\n'))
767 # The message is not printed for initial roots. For the other
773 # The message is not printed for initial roots. For the other
768 # changesets, it is printed in the following situations:
774 # changesets, it is printed in the following situations:
769 #
775 #
770 # Par column: for the 2 parents with ...
776 # Par column: for the 2 parents with ...
771 # N: null or no parent
777 # N: null or no parent
772 # B: parent is on another named branch
778 # B: parent is on another named branch
773 # C: parent is a regular non head changeset
779 # C: parent is a regular non head changeset
774 # H: parent was a branch head of the current branch
780 # H: parent was a branch head of the current branch
775 # Msg column: whether we print "created new head" message
781 # Msg column: whether we print "created new head" message
776 # In the following, it is assumed that there already exists some
782 # In the following, it is assumed that there already exists some
777 # initial branch heads of the current branch, otherwise nothing is
783 # initial branch heads of the current branch, otherwise nothing is
778 # printed anyway.
784 # printed anyway.
779 #
785 #
780 # Par Msg Comment
786 # Par Msg Comment
781 # NN y additional topo root
787 # NN y additional topo root
782 #
788 #
783 # BN y additional branch root
789 # BN y additional branch root
784 # CN y additional topo head
790 # CN y additional topo head
785 # HN n usual case
791 # HN n usual case
786 #
792 #
787 # BB y weird additional branch root
793 # BB y weird additional branch root
788 # CB y branch merge
794 # CB y branch merge
789 # HB n merge with named branch
795 # HB n merge with named branch
790 #
796 #
791 # CC y additional head from merge
797 # CC y additional head from merge
792 # CH n merge with a head
798 # CH n merge with a head
793 #
799 #
794 # HH n head merge: head count decreases
800 # HH n head merge: head count decreases
795
801
796 if not opts.get('close_branch'):
802 if not opts.get('close_branch'):
797 for r in parents:
803 for r in parents:
798 if r.extra().get('close') and r.branch() == branch:
804 if r.extra().get('close') and r.branch() == branch:
799 ui.status(_('reopening closed branch head %d\n') % r)
805 ui.status(_('reopening closed branch head %d\n') % r)
800
806
801 if ui.debugflag:
807 if ui.debugflag:
802 ui.write(_('committed changeset %d:%s\n') % (int(ctx), ctx.hex()))
808 ui.write(_('committed changeset %d:%s\n') % (int(ctx), ctx.hex()))
803 elif ui.verbose:
809 elif ui.verbose:
804 ui.write(_('committed changeset %d:%s\n') % (int(ctx), ctx))
810 ui.write(_('committed changeset %d:%s\n') % (int(ctx), ctx))
805
811
806 def copy(ui, repo, *pats, **opts):
812 def copy(ui, repo, *pats, **opts):
807 """mark files as copied for the next commit
813 """mark files as copied for the next commit
808
814
809 Mark dest as having copies of source files. If dest is a
815 Mark dest as having copies of source files. If dest is a
810 directory, copies are put in that directory. If dest is a file,
816 directory, copies are put in that directory. If dest is a file,
811 the source must be a single file.
817 the source must be a single file.
812
818
813 By default, this command copies the contents of files as they
819 By default, this command copies the contents of files as they
814 exist in the working directory. If invoked with -A/--after, the
820 exist in the working directory. If invoked with -A/--after, the
815 operation is recorded, but no copying is performed.
821 operation is recorded, but no copying is performed.
816
822
817 This command takes effect with the next commit. To undo a copy
823 This command takes effect with the next commit. To undo a copy
818 before that, see :hg:`revert`.
824 before that, see :hg:`revert`.
819
825
820 Returns 0 on success, 1 if errors are encountered.
826 Returns 0 on success, 1 if errors are encountered.
821 """
827 """
822 wlock = repo.wlock(False)
828 wlock = repo.wlock(False)
823 try:
829 try:
824 return cmdutil.copy(ui, repo, pats, opts)
830 return cmdutil.copy(ui, repo, pats, opts)
825 finally:
831 finally:
826 wlock.release()
832 wlock.release()
827
833
828 def debugancestor(ui, repo, *args):
834 def debugancestor(ui, repo, *args):
829 """find the ancestor revision of two revisions in a given index"""
835 """find the ancestor revision of two revisions in a given index"""
830 if len(args) == 3:
836 if len(args) == 3:
831 index, rev1, rev2 = args
837 index, rev1, rev2 = args
832 r = revlog.revlog(util.opener(os.getcwd(), audit=False), index)
838 r = revlog.revlog(util.opener(os.getcwd(), audit=False), index)
833 lookup = r.lookup
839 lookup = r.lookup
834 elif len(args) == 2:
840 elif len(args) == 2:
835 if not repo:
841 if not repo:
836 raise util.Abort(_("There is no Mercurial repository here "
842 raise util.Abort(_("There is no Mercurial repository here "
837 "(.hg not found)"))
843 "(.hg not found)"))
838 rev1, rev2 = args
844 rev1, rev2 = args
839 r = repo.changelog
845 r = repo.changelog
840 lookup = repo.lookup
846 lookup = repo.lookup
841 else:
847 else:
842 raise util.Abort(_('either two or three arguments required'))
848 raise util.Abort(_('either two or three arguments required'))
843 a = r.ancestor(lookup(rev1), lookup(rev2))
849 a = r.ancestor(lookup(rev1), lookup(rev2))
844 ui.write("%d:%s\n" % (r.rev(a), hex(a)))
850 ui.write("%d:%s\n" % (r.rev(a), hex(a)))
845
851
846 def debugbuilddag(ui, repo, text,
852 def debugbuilddag(ui, repo, text,
847 mergeable_file=False,
853 mergeable_file=False,
848 appended_file=False,
854 appended_file=False,
849 overwritten_file=False,
855 overwritten_file=False,
850 new_file=False):
856 new_file=False):
851 """builds a repo with a given dag from scratch in the current empty repo
857 """builds a repo with a given dag from scratch in the current empty repo
852
858
853 Elements:
859 Elements:
854
860
855 - "+n" is a linear run of n nodes based on the current default parent
861 - "+n" is a linear run of n nodes based on the current default parent
856 - "." is a single node based on the current default parent
862 - "." is a single node based on the current default parent
857 - "$" resets the default parent to null (implied at the start);
863 - "$" resets the default parent to null (implied at the start);
858 otherwise the default parent is always the last node created
864 otherwise the default parent is always the last node created
859 - "<p" sets the default parent to the backref p
865 - "<p" sets the default parent to the backref p
860 - "*p" is a fork at parent p, which is a backref
866 - "*p" is a fork at parent p, which is a backref
861 - "*p1/p2" is a merge of parents p1 and p2, which are backrefs
867 - "*p1/p2" is a merge of parents p1 and p2, which are backrefs
862 - "/p2" is a merge of the preceding node and p2
868 - "/p2" is a merge of the preceding node and p2
863 - ":tag" defines a local tag for the preceding node
869 - ":tag" defines a local tag for the preceding node
864 - "@branch" sets the named branch for subsequent nodes
870 - "@branch" sets the named branch for subsequent nodes
865 - "!command" runs the command using your shell
871 - "!command" runs the command using your shell
866 - "!!my command\\n" is like "!", but to the end of the line
872 - "!!my command\\n" is like "!", but to the end of the line
867 - "#...\\n" is a comment up to the end of the line
873 - "#...\\n" is a comment up to the end of the line
868
874
869 Whitespace between the above elements is ignored.
875 Whitespace between the above elements is ignored.
870
876
871 A backref is either
877 A backref is either
872
878
873 - a number n, which references the node curr-n, where curr is the current
879 - a number n, which references the node curr-n, where curr is the current
874 node, or
880 node, or
875 - the name of a local tag you placed earlier using ":tag", or
881 - the name of a local tag you placed earlier using ":tag", or
876 - empty to denote the default parent.
882 - empty to denote the default parent.
877
883
878 All string valued-elements are either strictly alphanumeric, or must
884 All string valued-elements are either strictly alphanumeric, or must
879 be enclosed in double quotes ("..."), with "\\" as escape character.
885 be enclosed in double quotes ("..."), with "\\" as escape character.
880
886
881 Note that the --overwritten-file and --appended-file options imply the
887 Note that the --overwritten-file and --appended-file options imply the
882 use of "HGMERGE=internal:local" during DAG buildup.
888 use of "HGMERGE=internal:local" during DAG buildup.
883 """
889 """
884
890
885 if not (mergeable_file or appended_file or overwritten_file or new_file):
891 if not (mergeable_file or appended_file or overwritten_file or new_file):
886 raise util.Abort(_('need at least one of -m, -a, -o, -n'))
892 raise util.Abort(_('need at least one of -m, -a, -o, -n'))
887
893
888 if len(repo.changelog) > 0:
894 if len(repo.changelog) > 0:
889 raise util.Abort(_('repository is not empty'))
895 raise util.Abort(_('repository is not empty'))
890
896
891 if overwritten_file or appended_file:
897 if overwritten_file or appended_file:
892 # we don't want to fail in merges during buildup
898 # we don't want to fail in merges during buildup
893 os.environ['HGMERGE'] = 'internal:local'
899 os.environ['HGMERGE'] = 'internal:local'
894
900
895 def writefile(fname, text, fmode="wb"):
901 def writefile(fname, text, fmode="wb"):
896 f = open(fname, fmode)
902 f = open(fname, fmode)
897 try:
903 try:
898 f.write(text)
904 f.write(text)
899 finally:
905 finally:
900 f.close()
906 f.close()
901
907
902 if mergeable_file:
908 if mergeable_file:
903 linesperrev = 2
909 linesperrev = 2
904 # determine number of revs in DAG
910 # determine number of revs in DAG
905 n = 0
911 n = 0
906 for type, data in dagparser.parsedag(text):
912 for type, data in dagparser.parsedag(text):
907 if type == 'n':
913 if type == 'n':
908 n += 1
914 n += 1
909 # make a file with k lines per rev
915 # make a file with k lines per rev
910 writefile("mf", "\n".join(str(i) for i in xrange(0, n * linesperrev))
916 writefile("mf", "\n".join(str(i) for i in xrange(0, n * linesperrev))
911 + "\n")
917 + "\n")
912
918
913 at = -1
919 at = -1
914 atbranch = 'default'
920 atbranch = 'default'
915 for type, data in dagparser.parsedag(text):
921 for type, data in dagparser.parsedag(text):
916 if type == 'n':
922 if type == 'n':
917 ui.status('node %s\n' % str(data))
923 ui.status('node %s\n' % str(data))
918 id, ps = data
924 id, ps = data
919 p1 = ps[0]
925 p1 = ps[0]
920 if p1 != at:
926 if p1 != at:
921 update(ui, repo, node=p1, clean=True)
927 update(ui, repo, node=p1, clean=True)
922 at = p1
928 at = p1
923 if repo.dirstate.branch() != atbranch:
929 if repo.dirstate.branch() != atbranch:
924 branch(ui, repo, atbranch, force=True)
930 branch(ui, repo, atbranch, force=True)
925 if len(ps) > 1:
931 if len(ps) > 1:
926 p2 = ps[1]
932 p2 = ps[1]
927 merge(ui, repo, node=p2)
933 merge(ui, repo, node=p2)
928
934
929 if mergeable_file:
935 if mergeable_file:
930 f = open("mf", "rb+")
936 f = open("mf", "rb+")
931 try:
937 try:
932 lines = f.read().split("\n")
938 lines = f.read().split("\n")
933 lines[id * linesperrev] += " r%i" % id
939 lines[id * linesperrev] += " r%i" % id
934 f.seek(0)
940 f.seek(0)
935 f.write("\n".join(lines))
941 f.write("\n".join(lines))
936 finally:
942 finally:
937 f.close()
943 f.close()
938
944
939 if appended_file:
945 if appended_file:
940 writefile("af", "r%i\n" % id, "ab")
946 writefile("af", "r%i\n" % id, "ab")
941
947
942 if overwritten_file:
948 if overwritten_file:
943 writefile("of", "r%i\n" % id)
949 writefile("of", "r%i\n" % id)
944
950
945 if new_file:
951 if new_file:
946 writefile("nf%i" % id, "r%i\n" % id)
952 writefile("nf%i" % id, "r%i\n" % id)
947
953
948 commit(ui, repo, addremove=True, message="r%i" % id, date=(id, 0))
954 commit(ui, repo, addremove=True, message="r%i" % id, date=(id, 0))
949 at = id
955 at = id
950 elif type == 'l':
956 elif type == 'l':
951 id, name = data
957 id, name = data
952 ui.status('tag %s\n' % name)
958 ui.status('tag %s\n' % name)
953 tag(ui, repo, name, local=True)
959 tag(ui, repo, name, local=True)
954 elif type == 'a':
960 elif type == 'a':
955 ui.status('branch %s\n' % data)
961 ui.status('branch %s\n' % data)
956 atbranch = data
962 atbranch = data
957 elif type in 'cC':
963 elif type in 'cC':
958 r = util.system(data, cwd=repo.root)
964 r = util.system(data, cwd=repo.root)
959 if r:
965 if r:
960 desc, r = util.explain_exit(r)
966 desc, r = util.explain_exit(r)
961 raise util.Abort(_('%s command %s') % (data, desc))
967 raise util.Abort(_('%s command %s') % (data, desc))
962
968
963 def debugcommands(ui, cmd='', *args):
969 def debugcommands(ui, cmd='', *args):
964 """list all available commands and options"""
970 """list all available commands and options"""
965 for cmd, vals in sorted(table.iteritems()):
971 for cmd, vals in sorted(table.iteritems()):
966 cmd = cmd.split('|')[0].strip('^')
972 cmd = cmd.split('|')[0].strip('^')
967 opts = ', '.join([i[1] for i in vals[1]])
973 opts = ', '.join([i[1] for i in vals[1]])
968 ui.write('%s: %s\n' % (cmd, opts))
974 ui.write('%s: %s\n' % (cmd, opts))
969
975
970 def debugcomplete(ui, cmd='', **opts):
976 def debugcomplete(ui, cmd='', **opts):
971 """returns the completion list associated with the given command"""
977 """returns the completion list associated with the given command"""
972
978
973 if opts.get('options'):
979 if opts.get('options'):
974 options = []
980 options = []
975 otables = [globalopts]
981 otables = [globalopts]
976 if cmd:
982 if cmd:
977 aliases, entry = cmdutil.findcmd(cmd, table, False)
983 aliases, entry = cmdutil.findcmd(cmd, table, False)
978 otables.append(entry[1])
984 otables.append(entry[1])
979 for t in otables:
985 for t in otables:
980 for o in t:
986 for o in t:
981 if "(DEPRECATED)" in o[3]:
987 if "(DEPRECATED)" in o[3]:
982 continue
988 continue
983 if o[0]:
989 if o[0]:
984 options.append('-%s' % o[0])
990 options.append('-%s' % o[0])
985 options.append('--%s' % o[1])
991 options.append('--%s' % o[1])
986 ui.write("%s\n" % "\n".join(options))
992 ui.write("%s\n" % "\n".join(options))
987 return
993 return
988
994
989 cmdlist = cmdutil.findpossible(cmd, table)
995 cmdlist = cmdutil.findpossible(cmd, table)
990 if ui.verbose:
996 if ui.verbose:
991 cmdlist = [' '.join(c[0]) for c in cmdlist.values()]
997 cmdlist = [' '.join(c[0]) for c in cmdlist.values()]
992 ui.write("%s\n" % "\n".join(sorted(cmdlist)))
998 ui.write("%s\n" % "\n".join(sorted(cmdlist)))
993
999
994 def debugfsinfo(ui, path = "."):
1000 def debugfsinfo(ui, path = "."):
995 """show information detected about current filesystem"""
1001 """show information detected about current filesystem"""
996 open('.debugfsinfo', 'w').write('')
1002 open('.debugfsinfo', 'w').write('')
997 ui.write('exec: %s\n' % (util.checkexec(path) and 'yes' or 'no'))
1003 ui.write('exec: %s\n' % (util.checkexec(path) and 'yes' or 'no'))
998 ui.write('symlink: %s\n' % (util.checklink(path) and 'yes' or 'no'))
1004 ui.write('symlink: %s\n' % (util.checklink(path) and 'yes' or 'no'))
999 ui.write('case-sensitive: %s\n' % (util.checkcase('.debugfsinfo')
1005 ui.write('case-sensitive: %s\n' % (util.checkcase('.debugfsinfo')
1000 and 'yes' or 'no'))
1006 and 'yes' or 'no'))
1001 os.unlink('.debugfsinfo')
1007 os.unlink('.debugfsinfo')
1002
1008
1003 def debugrebuildstate(ui, repo, rev="tip"):
1009 def debugrebuildstate(ui, repo, rev="tip"):
1004 """rebuild the dirstate as it would look like for the given revision"""
1010 """rebuild the dirstate as it would look like for the given revision"""
1005 ctx = repo[rev]
1011 ctx = repo[rev]
1006 wlock = repo.wlock()
1012 wlock = repo.wlock()
1007 try:
1013 try:
1008 repo.dirstate.rebuild(ctx.node(), ctx.manifest())
1014 repo.dirstate.rebuild(ctx.node(), ctx.manifest())
1009 finally:
1015 finally:
1010 wlock.release()
1016 wlock.release()
1011
1017
1012 def debugcheckstate(ui, repo):
1018 def debugcheckstate(ui, repo):
1013 """validate the correctness of the current dirstate"""
1019 """validate the correctness of the current dirstate"""
1014 parent1, parent2 = repo.dirstate.parents()
1020 parent1, parent2 = repo.dirstate.parents()
1015 m1 = repo[parent1].manifest()
1021 m1 = repo[parent1].manifest()
1016 m2 = repo[parent2].manifest()
1022 m2 = repo[parent2].manifest()
1017 errors = 0
1023 errors = 0
1018 for f in repo.dirstate:
1024 for f in repo.dirstate:
1019 state = repo.dirstate[f]
1025 state = repo.dirstate[f]
1020 if state in "nr" and f not in m1:
1026 if state in "nr" and f not in m1:
1021 ui.warn(_("%s in state %s, but not in manifest1\n") % (f, state))
1027 ui.warn(_("%s in state %s, but not in manifest1\n") % (f, state))
1022 errors += 1
1028 errors += 1
1023 if state in "a" and f in m1:
1029 if state in "a" and f in m1:
1024 ui.warn(_("%s in state %s, but also in manifest1\n") % (f, state))
1030 ui.warn(_("%s in state %s, but also in manifest1\n") % (f, state))
1025 errors += 1
1031 errors += 1
1026 if state in "m" and f not in m1 and f not in m2:
1032 if state in "m" and f not in m1 and f not in m2:
1027 ui.warn(_("%s in state %s, but not in either manifest\n") %
1033 ui.warn(_("%s in state %s, but not in either manifest\n") %
1028 (f, state))
1034 (f, state))
1029 errors += 1
1035 errors += 1
1030 for f in m1:
1036 for f in m1:
1031 state = repo.dirstate[f]
1037 state = repo.dirstate[f]
1032 if state not in "nrm":
1038 if state not in "nrm":
1033 ui.warn(_("%s in manifest1, but listed as state %s") % (f, state))
1039 ui.warn(_("%s in manifest1, but listed as state %s") % (f, state))
1034 errors += 1
1040 errors += 1
1035 if errors:
1041 if errors:
1036 error = _(".hg/dirstate inconsistent with current parent's manifest")
1042 error = _(".hg/dirstate inconsistent with current parent's manifest")
1037 raise util.Abort(error)
1043 raise util.Abort(error)
1038
1044
1039 def showconfig(ui, repo, *values, **opts):
1045 def showconfig(ui, repo, *values, **opts):
1040 """show combined config settings from all hgrc files
1046 """show combined config settings from all hgrc files
1041
1047
1042 With no arguments, print names and values of all config items.
1048 With no arguments, print names and values of all config items.
1043
1049
1044 With one argument of the form section.name, print just the value
1050 With one argument of the form section.name, print just the value
1045 of that config item.
1051 of that config item.
1046
1052
1047 With multiple arguments, print names and values of all config
1053 With multiple arguments, print names and values of all config
1048 items with matching section names.
1054 items with matching section names.
1049
1055
1050 With --debug, the source (filename and line number) is printed
1056 With --debug, the source (filename and line number) is printed
1051 for each config item.
1057 for each config item.
1052
1058
1053 Returns 0 on success.
1059 Returns 0 on success.
1054 """
1060 """
1055
1061
1056 for f in util.rcpath():
1062 for f in util.rcpath():
1057 ui.debug(_('read config from: %s\n') % f)
1063 ui.debug(_('read config from: %s\n') % f)
1058 untrusted = bool(opts.get('untrusted'))
1064 untrusted = bool(opts.get('untrusted'))
1059 if values:
1065 if values:
1060 if len([v for v in values if '.' in v]) > 1:
1066 if len([v for v in values if '.' in v]) > 1:
1061 raise util.Abort(_('only one config item permitted'))
1067 raise util.Abort(_('only one config item permitted'))
1062 for section, name, value in ui.walkconfig(untrusted=untrusted):
1068 for section, name, value in ui.walkconfig(untrusted=untrusted):
1063 sectname = section + '.' + name
1069 sectname = section + '.' + name
1064 if values:
1070 if values:
1065 for v in values:
1071 for v in values:
1066 if v == section:
1072 if v == section:
1067 ui.debug('%s: ' %
1073 ui.debug('%s: ' %
1068 ui.configsource(section, name, untrusted))
1074 ui.configsource(section, name, untrusted))
1069 ui.write('%s=%s\n' % (sectname, value))
1075 ui.write('%s=%s\n' % (sectname, value))
1070 elif v == sectname:
1076 elif v == sectname:
1071 ui.debug('%s: ' %
1077 ui.debug('%s: ' %
1072 ui.configsource(section, name, untrusted))
1078 ui.configsource(section, name, untrusted))
1073 ui.write(value, '\n')
1079 ui.write(value, '\n')
1074 else:
1080 else:
1075 ui.debug('%s: ' %
1081 ui.debug('%s: ' %
1076 ui.configsource(section, name, untrusted))
1082 ui.configsource(section, name, untrusted))
1077 ui.write('%s=%s\n' % (sectname, value))
1083 ui.write('%s=%s\n' % (sectname, value))
1078
1084
1079 def debugpushkey(ui, repopath, namespace, *keyinfo):
1085 def debugpushkey(ui, repopath, namespace, *keyinfo):
1080 '''access the pushkey key/value protocol
1086 '''access the pushkey key/value protocol
1081
1087
1082 With two args, list the keys in the given namespace.
1088 With two args, list the keys in the given namespace.
1083
1089
1084 With five args, set a key to new if it currently is set to old.
1090 With five args, set a key to new if it currently is set to old.
1085 Reports success or failure.
1091 Reports success or failure.
1086 '''
1092 '''
1087
1093
1088 target = hg.repository(ui, repopath)
1094 target = hg.repository(ui, repopath)
1089 if keyinfo:
1095 if keyinfo:
1090 key, old, new = keyinfo
1096 key, old, new = keyinfo
1091 r = target.pushkey(namespace, key, old, new)
1097 r = target.pushkey(namespace, key, old, new)
1092 ui.status(str(r) + '\n')
1098 ui.status(str(r) + '\n')
1093 return not(r)
1099 return not(r)
1094 else:
1100 else:
1095 for k, v in target.listkeys(namespace).iteritems():
1101 for k, v in target.listkeys(namespace).iteritems():
1096 ui.write("%s\t%s\n" % (k.encode('string-escape'),
1102 ui.write("%s\t%s\n" % (k.encode('string-escape'),
1097 v.encode('string-escape')))
1103 v.encode('string-escape')))
1098
1104
1099 def debugrevspec(ui, repo, expr):
1105 def debugrevspec(ui, repo, expr):
1100 '''parse and apply a revision specification'''
1106 '''parse and apply a revision specification'''
1101 if ui.verbose:
1107 if ui.verbose:
1102 tree = revset.parse(expr)
1108 tree = revset.parse(expr)
1103 ui.note(tree, "\n")
1109 ui.note(tree, "\n")
1104 func = revset.match(expr)
1110 func = revset.match(expr)
1105 for c in func(repo, range(len(repo))):
1111 for c in func(repo, range(len(repo))):
1106 ui.write("%s\n" % c)
1112 ui.write("%s\n" % c)
1107
1113
1108 def debugsetparents(ui, repo, rev1, rev2=None):
1114 def debugsetparents(ui, repo, rev1, rev2=None):
1109 """manually set the parents of the current working directory
1115 """manually set the parents of the current working directory
1110
1116
1111 This is useful for writing repository conversion tools, but should
1117 This is useful for writing repository conversion tools, but should
1112 be used with care.
1118 be used with care.
1113
1119
1114 Returns 0 on success.
1120 Returns 0 on success.
1115 """
1121 """
1116
1122
1117 if not rev2:
1123 if not rev2:
1118 rev2 = hex(nullid)
1124 rev2 = hex(nullid)
1119
1125
1120 wlock = repo.wlock()
1126 wlock = repo.wlock()
1121 try:
1127 try:
1122 repo.dirstate.setparents(repo.lookup(rev1), repo.lookup(rev2))
1128 repo.dirstate.setparents(repo.lookup(rev1), repo.lookup(rev2))
1123 finally:
1129 finally:
1124 wlock.release()
1130 wlock.release()
1125
1131
1126 def debugstate(ui, repo, nodates=None):
1132 def debugstate(ui, repo, nodates=None):
1127 """show the contents of the current dirstate"""
1133 """show the contents of the current dirstate"""
1128 timestr = ""
1134 timestr = ""
1129 showdate = not nodates
1135 showdate = not nodates
1130 for file_, ent in sorted(repo.dirstate._map.iteritems()):
1136 for file_, ent in sorted(repo.dirstate._map.iteritems()):
1131 if showdate:
1137 if showdate:
1132 if ent[3] == -1:
1138 if ent[3] == -1:
1133 # Pad or slice to locale representation
1139 # Pad or slice to locale representation
1134 locale_len = len(time.strftime("%Y-%m-%d %H:%M:%S ",
1140 locale_len = len(time.strftime("%Y-%m-%d %H:%M:%S ",
1135 time.localtime(0)))
1141 time.localtime(0)))
1136 timestr = 'unset'
1142 timestr = 'unset'
1137 timestr = (timestr[:locale_len] +
1143 timestr = (timestr[:locale_len] +
1138 ' ' * (locale_len - len(timestr)))
1144 ' ' * (locale_len - len(timestr)))
1139 else:
1145 else:
1140 timestr = time.strftime("%Y-%m-%d %H:%M:%S ",
1146 timestr = time.strftime("%Y-%m-%d %H:%M:%S ",
1141 time.localtime(ent[3]))
1147 time.localtime(ent[3]))
1142 if ent[1] & 020000:
1148 if ent[1] & 020000:
1143 mode = 'lnk'
1149 mode = 'lnk'
1144 else:
1150 else:
1145 mode = '%3o' % (ent[1] & 0777)
1151 mode = '%3o' % (ent[1] & 0777)
1146 ui.write("%c %s %10d %s%s\n" % (ent[0], mode, ent[2], timestr, file_))
1152 ui.write("%c %s %10d %s%s\n" % (ent[0], mode, ent[2], timestr, file_))
1147 for f in repo.dirstate.copies():
1153 for f in repo.dirstate.copies():
1148 ui.write(_("copy: %s -> %s\n") % (repo.dirstate.copied(f), f))
1154 ui.write(_("copy: %s -> %s\n") % (repo.dirstate.copied(f), f))
1149
1155
1150 def debugsub(ui, repo, rev=None):
1156 def debugsub(ui, repo, rev=None):
1151 if rev == '':
1157 if rev == '':
1152 rev = None
1158 rev = None
1153 for k, v in sorted(repo[rev].substate.items()):
1159 for k, v in sorted(repo[rev].substate.items()):
1154 ui.write('path %s\n' % k)
1160 ui.write('path %s\n' % k)
1155 ui.write(' source %s\n' % v[0])
1161 ui.write(' source %s\n' % v[0])
1156 ui.write(' revision %s\n' % v[1])
1162 ui.write(' revision %s\n' % v[1])
1157
1163
1158 def debugdag(ui, repo, file_=None, *revs, **opts):
1164 def debugdag(ui, repo, file_=None, *revs, **opts):
1159 """format the changelog or an index DAG as a concise textual description
1165 """format the changelog or an index DAG as a concise textual description
1160
1166
1161 If you pass a revlog index, the revlog's DAG is emitted. If you list
1167 If you pass a revlog index, the revlog's DAG is emitted. If you list
1162 revision numbers, they get labelled in the output as rN.
1168 revision numbers, they get labelled in the output as rN.
1163
1169
1164 Otherwise, the changelog DAG of the current repo is emitted.
1170 Otherwise, the changelog DAG of the current repo is emitted.
1165 """
1171 """
1166 spaces = opts.get('spaces')
1172 spaces = opts.get('spaces')
1167 dots = opts.get('dots')
1173 dots = opts.get('dots')
1168 if file_:
1174 if file_:
1169 rlog = revlog.revlog(util.opener(os.getcwd(), audit=False), file_)
1175 rlog = revlog.revlog(util.opener(os.getcwd(), audit=False), file_)
1170 revs = set((int(r) for r in revs))
1176 revs = set((int(r) for r in revs))
1171 def events():
1177 def events():
1172 for r in rlog:
1178 for r in rlog:
1173 yield 'n', (r, list(set(p for p in rlog.parentrevs(r) if p != -1)))
1179 yield 'n', (r, list(set(p for p in rlog.parentrevs(r) if p != -1)))
1174 if r in revs:
1180 if r in revs:
1175 yield 'l', (r, "r%i" % r)
1181 yield 'l', (r, "r%i" % r)
1176 elif repo:
1182 elif repo:
1177 cl = repo.changelog
1183 cl = repo.changelog
1178 tags = opts.get('tags')
1184 tags = opts.get('tags')
1179 branches = opts.get('branches')
1185 branches = opts.get('branches')
1180 if tags:
1186 if tags:
1181 labels = {}
1187 labels = {}
1182 for l, n in repo.tags().items():
1188 for l, n in repo.tags().items():
1183 labels.setdefault(cl.rev(n), []).append(l)
1189 labels.setdefault(cl.rev(n), []).append(l)
1184 def events():
1190 def events():
1185 b = "default"
1191 b = "default"
1186 for r in cl:
1192 for r in cl:
1187 if branches:
1193 if branches:
1188 newb = cl.read(cl.node(r))[5]['branch']
1194 newb = cl.read(cl.node(r))[5]['branch']
1189 if newb != b:
1195 if newb != b:
1190 yield 'a', newb
1196 yield 'a', newb
1191 b = newb
1197 b = newb
1192 yield 'n', (r, list(set(p for p in cl.parentrevs(r) if p != -1)))
1198 yield 'n', (r, list(set(p for p in cl.parentrevs(r) if p != -1)))
1193 if tags:
1199 if tags:
1194 ls = labels.get(r)
1200 ls = labels.get(r)
1195 if ls:
1201 if ls:
1196 for l in ls:
1202 for l in ls:
1197 yield 'l', (r, l)
1203 yield 'l', (r, l)
1198 else:
1204 else:
1199 raise util.Abort(_('need repo for changelog dag'))
1205 raise util.Abort(_('need repo for changelog dag'))
1200
1206
1201 for line in dagparser.dagtextlines(events(),
1207 for line in dagparser.dagtextlines(events(),
1202 addspaces=spaces,
1208 addspaces=spaces,
1203 wraplabels=True,
1209 wraplabels=True,
1204 wrapannotations=True,
1210 wrapannotations=True,
1205 wrapnonlinear=dots,
1211 wrapnonlinear=dots,
1206 usedots=dots,
1212 usedots=dots,
1207 maxlinewidth=70):
1213 maxlinewidth=70):
1208 ui.write(line)
1214 ui.write(line)
1209 ui.write("\n")
1215 ui.write("\n")
1210
1216
1211 def debugdata(ui, file_, rev):
1217 def debugdata(ui, file_, rev):
1212 """dump the contents of a data file revision"""
1218 """dump the contents of a data file revision"""
1213 r = revlog.revlog(util.opener(os.getcwd(), audit=False), file_[:-2] + ".i")
1219 r = revlog.revlog(util.opener(os.getcwd(), audit=False), file_[:-2] + ".i")
1214 try:
1220 try:
1215 ui.write(r.revision(r.lookup(rev)))
1221 ui.write(r.revision(r.lookup(rev)))
1216 except KeyError:
1222 except KeyError:
1217 raise util.Abort(_('invalid revision identifier %s') % rev)
1223 raise util.Abort(_('invalid revision identifier %s') % rev)
1218
1224
1219 def debugdate(ui, date, range=None, **opts):
1225 def debugdate(ui, date, range=None, **opts):
1220 """parse and display a date"""
1226 """parse and display a date"""
1221 if opts["extended"]:
1227 if opts["extended"]:
1222 d = util.parsedate(date, util.extendeddateformats)
1228 d = util.parsedate(date, util.extendeddateformats)
1223 else:
1229 else:
1224 d = util.parsedate(date)
1230 d = util.parsedate(date)
1225 ui.write("internal: %s %s\n" % d)
1231 ui.write("internal: %s %s\n" % d)
1226 ui.write("standard: %s\n" % util.datestr(d))
1232 ui.write("standard: %s\n" % util.datestr(d))
1227 if range:
1233 if range:
1228 m = util.matchdate(range)
1234 m = util.matchdate(range)
1229 ui.write("match: %s\n" % m(d[0]))
1235 ui.write("match: %s\n" % m(d[0]))
1230
1236
1231 def debugindex(ui, file_):
1237 def debugindex(ui, file_):
1232 """dump the contents of an index file"""
1238 """dump the contents of an index file"""
1233 r = revlog.revlog(util.opener(os.getcwd(), audit=False), file_)
1239 r = revlog.revlog(util.opener(os.getcwd(), audit=False), file_)
1234 ui.write(" rev offset length base linkrev"
1240 ui.write(" rev offset length base linkrev"
1235 " nodeid p1 p2\n")
1241 " nodeid p1 p2\n")
1236 for i in r:
1242 for i in r:
1237 node = r.node(i)
1243 node = r.node(i)
1238 try:
1244 try:
1239 pp = r.parents(node)
1245 pp = r.parents(node)
1240 except:
1246 except:
1241 pp = [nullid, nullid]
1247 pp = [nullid, nullid]
1242 ui.write("% 6d % 9d % 7d % 6d % 7d %s %s %s\n" % (
1248 ui.write("% 6d % 9d % 7d % 6d % 7d %s %s %s\n" % (
1243 i, r.start(i), r.length(i), r.base(i), r.linkrev(i),
1249 i, r.start(i), r.length(i), r.base(i), r.linkrev(i),
1244 short(node), short(pp[0]), short(pp[1])))
1250 short(node), short(pp[0]), short(pp[1])))
1245
1251
1246 def debugindexdot(ui, file_):
1252 def debugindexdot(ui, file_):
1247 """dump an index DAG as a graphviz dot file"""
1253 """dump an index DAG as a graphviz dot file"""
1248 r = revlog.revlog(util.opener(os.getcwd(), audit=False), file_)
1254 r = revlog.revlog(util.opener(os.getcwd(), audit=False), file_)
1249 ui.write("digraph G {\n")
1255 ui.write("digraph G {\n")
1250 for i in r:
1256 for i in r:
1251 node = r.node(i)
1257 node = r.node(i)
1252 pp = r.parents(node)
1258 pp = r.parents(node)
1253 ui.write("\t%d -> %d\n" % (r.rev(pp[0]), i))
1259 ui.write("\t%d -> %d\n" % (r.rev(pp[0]), i))
1254 if pp[1] != nullid:
1260 if pp[1] != nullid:
1255 ui.write("\t%d -> %d\n" % (r.rev(pp[1]), i))
1261 ui.write("\t%d -> %d\n" % (r.rev(pp[1]), i))
1256 ui.write("}\n")
1262 ui.write("}\n")
1257
1263
1258 def debuginstall(ui):
1264 def debuginstall(ui):
1259 '''test Mercurial installation
1265 '''test Mercurial installation
1260
1266
1261 Returns 0 on success.
1267 Returns 0 on success.
1262 '''
1268 '''
1263
1269
1264 def writetemp(contents):
1270 def writetemp(contents):
1265 (fd, name) = tempfile.mkstemp(prefix="hg-debuginstall-")
1271 (fd, name) = tempfile.mkstemp(prefix="hg-debuginstall-")
1266 f = os.fdopen(fd, "wb")
1272 f = os.fdopen(fd, "wb")
1267 f.write(contents)
1273 f.write(contents)
1268 f.close()
1274 f.close()
1269 return name
1275 return name
1270
1276
1271 problems = 0
1277 problems = 0
1272
1278
1273 # encoding
1279 # encoding
1274 ui.status(_("Checking encoding (%s)...\n") % encoding.encoding)
1280 ui.status(_("Checking encoding (%s)...\n") % encoding.encoding)
1275 try:
1281 try:
1276 encoding.fromlocal("test")
1282 encoding.fromlocal("test")
1277 except util.Abort, inst:
1283 except util.Abort, inst:
1278 ui.write(" %s\n" % inst)
1284 ui.write(" %s\n" % inst)
1279 ui.write(_(" (check that your locale is properly set)\n"))
1285 ui.write(_(" (check that your locale is properly set)\n"))
1280 problems += 1
1286 problems += 1
1281
1287
1282 # compiled modules
1288 # compiled modules
1283 ui.status(_("Checking extensions...\n"))
1289 ui.status(_("Checking extensions...\n"))
1284 try:
1290 try:
1285 import bdiff, mpatch, base85
1291 import bdiff, mpatch, base85
1286 except Exception, inst:
1292 except Exception, inst:
1287 ui.write(" %s\n" % inst)
1293 ui.write(" %s\n" % inst)
1288 ui.write(_(" One or more extensions could not be found"))
1294 ui.write(_(" One or more extensions could not be found"))
1289 ui.write(_(" (check that you compiled the extensions)\n"))
1295 ui.write(_(" (check that you compiled the extensions)\n"))
1290 problems += 1
1296 problems += 1
1291
1297
1292 # templates
1298 # templates
1293 ui.status(_("Checking templates...\n"))
1299 ui.status(_("Checking templates...\n"))
1294 try:
1300 try:
1295 import templater
1301 import templater
1296 templater.templater(templater.templatepath("map-cmdline.default"))
1302 templater.templater(templater.templatepath("map-cmdline.default"))
1297 except Exception, inst:
1303 except Exception, inst:
1298 ui.write(" %s\n" % inst)
1304 ui.write(" %s\n" % inst)
1299 ui.write(_(" (templates seem to have been installed incorrectly)\n"))
1305 ui.write(_(" (templates seem to have been installed incorrectly)\n"))
1300 problems += 1
1306 problems += 1
1301
1307
1302 # patch
1308 # patch
1303 ui.status(_("Checking patch...\n"))
1309 ui.status(_("Checking patch...\n"))
1304 patchproblems = 0
1310 patchproblems = 0
1305 a = "1\n2\n3\n4\n"
1311 a = "1\n2\n3\n4\n"
1306 b = "1\n2\n3\ninsert\n4\n"
1312 b = "1\n2\n3\ninsert\n4\n"
1307 fa = writetemp(a)
1313 fa = writetemp(a)
1308 d = mdiff.unidiff(a, None, b, None, os.path.basename(fa),
1314 d = mdiff.unidiff(a, None, b, None, os.path.basename(fa),
1309 os.path.basename(fa))
1315 os.path.basename(fa))
1310 fd = writetemp(d)
1316 fd = writetemp(d)
1311
1317
1312 files = {}
1318 files = {}
1313 try:
1319 try:
1314 patch.patch(fd, ui, cwd=os.path.dirname(fa), files=files)
1320 patch.patch(fd, ui, cwd=os.path.dirname(fa), files=files)
1315 except util.Abort, e:
1321 except util.Abort, e:
1316 ui.write(_(" patch call failed:\n"))
1322 ui.write(_(" patch call failed:\n"))
1317 ui.write(" " + str(e) + "\n")
1323 ui.write(" " + str(e) + "\n")
1318 patchproblems += 1
1324 patchproblems += 1
1319 else:
1325 else:
1320 if list(files) != [os.path.basename(fa)]:
1326 if list(files) != [os.path.basename(fa)]:
1321 ui.write(_(" unexpected patch output!\n"))
1327 ui.write(_(" unexpected patch output!\n"))
1322 patchproblems += 1
1328 patchproblems += 1
1323 a = open(fa).read()
1329 a = open(fa).read()
1324 if a != b:
1330 if a != b:
1325 ui.write(_(" patch test failed!\n"))
1331 ui.write(_(" patch test failed!\n"))
1326 patchproblems += 1
1332 patchproblems += 1
1327
1333
1328 if patchproblems:
1334 if patchproblems:
1329 if ui.config('ui', 'patch'):
1335 if ui.config('ui', 'patch'):
1330 ui.write(_(" (Current patch tool may be incompatible with patch,"
1336 ui.write(_(" (Current patch tool may be incompatible with patch,"
1331 " or misconfigured. Please check your .hgrc file)\n"))
1337 " or misconfigured. Please check your .hgrc file)\n"))
1332 else:
1338 else:
1333 ui.write(_(" Internal patcher failure, please report this error"
1339 ui.write(_(" Internal patcher failure, please report this error"
1334 " to http://mercurial.selenic.com/bts/\n"))
1340 " to http://mercurial.selenic.com/bts/\n"))
1335 problems += patchproblems
1341 problems += patchproblems
1336
1342
1337 os.unlink(fa)
1343 os.unlink(fa)
1338 os.unlink(fd)
1344 os.unlink(fd)
1339
1345
1340 # editor
1346 # editor
1341 ui.status(_("Checking commit editor...\n"))
1347 ui.status(_("Checking commit editor...\n"))
1342 editor = ui.geteditor()
1348 editor = ui.geteditor()
1343 cmdpath = util.find_exe(editor) or util.find_exe(editor.split()[0])
1349 cmdpath = util.find_exe(editor) or util.find_exe(editor.split()[0])
1344 if not cmdpath:
1350 if not cmdpath:
1345 if editor == 'vi':
1351 if editor == 'vi':
1346 ui.write(_(" No commit editor set and can't find vi in PATH\n"))
1352 ui.write(_(" No commit editor set and can't find vi in PATH\n"))
1347 ui.write(_(" (specify a commit editor in your .hgrc file)\n"))
1353 ui.write(_(" (specify a commit editor in your .hgrc file)\n"))
1348 else:
1354 else:
1349 ui.write(_(" Can't find editor '%s' in PATH\n") % editor)
1355 ui.write(_(" Can't find editor '%s' in PATH\n") % editor)
1350 ui.write(_(" (specify a commit editor in your .hgrc file)\n"))
1356 ui.write(_(" (specify a commit editor in your .hgrc file)\n"))
1351 problems += 1
1357 problems += 1
1352
1358
1353 # check username
1359 # check username
1354 ui.status(_("Checking username...\n"))
1360 ui.status(_("Checking username...\n"))
1355 try:
1361 try:
1356 user = ui.username()
1362 user = ui.username()
1357 except util.Abort, e:
1363 except util.Abort, e:
1358 ui.write(" %s\n" % e)
1364 ui.write(" %s\n" % e)
1359 ui.write(_(" (specify a username in your .hgrc file)\n"))
1365 ui.write(_(" (specify a username in your .hgrc file)\n"))
1360 problems += 1
1366 problems += 1
1361
1367
1362 if not problems:
1368 if not problems:
1363 ui.status(_("No problems detected\n"))
1369 ui.status(_("No problems detected\n"))
1364 else:
1370 else:
1365 ui.write(_("%s problems detected,"
1371 ui.write(_("%s problems detected,"
1366 " please check your install!\n") % problems)
1372 " please check your install!\n") % problems)
1367
1373
1368 return problems
1374 return problems
1369
1375
1370 def debugrename(ui, repo, file1, *pats, **opts):
1376 def debugrename(ui, repo, file1, *pats, **opts):
1371 """dump rename information"""
1377 """dump rename information"""
1372
1378
1373 ctx = repo[opts.get('rev')]
1379 ctx = repo[opts.get('rev')]
1374 m = cmdutil.match(repo, (file1,) + pats, opts)
1380 m = cmdutil.match(repo, (file1,) + pats, opts)
1375 for abs in ctx.walk(m):
1381 for abs in ctx.walk(m):
1376 fctx = ctx[abs]
1382 fctx = ctx[abs]
1377 o = fctx.filelog().renamed(fctx.filenode())
1383 o = fctx.filelog().renamed(fctx.filenode())
1378 rel = m.rel(abs)
1384 rel = m.rel(abs)
1379 if o:
1385 if o:
1380 ui.write(_("%s renamed from %s:%s\n") % (rel, o[0], hex(o[1])))
1386 ui.write(_("%s renamed from %s:%s\n") % (rel, o[0], hex(o[1])))
1381 else:
1387 else:
1382 ui.write(_("%s not renamed\n") % rel)
1388 ui.write(_("%s not renamed\n") % rel)
1383
1389
1384 def debugwalk(ui, repo, *pats, **opts):
1390 def debugwalk(ui, repo, *pats, **opts):
1385 """show how files match on given patterns"""
1391 """show how files match on given patterns"""
1386 m = cmdutil.match(repo, pats, opts)
1392 m = cmdutil.match(repo, pats, opts)
1387 items = list(repo.walk(m))
1393 items = list(repo.walk(m))
1388 if not items:
1394 if not items:
1389 return
1395 return
1390 fmt = 'f %%-%ds %%-%ds %%s' % (
1396 fmt = 'f %%-%ds %%-%ds %%s' % (
1391 max([len(abs) for abs in items]),
1397 max([len(abs) for abs in items]),
1392 max([len(m.rel(abs)) for abs in items]))
1398 max([len(m.rel(abs)) for abs in items]))
1393 for abs in items:
1399 for abs in items:
1394 line = fmt % (abs, m.rel(abs), m.exact(abs) and 'exact' or '')
1400 line = fmt % (abs, m.rel(abs), m.exact(abs) and 'exact' or '')
1395 ui.write("%s\n" % line.rstrip())
1401 ui.write("%s\n" % line.rstrip())
1396
1402
1397 def diff(ui, repo, *pats, **opts):
1403 def diff(ui, repo, *pats, **opts):
1398 """diff repository (or selected files)
1404 """diff repository (or selected files)
1399
1405
1400 Show differences between revisions for the specified files.
1406 Show differences between revisions for the specified files.
1401
1407
1402 Differences between files are shown using the unified diff format.
1408 Differences between files are shown using the unified diff format.
1403
1409
1404 NOTE: diff may generate unexpected results for merges, as it will
1410 NOTE: diff may generate unexpected results for merges, as it will
1405 default to comparing against the working directory's first parent
1411 default to comparing against the working directory's first parent
1406 changeset if no revisions are specified.
1412 changeset if no revisions are specified.
1407
1413
1408 When two revision arguments are given, then changes are shown
1414 When two revision arguments are given, then changes are shown
1409 between those revisions. If only one revision is specified then
1415 between those revisions. If only one revision is specified then
1410 that revision is compared to the working directory, and, when no
1416 that revision is compared to the working directory, and, when no
1411 revisions are specified, the working directory files are compared
1417 revisions are specified, the working directory files are compared
1412 to its parent.
1418 to its parent.
1413
1419
1414 Alternatively you can specify -c/--change with a revision to see
1420 Alternatively you can specify -c/--change with a revision to see
1415 the changes in that changeset relative to its first parent.
1421 the changes in that changeset relative to its first parent.
1416
1422
1417 Without the -a/--text option, diff will avoid generating diffs of
1423 Without the -a/--text option, diff will avoid generating diffs of
1418 files it detects as binary. With -a, diff will generate a diff
1424 files it detects as binary. With -a, diff will generate a diff
1419 anyway, probably with undesirable results.
1425 anyway, probably with undesirable results.
1420
1426
1421 Use the -g/--git option to generate diffs in the git extended diff
1427 Use the -g/--git option to generate diffs in the git extended diff
1422 format. For more information, read :hg:`help diffs`.
1428 format. For more information, read :hg:`help diffs`.
1423
1429
1424 Returns 0 on success.
1430 Returns 0 on success.
1425 """
1431 """
1426
1432
1427 revs = opts.get('rev')
1433 revs = opts.get('rev')
1428 change = opts.get('change')
1434 change = opts.get('change')
1429 stat = opts.get('stat')
1435 stat = opts.get('stat')
1430 reverse = opts.get('reverse')
1436 reverse = opts.get('reverse')
1431
1437
1432 if revs and change:
1438 if revs and change:
1433 msg = _('cannot specify --rev and --change at the same time')
1439 msg = _('cannot specify --rev and --change at the same time')
1434 raise util.Abort(msg)
1440 raise util.Abort(msg)
1435 elif change:
1441 elif change:
1436 node2 = repo.lookup(change)
1442 node2 = repo.lookup(change)
1437 node1 = repo[node2].parents()[0].node()
1443 node1 = repo[node2].parents()[0].node()
1438 else:
1444 else:
1439 node1, node2 = cmdutil.revpair(repo, revs)
1445 node1, node2 = cmdutil.revpair(repo, revs)
1440
1446
1441 if reverse:
1447 if reverse:
1442 node1, node2 = node2, node1
1448 node1, node2 = node2, node1
1443
1449
1444 diffopts = patch.diffopts(ui, opts)
1450 diffopts = patch.diffopts(ui, opts)
1445 m = cmdutil.match(repo, pats, opts)
1451 m = cmdutil.match(repo, pats, opts)
1446 cmdutil.diffordiffstat(ui, repo, diffopts, node1, node2, m, stat=stat)
1452 cmdutil.diffordiffstat(ui, repo, diffopts, node1, node2, m, stat=stat)
1447
1453
1448 def export(ui, repo, *changesets, **opts):
1454 def export(ui, repo, *changesets, **opts):
1449 """dump the header and diffs for one or more changesets
1455 """dump the header and diffs for one or more changesets
1450
1456
1451 Print the changeset header and diffs for one or more revisions.
1457 Print the changeset header and diffs for one or more revisions.
1452
1458
1453 The information shown in the changeset header is: author, date,
1459 The information shown in the changeset header is: author, date,
1454 branch name (if non-default), changeset hash, parent(s) and commit
1460 branch name (if non-default), changeset hash, parent(s) and commit
1455 comment.
1461 comment.
1456
1462
1457 NOTE: export may generate unexpected diff output for merge
1463 NOTE: export may generate unexpected diff output for merge
1458 changesets, as it will compare the merge changeset against its
1464 changesets, as it will compare the merge changeset against its
1459 first parent only.
1465 first parent only.
1460
1466
1461 Output may be to a file, in which case the name of the file is
1467 Output may be to a file, in which case the name of the file is
1462 given using a format string. The formatting rules are as follows:
1468 given using a format string. The formatting rules are as follows:
1463
1469
1464 :``%%``: literal "%" character
1470 :``%%``: literal "%" character
1465 :``%H``: changeset hash (40 hexadecimal digits)
1471 :``%H``: changeset hash (40 hexadecimal digits)
1466 :``%N``: number of patches being generated
1472 :``%N``: number of patches being generated
1467 :``%R``: changeset revision number
1473 :``%R``: changeset revision number
1468 :``%b``: basename of the exporting repository
1474 :``%b``: basename of the exporting repository
1469 :``%h``: short-form changeset hash (12 hexadecimal digits)
1475 :``%h``: short-form changeset hash (12 hexadecimal digits)
1470 :``%n``: zero-padded sequence number, starting at 1
1476 :``%n``: zero-padded sequence number, starting at 1
1471 :``%r``: zero-padded changeset revision number
1477 :``%r``: zero-padded changeset revision number
1472
1478
1473 Without the -a/--text option, export will avoid generating diffs
1479 Without the -a/--text option, export will avoid generating diffs
1474 of files it detects as binary. With -a, export will generate a
1480 of files it detects as binary. With -a, export will generate a
1475 diff anyway, probably with undesirable results.
1481 diff anyway, probably with undesirable results.
1476
1482
1477 Use the -g/--git option to generate diffs in the git extended diff
1483 Use the -g/--git option to generate diffs in the git extended diff
1478 format. See :hg:`help diffs` for more information.
1484 format. See :hg:`help diffs` for more information.
1479
1485
1480 With the --switch-parent option, the diff will be against the
1486 With the --switch-parent option, the diff will be against the
1481 second parent. It can be useful to review a merge.
1487 second parent. It can be useful to review a merge.
1482
1488
1483 Returns 0 on success.
1489 Returns 0 on success.
1484 """
1490 """
1485 changesets += tuple(opts.get('rev', []))
1491 changesets += tuple(opts.get('rev', []))
1486 if not changesets:
1492 if not changesets:
1487 raise util.Abort(_("export requires at least one changeset"))
1493 raise util.Abort(_("export requires at least one changeset"))
1488 revs = cmdutil.revrange(repo, changesets)
1494 revs = cmdutil.revrange(repo, changesets)
1489 if len(revs) > 1:
1495 if len(revs) > 1:
1490 ui.note(_('exporting patches:\n'))
1496 ui.note(_('exporting patches:\n'))
1491 else:
1497 else:
1492 ui.note(_('exporting patch:\n'))
1498 ui.note(_('exporting patch:\n'))
1493 cmdutil.export(repo, revs, template=opts.get('output'),
1499 cmdutil.export(repo, revs, template=opts.get('output'),
1494 switch_parent=opts.get('switch_parent'),
1500 switch_parent=opts.get('switch_parent'),
1495 opts=patch.diffopts(ui, opts))
1501 opts=patch.diffopts(ui, opts))
1496
1502
1497 def forget(ui, repo, *pats, **opts):
1503 def forget(ui, repo, *pats, **opts):
1498 """forget the specified files on the next commit
1504 """forget the specified files on the next commit
1499
1505
1500 Mark the specified files so they will no longer be tracked
1506 Mark the specified files so they will no longer be tracked
1501 after the next commit.
1507 after the next commit.
1502
1508
1503 This only removes files from the current branch, not from the
1509 This only removes files from the current branch, not from the
1504 entire project history, and it does not delete them from the
1510 entire project history, and it does not delete them from the
1505 working directory.
1511 working directory.
1506
1512
1507 To undo a forget before the next commit, see :hg:`add`.
1513 To undo a forget before the next commit, see :hg:`add`.
1508
1514
1509 Returns 0 on success.
1515 Returns 0 on success.
1510 """
1516 """
1511
1517
1512 if not pats:
1518 if not pats:
1513 raise util.Abort(_('no files specified'))
1519 raise util.Abort(_('no files specified'))
1514
1520
1515 m = cmdutil.match(repo, pats, opts)
1521 m = cmdutil.match(repo, pats, opts)
1516 s = repo.status(match=m, clean=True)
1522 s = repo.status(match=m, clean=True)
1517 forget = sorted(s[0] + s[1] + s[3] + s[6])
1523 forget = sorted(s[0] + s[1] + s[3] + s[6])
1518 errs = 0
1524 errs = 0
1519
1525
1520 for f in m.files():
1526 for f in m.files():
1521 if f not in repo.dirstate and not os.path.isdir(m.rel(f)):
1527 if f not in repo.dirstate and not os.path.isdir(m.rel(f)):
1522 ui.warn(_('not removing %s: file is already untracked\n')
1528 ui.warn(_('not removing %s: file is already untracked\n')
1523 % m.rel(f))
1529 % m.rel(f))
1524 errs = 1
1530 errs = 1
1525
1531
1526 for f in forget:
1532 for f in forget:
1527 if ui.verbose or not m.exact(f):
1533 if ui.verbose or not m.exact(f):
1528 ui.status(_('removing %s\n') % m.rel(f))
1534 ui.status(_('removing %s\n') % m.rel(f))
1529
1535
1530 repo[None].remove(forget, unlink=False)
1536 repo[None].remove(forget, unlink=False)
1531 return errs
1537 return errs
1532
1538
1533 def grep(ui, repo, pattern, *pats, **opts):
1539 def grep(ui, repo, pattern, *pats, **opts):
1534 """search for a pattern in specified files and revisions
1540 """search for a pattern in specified files and revisions
1535
1541
1536 Search revisions of files for a regular expression.
1542 Search revisions of files for a regular expression.
1537
1543
1538 This command behaves differently than Unix grep. It only accepts
1544 This command behaves differently than Unix grep. It only accepts
1539 Python/Perl regexps. It searches repository history, not the
1545 Python/Perl regexps. It searches repository history, not the
1540 working directory. It always prints the revision number in which a
1546 working directory. It always prints the revision number in which a
1541 match appears.
1547 match appears.
1542
1548
1543 By default, grep only prints output for the first revision of a
1549 By default, grep only prints output for the first revision of a
1544 file in which it finds a match. To get it to print every revision
1550 file in which it finds a match. To get it to print every revision
1545 that contains a change in match status ("-" for a match that
1551 that contains a change in match status ("-" for a match that
1546 becomes a non-match, or "+" for a non-match that becomes a match),
1552 becomes a non-match, or "+" for a non-match that becomes a match),
1547 use the --all flag.
1553 use the --all flag.
1548
1554
1549 Returns 0 if a match is found, 1 otherwise.
1555 Returns 0 if a match is found, 1 otherwise.
1550 """
1556 """
1551 reflags = 0
1557 reflags = 0
1552 if opts.get('ignore_case'):
1558 if opts.get('ignore_case'):
1553 reflags |= re.I
1559 reflags |= re.I
1554 try:
1560 try:
1555 regexp = re.compile(pattern, reflags)
1561 regexp = re.compile(pattern, reflags)
1556 except Exception, inst:
1562 except Exception, inst:
1557 ui.warn(_("grep: invalid match pattern: %s\n") % inst)
1563 ui.warn(_("grep: invalid match pattern: %s\n") % inst)
1558 return 1
1564 return 1
1559 sep, eol = ':', '\n'
1565 sep, eol = ':', '\n'
1560 if opts.get('print0'):
1566 if opts.get('print0'):
1561 sep = eol = '\0'
1567 sep = eol = '\0'
1562
1568
1563 getfile = util.lrucachefunc(repo.file)
1569 getfile = util.lrucachefunc(repo.file)
1564
1570
1565 def matchlines(body):
1571 def matchlines(body):
1566 begin = 0
1572 begin = 0
1567 linenum = 0
1573 linenum = 0
1568 while True:
1574 while True:
1569 match = regexp.search(body, begin)
1575 match = regexp.search(body, begin)
1570 if not match:
1576 if not match:
1571 break
1577 break
1572 mstart, mend = match.span()
1578 mstart, mend = match.span()
1573 linenum += body.count('\n', begin, mstart) + 1
1579 linenum += body.count('\n', begin, mstart) + 1
1574 lstart = body.rfind('\n', begin, mstart) + 1 or begin
1580 lstart = body.rfind('\n', begin, mstart) + 1 or begin
1575 begin = body.find('\n', mend) + 1 or len(body)
1581 begin = body.find('\n', mend) + 1 or len(body)
1576 lend = begin - 1
1582 lend = begin - 1
1577 yield linenum, mstart - lstart, mend - lstart, body[lstart:lend]
1583 yield linenum, mstart - lstart, mend - lstart, body[lstart:lend]
1578
1584
1579 class linestate(object):
1585 class linestate(object):
1580 def __init__(self, line, linenum, colstart, colend):
1586 def __init__(self, line, linenum, colstart, colend):
1581 self.line = line
1587 self.line = line
1582 self.linenum = linenum
1588 self.linenum = linenum
1583 self.colstart = colstart
1589 self.colstart = colstart
1584 self.colend = colend
1590 self.colend = colend
1585
1591
1586 def __hash__(self):
1592 def __hash__(self):
1587 return hash((self.linenum, self.line))
1593 return hash((self.linenum, self.line))
1588
1594
1589 def __eq__(self, other):
1595 def __eq__(self, other):
1590 return self.line == other.line
1596 return self.line == other.line
1591
1597
1592 matches = {}
1598 matches = {}
1593 copies = {}
1599 copies = {}
1594 def grepbody(fn, rev, body):
1600 def grepbody(fn, rev, body):
1595 matches[rev].setdefault(fn, [])
1601 matches[rev].setdefault(fn, [])
1596 m = matches[rev][fn]
1602 m = matches[rev][fn]
1597 for lnum, cstart, cend, line in matchlines(body):
1603 for lnum, cstart, cend, line in matchlines(body):
1598 s = linestate(line, lnum, cstart, cend)
1604 s = linestate(line, lnum, cstart, cend)
1599 m.append(s)
1605 m.append(s)
1600
1606
1601 def difflinestates(a, b):
1607 def difflinestates(a, b):
1602 sm = difflib.SequenceMatcher(None, a, b)
1608 sm = difflib.SequenceMatcher(None, a, b)
1603 for tag, alo, ahi, blo, bhi in sm.get_opcodes():
1609 for tag, alo, ahi, blo, bhi in sm.get_opcodes():
1604 if tag == 'insert':
1610 if tag == 'insert':
1605 for i in xrange(blo, bhi):
1611 for i in xrange(blo, bhi):
1606 yield ('+', b[i])
1612 yield ('+', b[i])
1607 elif tag == 'delete':
1613 elif tag == 'delete':
1608 for i in xrange(alo, ahi):
1614 for i in xrange(alo, ahi):
1609 yield ('-', a[i])
1615 yield ('-', a[i])
1610 elif tag == 'replace':
1616 elif tag == 'replace':
1611 for i in xrange(alo, ahi):
1617 for i in xrange(alo, ahi):
1612 yield ('-', a[i])
1618 yield ('-', a[i])
1613 for i in xrange(blo, bhi):
1619 for i in xrange(blo, bhi):
1614 yield ('+', b[i])
1620 yield ('+', b[i])
1615
1621
1616 def display(fn, ctx, pstates, states):
1622 def display(fn, ctx, pstates, states):
1617 rev = ctx.rev()
1623 rev = ctx.rev()
1618 datefunc = ui.quiet and util.shortdate or util.datestr
1624 datefunc = ui.quiet and util.shortdate or util.datestr
1619 found = False
1625 found = False
1620 filerevmatches = {}
1626 filerevmatches = {}
1621 if opts.get('all'):
1627 if opts.get('all'):
1622 iter = difflinestates(pstates, states)
1628 iter = difflinestates(pstates, states)
1623 else:
1629 else:
1624 iter = [('', l) for l in states]
1630 iter = [('', l) for l in states]
1625 for change, l in iter:
1631 for change, l in iter:
1626 cols = [fn, str(rev)]
1632 cols = [fn, str(rev)]
1627 before, match, after = None, None, None
1633 before, match, after = None, None, None
1628 if opts.get('line_number'):
1634 if opts.get('line_number'):
1629 cols.append(str(l.linenum))
1635 cols.append(str(l.linenum))
1630 if opts.get('all'):
1636 if opts.get('all'):
1631 cols.append(change)
1637 cols.append(change)
1632 if opts.get('user'):
1638 if opts.get('user'):
1633 cols.append(ui.shortuser(ctx.user()))
1639 cols.append(ui.shortuser(ctx.user()))
1634 if opts.get('date'):
1640 if opts.get('date'):
1635 cols.append(datefunc(ctx.date()))
1641 cols.append(datefunc(ctx.date()))
1636 if opts.get('files_with_matches'):
1642 if opts.get('files_with_matches'):
1637 c = (fn, rev)
1643 c = (fn, rev)
1638 if c in filerevmatches:
1644 if c in filerevmatches:
1639 continue
1645 continue
1640 filerevmatches[c] = 1
1646 filerevmatches[c] = 1
1641 else:
1647 else:
1642 before = l.line[:l.colstart]
1648 before = l.line[:l.colstart]
1643 match = l.line[l.colstart:l.colend]
1649 match = l.line[l.colstart:l.colend]
1644 after = l.line[l.colend:]
1650 after = l.line[l.colend:]
1645 ui.write(sep.join(cols))
1651 ui.write(sep.join(cols))
1646 if before is not None:
1652 if before is not None:
1647 ui.write(sep + before)
1653 ui.write(sep + before)
1648 ui.write(match, label='grep.match')
1654 ui.write(match, label='grep.match')
1649 ui.write(after)
1655 ui.write(after)
1650 ui.write(eol)
1656 ui.write(eol)
1651 found = True
1657 found = True
1652 return found
1658 return found
1653
1659
1654 skip = {}
1660 skip = {}
1655 revfiles = {}
1661 revfiles = {}
1656 matchfn = cmdutil.match(repo, pats, opts)
1662 matchfn = cmdutil.match(repo, pats, opts)
1657 found = False
1663 found = False
1658 follow = opts.get('follow')
1664 follow = opts.get('follow')
1659
1665
1660 def prep(ctx, fns):
1666 def prep(ctx, fns):
1661 rev = ctx.rev()
1667 rev = ctx.rev()
1662 pctx = ctx.parents()[0]
1668 pctx = ctx.parents()[0]
1663 parent = pctx.rev()
1669 parent = pctx.rev()
1664 matches.setdefault(rev, {})
1670 matches.setdefault(rev, {})
1665 matches.setdefault(parent, {})
1671 matches.setdefault(parent, {})
1666 files = revfiles.setdefault(rev, [])
1672 files = revfiles.setdefault(rev, [])
1667 for fn in fns:
1673 for fn in fns:
1668 flog = getfile(fn)
1674 flog = getfile(fn)
1669 try:
1675 try:
1670 fnode = ctx.filenode(fn)
1676 fnode = ctx.filenode(fn)
1671 except error.LookupError:
1677 except error.LookupError:
1672 continue
1678 continue
1673
1679
1674 copied = flog.renamed(fnode)
1680 copied = flog.renamed(fnode)
1675 copy = follow and copied and copied[0]
1681 copy = follow and copied and copied[0]
1676 if copy:
1682 if copy:
1677 copies.setdefault(rev, {})[fn] = copy
1683 copies.setdefault(rev, {})[fn] = copy
1678 if fn in skip:
1684 if fn in skip:
1679 if copy:
1685 if copy:
1680 skip[copy] = True
1686 skip[copy] = True
1681 continue
1687 continue
1682 files.append(fn)
1688 files.append(fn)
1683
1689
1684 if fn not in matches[rev]:
1690 if fn not in matches[rev]:
1685 grepbody(fn, rev, flog.read(fnode))
1691 grepbody(fn, rev, flog.read(fnode))
1686
1692
1687 pfn = copy or fn
1693 pfn = copy or fn
1688 if pfn not in matches[parent]:
1694 if pfn not in matches[parent]:
1689 try:
1695 try:
1690 fnode = pctx.filenode(pfn)
1696 fnode = pctx.filenode(pfn)
1691 grepbody(pfn, parent, flog.read(fnode))
1697 grepbody(pfn, parent, flog.read(fnode))
1692 except error.LookupError:
1698 except error.LookupError:
1693 pass
1699 pass
1694
1700
1695 for ctx in cmdutil.walkchangerevs(repo, matchfn, opts, prep):
1701 for ctx in cmdutil.walkchangerevs(repo, matchfn, opts, prep):
1696 rev = ctx.rev()
1702 rev = ctx.rev()
1697 parent = ctx.parents()[0].rev()
1703 parent = ctx.parents()[0].rev()
1698 for fn in sorted(revfiles.get(rev, [])):
1704 for fn in sorted(revfiles.get(rev, [])):
1699 states = matches[rev][fn]
1705 states = matches[rev][fn]
1700 copy = copies.get(rev, {}).get(fn)
1706 copy = copies.get(rev, {}).get(fn)
1701 if fn in skip:
1707 if fn in skip:
1702 if copy:
1708 if copy:
1703 skip[copy] = True
1709 skip[copy] = True
1704 continue
1710 continue
1705 pstates = matches.get(parent, {}).get(copy or fn, [])
1711 pstates = matches.get(parent, {}).get(copy or fn, [])
1706 if pstates or states:
1712 if pstates or states:
1707 r = display(fn, ctx, pstates, states)
1713 r = display(fn, ctx, pstates, states)
1708 found = found or r
1714 found = found or r
1709 if r and not opts.get('all'):
1715 if r and not opts.get('all'):
1710 skip[fn] = True
1716 skip[fn] = True
1711 if copy:
1717 if copy:
1712 skip[copy] = True
1718 skip[copy] = True
1713 del matches[rev]
1719 del matches[rev]
1714 del revfiles[rev]
1720 del revfiles[rev]
1715
1721
1716 return not found
1722 return not found
1717
1723
1718 def heads(ui, repo, *branchrevs, **opts):
1724 def heads(ui, repo, *branchrevs, **opts):
1719 """show current repository heads or show branch heads
1725 """show current repository heads or show branch heads
1720
1726
1721 With no arguments, show all repository branch heads.
1727 With no arguments, show all repository branch heads.
1722
1728
1723 Repository "heads" are changesets with no child changesets. They are
1729 Repository "heads" are changesets with no child changesets. They are
1724 where development generally takes place and are the usual targets
1730 where development generally takes place and are the usual targets
1725 for update and merge operations. Branch heads are changesets that have
1731 for update and merge operations. Branch heads are changesets that have
1726 no child changeset on the same branch.
1732 no child changeset on the same branch.
1727
1733
1728 If one or more REVs are given, only branch heads on the branches
1734 If one or more REVs are given, only branch heads on the branches
1729 associated with the specified changesets are shown.
1735 associated with the specified changesets are shown.
1730
1736
1731 If -c/--closed is specified, also show branch heads marked closed
1737 If -c/--closed is specified, also show branch heads marked closed
1732 (see :hg:`commit --close-branch`).
1738 (see :hg:`commit --close-branch`).
1733
1739
1734 If STARTREV is specified, only those heads that are descendants of
1740 If STARTREV is specified, only those heads that are descendants of
1735 STARTREV will be displayed.
1741 STARTREV will be displayed.
1736
1742
1737 If -t/--topo is specified, named branch mechanics will be ignored and only
1743 If -t/--topo is specified, named branch mechanics will be ignored and only
1738 changesets without children will be shown.
1744 changesets without children will be shown.
1739
1745
1740 Returns 0 if matching heads are found, 1 if not.
1746 Returns 0 if matching heads are found, 1 if not.
1741 """
1747 """
1742
1748
1743 if opts.get('rev'):
1749 if opts.get('rev'):
1744 start = repo.lookup(opts['rev'])
1750 start = repo.lookup(opts['rev'])
1745 else:
1751 else:
1746 start = None
1752 start = None
1747
1753
1748 if opts.get('topo'):
1754 if opts.get('topo'):
1749 heads = [repo[h] for h in repo.heads(start)]
1755 heads = [repo[h] for h in repo.heads(start)]
1750 else:
1756 else:
1751 heads = []
1757 heads = []
1752 for b, ls in repo.branchmap().iteritems():
1758 for b, ls in repo.branchmap().iteritems():
1753 if start is None:
1759 if start is None:
1754 heads += [repo[h] for h in ls]
1760 heads += [repo[h] for h in ls]
1755 continue
1761 continue
1756 startrev = repo.changelog.rev(start)
1762 startrev = repo.changelog.rev(start)
1757 descendants = set(repo.changelog.descendants(startrev))
1763 descendants = set(repo.changelog.descendants(startrev))
1758 descendants.add(startrev)
1764 descendants.add(startrev)
1759 rev = repo.changelog.rev
1765 rev = repo.changelog.rev
1760 heads += [repo[h] for h in ls if rev(h) in descendants]
1766 heads += [repo[h] for h in ls if rev(h) in descendants]
1761
1767
1762 if branchrevs:
1768 if branchrevs:
1763 decode, encode = encoding.fromlocal, encoding.tolocal
1769 decode, encode = encoding.fromlocal, encoding.tolocal
1764 branches = set(repo[decode(br)].branch() for br in branchrevs)
1770 branches = set(repo[decode(br)].branch() for br in branchrevs)
1765 heads = [h for h in heads if h.branch() in branches]
1771 heads = [h for h in heads if h.branch() in branches]
1766
1772
1767 if not opts.get('closed'):
1773 if not opts.get('closed'):
1768 heads = [h for h in heads if not h.extra().get('close')]
1774 heads = [h for h in heads if not h.extra().get('close')]
1769
1775
1770 if opts.get('active') and branchrevs:
1776 if opts.get('active') and branchrevs:
1771 dagheads = repo.heads(start)
1777 dagheads = repo.heads(start)
1772 heads = [h for h in heads if h.node() in dagheads]
1778 heads = [h for h in heads if h.node() in dagheads]
1773
1779
1774 if branchrevs:
1780 if branchrevs:
1775 haveheads = set(h.branch() for h in heads)
1781 haveheads = set(h.branch() for h in heads)
1776 if branches - haveheads:
1782 if branches - haveheads:
1777 headless = ', '.join(encode(b) for b in branches - haveheads)
1783 headless = ', '.join(encode(b) for b in branches - haveheads)
1778 msg = _('no open branch heads found on branches %s')
1784 msg = _('no open branch heads found on branches %s')
1779 if opts.get('rev'):
1785 if opts.get('rev'):
1780 msg += _(' (started at %s)' % opts['rev'])
1786 msg += _(' (started at %s)' % opts['rev'])
1781 ui.warn((msg + '\n') % headless)
1787 ui.warn((msg + '\n') % headless)
1782
1788
1783 if not heads:
1789 if not heads:
1784 return 1
1790 return 1
1785
1791
1786 heads = sorted(heads, key=lambda x: -x.rev())
1792 heads = sorted(heads, key=lambda x: -x.rev())
1787 displayer = cmdutil.show_changeset(ui, repo, opts)
1793 displayer = cmdutil.show_changeset(ui, repo, opts)
1788 for ctx in heads:
1794 for ctx in heads:
1789 displayer.show(ctx)
1795 displayer.show(ctx)
1790 displayer.close()
1796 displayer.close()
1791
1797
1792 def help_(ui, name=None, with_version=False, unknowncmd=False):
1798 def help_(ui, name=None, with_version=False, unknowncmd=False):
1793 """show help for a given topic or a help overview
1799 """show help for a given topic or a help overview
1794
1800
1795 With no arguments, print a list of commands with short help messages.
1801 With no arguments, print a list of commands with short help messages.
1796
1802
1797 Given a topic, extension, or command name, print help for that
1803 Given a topic, extension, or command name, print help for that
1798 topic.
1804 topic.
1799
1805
1800 Returns 0 if successful.
1806 Returns 0 if successful.
1801 """
1807 """
1802 option_lists = []
1808 option_lists = []
1803 textwidth = util.termwidth() - 2
1809 textwidth = util.termwidth() - 2
1804
1810
1805 def addglobalopts(aliases):
1811 def addglobalopts(aliases):
1806 if ui.verbose:
1812 if ui.verbose:
1807 option_lists.append((_("global options:"), globalopts))
1813 option_lists.append((_("global options:"), globalopts))
1808 if name == 'shortlist':
1814 if name == 'shortlist':
1809 option_lists.append((_('use "hg help" for the full list '
1815 option_lists.append((_('use "hg help" for the full list '
1810 'of commands'), ()))
1816 'of commands'), ()))
1811 else:
1817 else:
1812 if name == 'shortlist':
1818 if name == 'shortlist':
1813 msg = _('use "hg help" for the full list of commands '
1819 msg = _('use "hg help" for the full list of commands '
1814 'or "hg -v" for details')
1820 'or "hg -v" for details')
1815 elif aliases:
1821 elif aliases:
1816 msg = _('use "hg -v help%s" to show aliases and '
1822 msg = _('use "hg -v help%s" to show aliases and '
1817 'global options') % (name and " " + name or "")
1823 'global options') % (name and " " + name or "")
1818 else:
1824 else:
1819 msg = _('use "hg -v help %s" to show global options') % name
1825 msg = _('use "hg -v help %s" to show global options') % name
1820 option_lists.append((msg, ()))
1826 option_lists.append((msg, ()))
1821
1827
1822 def helpcmd(name):
1828 def helpcmd(name):
1823 if with_version:
1829 if with_version:
1824 version_(ui)
1830 version_(ui)
1825 ui.write('\n')
1831 ui.write('\n')
1826
1832
1827 try:
1833 try:
1828 aliases, entry = cmdutil.findcmd(name, table, strict=unknowncmd)
1834 aliases, entry = cmdutil.findcmd(name, table, strict=unknowncmd)
1829 except error.AmbiguousCommand, inst:
1835 except error.AmbiguousCommand, inst:
1830 # py3k fix: except vars can't be used outside the scope of the
1836 # py3k fix: except vars can't be used outside the scope of the
1831 # except block, nor can be used inside a lambda. python issue4617
1837 # except block, nor can be used inside a lambda. python issue4617
1832 prefix = inst.args[0]
1838 prefix = inst.args[0]
1833 select = lambda c: c.lstrip('^').startswith(prefix)
1839 select = lambda c: c.lstrip('^').startswith(prefix)
1834 helplist(_('list of commands:\n\n'), select)
1840 helplist(_('list of commands:\n\n'), select)
1835 return
1841 return
1836
1842
1837 # check if it's an invalid alias and display its error if it is
1843 # check if it's an invalid alias and display its error if it is
1838 if getattr(entry[0], 'badalias', False):
1844 if getattr(entry[0], 'badalias', False):
1839 if not unknowncmd:
1845 if not unknowncmd:
1840 entry[0](ui)
1846 entry[0](ui)
1841 return
1847 return
1842
1848
1843 # synopsis
1849 # synopsis
1844 if len(entry) > 2:
1850 if len(entry) > 2:
1845 if entry[2].startswith('hg'):
1851 if entry[2].startswith('hg'):
1846 ui.write("%s\n" % entry[2])
1852 ui.write("%s\n" % entry[2])
1847 else:
1853 else:
1848 ui.write('hg %s %s\n' % (aliases[0], entry[2]))
1854 ui.write('hg %s %s\n' % (aliases[0], entry[2]))
1849 else:
1855 else:
1850 ui.write('hg %s\n' % aliases[0])
1856 ui.write('hg %s\n' % aliases[0])
1851
1857
1852 # aliases
1858 # aliases
1853 if not ui.quiet and len(aliases) > 1:
1859 if not ui.quiet and len(aliases) > 1:
1854 ui.write(_("\naliases: %s\n") % ', '.join(aliases[1:]))
1860 ui.write(_("\naliases: %s\n") % ', '.join(aliases[1:]))
1855
1861
1856 # description
1862 # description
1857 doc = gettext(entry[0].__doc__)
1863 doc = gettext(entry[0].__doc__)
1858 if not doc:
1864 if not doc:
1859 doc = _("(no help text available)")
1865 doc = _("(no help text available)")
1860 if hasattr(entry[0], 'definition'): # aliased command
1866 if hasattr(entry[0], 'definition'): # aliased command
1861 if entry[0].definition.startswith('!'): # shell alias
1867 if entry[0].definition.startswith('!'): # shell alias
1862 doc = _('shell alias for::\n\n %s') % entry[0].definition[1:]
1868 doc = _('shell alias for::\n\n %s') % entry[0].definition[1:]
1863 else:
1869 else:
1864 doc = _('alias for: hg %s\n\n%s') % (entry[0].definition, doc)
1870 doc = _('alias for: hg %s\n\n%s') % (entry[0].definition, doc)
1865 if ui.quiet:
1871 if ui.quiet:
1866 doc = doc.splitlines()[0]
1872 doc = doc.splitlines()[0]
1867 keep = ui.verbose and ['verbose'] or []
1873 keep = ui.verbose and ['verbose'] or []
1868 formatted, pruned = minirst.format(doc, textwidth, keep=keep)
1874 formatted, pruned = minirst.format(doc, textwidth, keep=keep)
1869 ui.write("\n%s\n" % formatted)
1875 ui.write("\n%s\n" % formatted)
1870 if pruned:
1876 if pruned:
1871 ui.write(_('\nuse "hg -v help %s" to show verbose help\n') % name)
1877 ui.write(_('\nuse "hg -v help %s" to show verbose help\n') % name)
1872
1878
1873 if not ui.quiet:
1879 if not ui.quiet:
1874 # options
1880 # options
1875 if entry[1]:
1881 if entry[1]:
1876 option_lists.append((_("options:\n"), entry[1]))
1882 option_lists.append((_("options:\n"), entry[1]))
1877
1883
1878 addglobalopts(False)
1884 addglobalopts(False)
1879
1885
1880 def helplist(header, select=None):
1886 def helplist(header, select=None):
1881 h = {}
1887 h = {}
1882 cmds = {}
1888 cmds = {}
1883 for c, e in table.iteritems():
1889 for c, e in table.iteritems():
1884 f = c.split("|", 1)[0]
1890 f = c.split("|", 1)[0]
1885 if select and not select(f):
1891 if select and not select(f):
1886 continue
1892 continue
1887 if (not select and name != 'shortlist' and
1893 if (not select and name != 'shortlist' and
1888 e[0].__module__ != __name__):
1894 e[0].__module__ != __name__):
1889 continue
1895 continue
1890 if name == "shortlist" and not f.startswith("^"):
1896 if name == "shortlist" and not f.startswith("^"):
1891 continue
1897 continue
1892 f = f.lstrip("^")
1898 f = f.lstrip("^")
1893 if not ui.debugflag and f.startswith("debug"):
1899 if not ui.debugflag and f.startswith("debug"):
1894 continue
1900 continue
1895 doc = e[0].__doc__
1901 doc = e[0].__doc__
1896 if doc and 'DEPRECATED' in doc and not ui.verbose:
1902 if doc and 'DEPRECATED' in doc and not ui.verbose:
1897 continue
1903 continue
1898 doc = gettext(doc)
1904 doc = gettext(doc)
1899 if not doc:
1905 if not doc:
1900 doc = _("(no help text available)")
1906 doc = _("(no help text available)")
1901 h[f] = doc.splitlines()[0].rstrip()
1907 h[f] = doc.splitlines()[0].rstrip()
1902 cmds[f] = c.lstrip("^")
1908 cmds[f] = c.lstrip("^")
1903
1909
1904 if not h:
1910 if not h:
1905 ui.status(_('no commands defined\n'))
1911 ui.status(_('no commands defined\n'))
1906 return
1912 return
1907
1913
1908 ui.status(header)
1914 ui.status(header)
1909 fns = sorted(h)
1915 fns = sorted(h)
1910 m = max(map(len, fns))
1916 m = max(map(len, fns))
1911 for f in fns:
1917 for f in fns:
1912 if ui.verbose:
1918 if ui.verbose:
1913 commands = cmds[f].replace("|",", ")
1919 commands = cmds[f].replace("|",", ")
1914 ui.write(" %s:\n %s\n"%(commands, h[f]))
1920 ui.write(" %s:\n %s\n"%(commands, h[f]))
1915 else:
1921 else:
1916 ui.write('%s\n' % (util.wrap(h[f],
1922 ui.write('%s\n' % (util.wrap(h[f],
1917 initindent=' %-*s ' % (m, f),
1923 initindent=' %-*s ' % (m, f),
1918 hangindent=' ' * (m + 4))))
1924 hangindent=' ' * (m + 4))))
1919
1925
1920 if not ui.quiet:
1926 if not ui.quiet:
1921 addglobalopts(True)
1927 addglobalopts(True)
1922
1928
1923 def helptopic(name):
1929 def helptopic(name):
1924 for names, header, doc in help.helptable:
1930 for names, header, doc in help.helptable:
1925 if name in names:
1931 if name in names:
1926 break
1932 break
1927 else:
1933 else:
1928 raise error.UnknownCommand(name)
1934 raise error.UnknownCommand(name)
1929
1935
1930 # description
1936 # description
1931 if not doc:
1937 if not doc:
1932 doc = _("(no help text available)")
1938 doc = _("(no help text available)")
1933 if hasattr(doc, '__call__'):
1939 if hasattr(doc, '__call__'):
1934 doc = doc()
1940 doc = doc()
1935
1941
1936 ui.write("%s\n\n" % header)
1942 ui.write("%s\n\n" % header)
1937 ui.write("%s\n" % minirst.format(doc, textwidth, indent=4))
1943 ui.write("%s\n" % minirst.format(doc, textwidth, indent=4))
1938
1944
1939 def helpext(name):
1945 def helpext(name):
1940 try:
1946 try:
1941 mod = extensions.find(name)
1947 mod = extensions.find(name)
1942 doc = gettext(mod.__doc__) or _('no help text available')
1948 doc = gettext(mod.__doc__) or _('no help text available')
1943 except KeyError:
1949 except KeyError:
1944 mod = None
1950 mod = None
1945 doc = extensions.disabledext(name)
1951 doc = extensions.disabledext(name)
1946 if not doc:
1952 if not doc:
1947 raise error.UnknownCommand(name)
1953 raise error.UnknownCommand(name)
1948
1954
1949 if '\n' not in doc:
1955 if '\n' not in doc:
1950 head, tail = doc, ""
1956 head, tail = doc, ""
1951 else:
1957 else:
1952 head, tail = doc.split('\n', 1)
1958 head, tail = doc.split('\n', 1)
1953 ui.write(_('%s extension - %s\n\n') % (name.split('.')[-1], head))
1959 ui.write(_('%s extension - %s\n\n') % (name.split('.')[-1], head))
1954 if tail:
1960 if tail:
1955 ui.write(minirst.format(tail, textwidth))
1961 ui.write(minirst.format(tail, textwidth))
1956 ui.status('\n\n')
1962 ui.status('\n\n')
1957
1963
1958 if mod:
1964 if mod:
1959 try:
1965 try:
1960 ct = mod.cmdtable
1966 ct = mod.cmdtable
1961 except AttributeError:
1967 except AttributeError:
1962 ct = {}
1968 ct = {}
1963 modcmds = set([c.split('|', 1)[0] for c in ct])
1969 modcmds = set([c.split('|', 1)[0] for c in ct])
1964 helplist(_('list of commands:\n\n'), modcmds.__contains__)
1970 helplist(_('list of commands:\n\n'), modcmds.__contains__)
1965 else:
1971 else:
1966 ui.write(_('use "hg help extensions" for information on enabling '
1972 ui.write(_('use "hg help extensions" for information on enabling '
1967 'extensions\n'))
1973 'extensions\n'))
1968
1974
1969 def helpextcmd(name):
1975 def helpextcmd(name):
1970 cmd, ext, mod = extensions.disabledcmd(name, ui.config('ui', 'strict'))
1976 cmd, ext, mod = extensions.disabledcmd(name, ui.config('ui', 'strict'))
1971 doc = gettext(mod.__doc__).splitlines()[0]
1977 doc = gettext(mod.__doc__).splitlines()[0]
1972
1978
1973 msg = help.listexts(_("'%s' is provided by the following "
1979 msg = help.listexts(_("'%s' is provided by the following "
1974 "extension:") % cmd, {ext: doc}, len(ext),
1980 "extension:") % cmd, {ext: doc}, len(ext),
1975 indent=4)
1981 indent=4)
1976 ui.write(minirst.format(msg, textwidth))
1982 ui.write(minirst.format(msg, textwidth))
1977 ui.write('\n\n')
1983 ui.write('\n\n')
1978 ui.write(_('use "hg help extensions" for information on enabling '
1984 ui.write(_('use "hg help extensions" for information on enabling '
1979 'extensions\n'))
1985 'extensions\n'))
1980
1986
1981 if name and name != 'shortlist':
1987 if name and name != 'shortlist':
1982 i = None
1988 i = None
1983 if unknowncmd:
1989 if unknowncmd:
1984 queries = (helpextcmd,)
1990 queries = (helpextcmd,)
1985 else:
1991 else:
1986 queries = (helptopic, helpcmd, helpext, helpextcmd)
1992 queries = (helptopic, helpcmd, helpext, helpextcmd)
1987 for f in queries:
1993 for f in queries:
1988 try:
1994 try:
1989 f(name)
1995 f(name)
1990 i = None
1996 i = None
1991 break
1997 break
1992 except error.UnknownCommand, inst:
1998 except error.UnknownCommand, inst:
1993 i = inst
1999 i = inst
1994 if i:
2000 if i:
1995 raise i
2001 raise i
1996
2002
1997 else:
2003 else:
1998 # program name
2004 # program name
1999 if ui.verbose or with_version:
2005 if ui.verbose or with_version:
2000 version_(ui)
2006 version_(ui)
2001 else:
2007 else:
2002 ui.status(_("Mercurial Distributed SCM\n"))
2008 ui.status(_("Mercurial Distributed SCM\n"))
2003 ui.status('\n')
2009 ui.status('\n')
2004
2010
2005 # list of commands
2011 # list of commands
2006 if name == "shortlist":
2012 if name == "shortlist":
2007 header = _('basic commands:\n\n')
2013 header = _('basic commands:\n\n')
2008 else:
2014 else:
2009 header = _('list of commands:\n\n')
2015 header = _('list of commands:\n\n')
2010
2016
2011 helplist(header)
2017 helplist(header)
2012 if name != 'shortlist':
2018 if name != 'shortlist':
2013 exts, maxlength = extensions.enabled()
2019 exts, maxlength = extensions.enabled()
2014 text = help.listexts(_('enabled extensions:'), exts, maxlength)
2020 text = help.listexts(_('enabled extensions:'), exts, maxlength)
2015 if text:
2021 if text:
2016 ui.write("\n%s\n" % minirst.format(text, textwidth))
2022 ui.write("\n%s\n" % minirst.format(text, textwidth))
2017
2023
2018 # list all option lists
2024 # list all option lists
2019 opt_output = []
2025 opt_output = []
2020 multioccur = False
2026 multioccur = False
2021 for title, options in option_lists:
2027 for title, options in option_lists:
2022 opt_output.append(("\n%s" % title, None))
2028 opt_output.append(("\n%s" % title, None))
2023 for option in options:
2029 for option in options:
2024 if len(option) == 5:
2030 if len(option) == 5:
2025 shortopt, longopt, default, desc, optlabel = option
2031 shortopt, longopt, default, desc, optlabel = option
2026 else:
2032 else:
2027 shortopt, longopt, default, desc = option
2033 shortopt, longopt, default, desc = option
2028 optlabel = _("VALUE") # default label
2034 optlabel = _("VALUE") # default label
2029
2035
2030 if _("DEPRECATED") in desc and not ui.verbose:
2036 if _("DEPRECATED") in desc and not ui.verbose:
2031 continue
2037 continue
2032 if isinstance(default, list):
2038 if isinstance(default, list):
2033 numqualifier = " %s [+]" % optlabel
2039 numqualifier = " %s [+]" % optlabel
2034 multioccur = True
2040 multioccur = True
2035 elif (default is not None) and not isinstance(default, bool):
2041 elif (default is not None) and not isinstance(default, bool):
2036 numqualifier = " %s" % optlabel
2042 numqualifier = " %s" % optlabel
2037 else:
2043 else:
2038 numqualifier = ""
2044 numqualifier = ""
2039 opt_output.append(("%2s%s" %
2045 opt_output.append(("%2s%s" %
2040 (shortopt and "-%s" % shortopt,
2046 (shortopt and "-%s" % shortopt,
2041 longopt and " --%s%s" %
2047 longopt and " --%s%s" %
2042 (longopt, numqualifier)),
2048 (longopt, numqualifier)),
2043 "%s%s" % (desc,
2049 "%s%s" % (desc,
2044 default
2050 default
2045 and _(" (default: %s)") % default
2051 and _(" (default: %s)") % default
2046 or "")))
2052 or "")))
2047 if multioccur:
2053 if multioccur:
2048 msg = _("\n[+] marked option can be specified multiple times")
2054 msg = _("\n[+] marked option can be specified multiple times")
2049 if ui.verbose and name != 'shortlist':
2055 if ui.verbose and name != 'shortlist':
2050 opt_output.append((msg, None))
2056 opt_output.append((msg, None))
2051 else:
2057 else:
2052 opt_output.insert(-1, (msg, None))
2058 opt_output.insert(-1, (msg, None))
2053
2059
2054 if not name:
2060 if not name:
2055 ui.write(_("\nadditional help topics:\n\n"))
2061 ui.write(_("\nadditional help topics:\n\n"))
2056 topics = []
2062 topics = []
2057 for names, header, doc in help.helptable:
2063 for names, header, doc in help.helptable:
2058 topics.append((sorted(names, key=len, reverse=True)[0], header))
2064 topics.append((sorted(names, key=len, reverse=True)[0], header))
2059 topics_len = max([len(s[0]) for s in topics])
2065 topics_len = max([len(s[0]) for s in topics])
2060 for t, desc in topics:
2066 for t, desc in topics:
2061 ui.write(" %-*s %s\n" % (topics_len, t, desc))
2067 ui.write(" %-*s %s\n" % (topics_len, t, desc))
2062
2068
2063 if opt_output:
2069 if opt_output:
2064 colwidth = encoding.colwidth
2070 colwidth = encoding.colwidth
2065 # normalize: (opt or message, desc or None, width of opt)
2071 # normalize: (opt or message, desc or None, width of opt)
2066 entries = [desc and (opt, desc, colwidth(opt)) or (opt, None, 0)
2072 entries = [desc and (opt, desc, colwidth(opt)) or (opt, None, 0)
2067 for opt, desc in opt_output]
2073 for opt, desc in opt_output]
2068 hanging = max([e[2] for e in entries])
2074 hanging = max([e[2] for e in entries])
2069 for opt, desc, width in entries:
2075 for opt, desc, width in entries:
2070 if desc:
2076 if desc:
2071 initindent = ' %s%s ' % (opt, ' ' * (hanging - width))
2077 initindent = ' %s%s ' % (opt, ' ' * (hanging - width))
2072 hangindent = ' ' * (hanging + 3)
2078 hangindent = ' ' * (hanging + 3)
2073 ui.write('%s\n' % (util.wrap(desc,
2079 ui.write('%s\n' % (util.wrap(desc,
2074 initindent=initindent,
2080 initindent=initindent,
2075 hangindent=hangindent)))
2081 hangindent=hangindent)))
2076 else:
2082 else:
2077 ui.write("%s\n" % opt)
2083 ui.write("%s\n" % opt)
2078
2084
2079 def identify(ui, repo, source=None,
2085 def identify(ui, repo, source=None,
2080 rev=None, num=None, id=None, branch=None, tags=None):
2086 rev=None, num=None, id=None, branch=None, tags=None):
2081 """identify the working copy or specified revision
2087 """identify the working copy or specified revision
2082
2088
2083 With no revision, print a summary of the current state of the
2089 With no revision, print a summary of the current state of the
2084 repository.
2090 repository.
2085
2091
2086 Specifying a path to a repository root or Mercurial bundle will
2092 Specifying a path to a repository root or Mercurial bundle will
2087 cause lookup to operate on that repository/bundle.
2093 cause lookup to operate on that repository/bundle.
2088
2094
2089 This summary identifies the repository state using one or two
2095 This summary identifies the repository state using one or two
2090 parent hash identifiers, followed by a "+" if there are
2096 parent hash identifiers, followed by a "+" if there are
2091 uncommitted changes in the working directory, a list of tags for
2097 uncommitted changes in the working directory, a list of tags for
2092 this revision and a branch name for non-default branches.
2098 this revision and a branch name for non-default branches.
2093
2099
2094 Returns 0 if successful.
2100 Returns 0 if successful.
2095 """
2101 """
2096
2102
2097 if not repo and not source:
2103 if not repo and not source:
2098 raise util.Abort(_("There is no Mercurial repository here "
2104 raise util.Abort(_("There is no Mercurial repository here "
2099 "(.hg not found)"))
2105 "(.hg not found)"))
2100
2106
2101 hexfunc = ui.debugflag and hex or short
2107 hexfunc = ui.debugflag and hex or short
2102 default = not (num or id or branch or tags)
2108 default = not (num or id or branch or tags)
2103 output = []
2109 output = []
2104
2110
2105 revs = []
2111 revs = []
2106 if source:
2112 if source:
2107 source, branches = hg.parseurl(ui.expandpath(source))
2113 source, branches = hg.parseurl(ui.expandpath(source))
2108 repo = hg.repository(ui, source)
2114 repo = hg.repository(ui, source)
2109 revs, checkout = hg.addbranchrevs(repo, repo, branches, None)
2115 revs, checkout = hg.addbranchrevs(repo, repo, branches, None)
2110
2116
2111 if not repo.local():
2117 if not repo.local():
2112 if not rev and revs:
2118 if not rev and revs:
2113 rev = revs[0]
2119 rev = revs[0]
2114 if not rev:
2120 if not rev:
2115 rev = "tip"
2121 rev = "tip"
2116 if num or branch or tags:
2122 if num or branch or tags:
2117 raise util.Abort(
2123 raise util.Abort(
2118 "can't query remote revision number, branch, or tags")
2124 "can't query remote revision number, branch, or tags")
2119 output = [hexfunc(repo.lookup(rev))]
2125 output = [hexfunc(repo.lookup(rev))]
2120 elif not rev:
2126 elif not rev:
2121 ctx = repo[None]
2127 ctx = repo[None]
2122 parents = ctx.parents()
2128 parents = ctx.parents()
2123 changed = False
2129 changed = False
2124 if default or id or num:
2130 if default or id or num:
2125 changed = util.any(repo.status())
2131 changed = util.any(repo.status())
2126 if default or id:
2132 if default or id:
2127 output = ["%s%s" % ('+'.join([hexfunc(p.node()) for p in parents]),
2133 output = ["%s%s" % ('+'.join([hexfunc(p.node()) for p in parents]),
2128 (changed) and "+" or "")]
2134 (changed) and "+" or "")]
2129 if num:
2135 if num:
2130 output.append("%s%s" % ('+'.join([str(p.rev()) for p in parents]),
2136 output.append("%s%s" % ('+'.join([str(p.rev()) for p in parents]),
2131 (changed) and "+" or ""))
2137 (changed) and "+" or ""))
2132 else:
2138 else:
2133 ctx = repo[rev]
2139 ctx = repo[rev]
2134 if default or id:
2140 if default or id:
2135 output = [hexfunc(ctx.node())]
2141 output = [hexfunc(ctx.node())]
2136 if num:
2142 if num:
2137 output.append(str(ctx.rev()))
2143 output.append(str(ctx.rev()))
2138
2144
2139 if repo.local() and default and not ui.quiet:
2145 if repo.local() and default and not ui.quiet:
2140 b = encoding.tolocal(ctx.branch())
2146 b = encoding.tolocal(ctx.branch())
2141 if b != 'default':
2147 if b != 'default':
2142 output.append("(%s)" % b)
2148 output.append("(%s)" % b)
2143
2149
2144 # multiple tags for a single parent separated by '/'
2150 # multiple tags for a single parent separated by '/'
2145 t = "/".join(ctx.tags())
2151 t = "/".join(ctx.tags())
2146 if t:
2152 if t:
2147 output.append(t)
2153 output.append(t)
2148
2154
2149 if branch:
2155 if branch:
2150 output.append(encoding.tolocal(ctx.branch()))
2156 output.append(encoding.tolocal(ctx.branch()))
2151
2157
2152 if tags:
2158 if tags:
2153 output.extend(ctx.tags())
2159 output.extend(ctx.tags())
2154
2160
2155 ui.write("%s\n" % ' '.join(output))
2161 ui.write("%s\n" % ' '.join(output))
2156
2162
2157 def import_(ui, repo, patch1, *patches, **opts):
2163 def import_(ui, repo, patch1, *patches, **opts):
2158 """import an ordered set of patches
2164 """import an ordered set of patches
2159
2165
2160 Import a list of patches and commit them individually (unless
2166 Import a list of patches and commit them individually (unless
2161 --no-commit is specified).
2167 --no-commit is specified).
2162
2168
2163 If there are outstanding changes in the working directory, import
2169 If there are outstanding changes in the working directory, import
2164 will abort unless given the -f/--force flag.
2170 will abort unless given the -f/--force flag.
2165
2171
2166 You can import a patch straight from a mail message. Even patches
2172 You can import a patch straight from a mail message. Even patches
2167 as attachments work (to use the body part, it must have type
2173 as attachments work (to use the body part, it must have type
2168 text/plain or text/x-patch). From and Subject headers of email
2174 text/plain or text/x-patch). From and Subject headers of email
2169 message are used as default committer and commit message. All
2175 message are used as default committer and commit message. All
2170 text/plain body parts before first diff are added to commit
2176 text/plain body parts before first diff are added to commit
2171 message.
2177 message.
2172
2178
2173 If the imported patch was generated by :hg:`export`, user and
2179 If the imported patch was generated by :hg:`export`, user and
2174 description from patch override values from message headers and
2180 description from patch override values from message headers and
2175 body. Values given on command line with -m/--message and -u/--user
2181 body. Values given on command line with -m/--message and -u/--user
2176 override these.
2182 override these.
2177
2183
2178 If --exact is specified, import will set the working directory to
2184 If --exact is specified, import will set the working directory to
2179 the parent of each patch before applying it, and will abort if the
2185 the parent of each patch before applying it, and will abort if the
2180 resulting changeset has a different ID than the one recorded in
2186 resulting changeset has a different ID than the one recorded in
2181 the patch. This may happen due to character set problems or other
2187 the patch. This may happen due to character set problems or other
2182 deficiencies in the text patch format.
2188 deficiencies in the text patch format.
2183
2189
2184 With -s/--similarity, hg will attempt to discover renames and
2190 With -s/--similarity, hg will attempt to discover renames and
2185 copies in the patch in the same way as 'addremove'.
2191 copies in the patch in the same way as 'addremove'.
2186
2192
2187 To read a patch from standard input, use "-" as the patch name. If
2193 To read a patch from standard input, use "-" as the patch name. If
2188 a URL is specified, the patch will be downloaded from it.
2194 a URL is specified, the patch will be downloaded from it.
2189 See :hg:`help dates` for a list of formats valid for -d/--date.
2195 See :hg:`help dates` for a list of formats valid for -d/--date.
2190
2196
2191 Returns 0 on success.
2197 Returns 0 on success.
2192 """
2198 """
2193 patches = (patch1,) + patches
2199 patches = (patch1,) + patches
2194
2200
2195 date = opts.get('date')
2201 date = opts.get('date')
2196 if date:
2202 if date:
2197 opts['date'] = util.parsedate(date)
2203 opts['date'] = util.parsedate(date)
2198
2204
2199 try:
2205 try:
2200 sim = float(opts.get('similarity') or 0)
2206 sim = float(opts.get('similarity') or 0)
2201 except ValueError:
2207 except ValueError:
2202 raise util.Abort(_('similarity must be a number'))
2208 raise util.Abort(_('similarity must be a number'))
2203 if sim < 0 or sim > 100:
2209 if sim < 0 or sim > 100:
2204 raise util.Abort(_('similarity must be between 0 and 100'))
2210 raise util.Abort(_('similarity must be between 0 and 100'))
2205
2211
2206 if opts.get('exact') or not opts.get('force'):
2212 if opts.get('exact') or not opts.get('force'):
2207 cmdutil.bail_if_changed(repo)
2213 cmdutil.bail_if_changed(repo)
2208
2214
2209 d = opts["base"]
2215 d = opts["base"]
2210 strip = opts["strip"]
2216 strip = opts["strip"]
2211 wlock = lock = None
2217 wlock = lock = None
2212
2218
2213 def tryone(ui, hunk):
2219 def tryone(ui, hunk):
2214 tmpname, message, user, date, branch, nodeid, p1, p2 = \
2220 tmpname, message, user, date, branch, nodeid, p1, p2 = \
2215 patch.extract(ui, hunk)
2221 patch.extract(ui, hunk)
2216
2222
2217 if not tmpname:
2223 if not tmpname:
2218 return None
2224 return None
2219 commitid = _('to working directory')
2225 commitid = _('to working directory')
2220
2226
2221 try:
2227 try:
2222 cmdline_message = cmdutil.logmessage(opts)
2228 cmdline_message = cmdutil.logmessage(opts)
2223 if cmdline_message:
2229 if cmdline_message:
2224 # pickup the cmdline msg
2230 # pickup the cmdline msg
2225 message = cmdline_message
2231 message = cmdline_message
2226 elif message:
2232 elif message:
2227 # pickup the patch msg
2233 # pickup the patch msg
2228 message = message.strip()
2234 message = message.strip()
2229 else:
2235 else:
2230 # launch the editor
2236 # launch the editor
2231 message = None
2237 message = None
2232 ui.debug('message:\n%s\n' % message)
2238 ui.debug('message:\n%s\n' % message)
2233
2239
2234 wp = repo.parents()
2240 wp = repo.parents()
2235 if opts.get('exact'):
2241 if opts.get('exact'):
2236 if not nodeid or not p1:
2242 if not nodeid or not p1:
2237 raise util.Abort(_('not a Mercurial patch'))
2243 raise util.Abort(_('not a Mercurial patch'))
2238 p1 = repo.lookup(p1)
2244 p1 = repo.lookup(p1)
2239 p2 = repo.lookup(p2 or hex(nullid))
2245 p2 = repo.lookup(p2 or hex(nullid))
2240
2246
2241 if p1 != wp[0].node():
2247 if p1 != wp[0].node():
2242 hg.clean(repo, p1)
2248 hg.clean(repo, p1)
2243 repo.dirstate.setparents(p1, p2)
2249 repo.dirstate.setparents(p1, p2)
2244 elif p2:
2250 elif p2:
2245 try:
2251 try:
2246 p1 = repo.lookup(p1)
2252 p1 = repo.lookup(p1)
2247 p2 = repo.lookup(p2)
2253 p2 = repo.lookup(p2)
2248 if p1 == wp[0].node():
2254 if p1 == wp[0].node():
2249 repo.dirstate.setparents(p1, p2)
2255 repo.dirstate.setparents(p1, p2)
2250 except error.RepoError:
2256 except error.RepoError:
2251 pass
2257 pass
2252 if opts.get('exact') or opts.get('import_branch'):
2258 if opts.get('exact') or opts.get('import_branch'):
2253 repo.dirstate.setbranch(branch or 'default')
2259 repo.dirstate.setbranch(branch or 'default')
2254
2260
2255 files = {}
2261 files = {}
2256 try:
2262 try:
2257 patch.patch(tmpname, ui, strip=strip, cwd=repo.root,
2263 patch.patch(tmpname, ui, strip=strip, cwd=repo.root,
2258 files=files, eolmode=None)
2264 files=files, eolmode=None)
2259 finally:
2265 finally:
2260 files = patch.updatedir(ui, repo, files,
2266 files = patch.updatedir(ui, repo, files,
2261 similarity=sim / 100.0)
2267 similarity=sim / 100.0)
2262 if not opts.get('no_commit'):
2268 if not opts.get('no_commit'):
2263 if opts.get('exact'):
2269 if opts.get('exact'):
2264 m = None
2270 m = None
2265 else:
2271 else:
2266 m = cmdutil.matchfiles(repo, files or [])
2272 m = cmdutil.matchfiles(repo, files or [])
2267 n = repo.commit(message, opts.get('user') or user,
2273 n = repo.commit(message, opts.get('user') or user,
2268 opts.get('date') or date, match=m,
2274 opts.get('date') or date, match=m,
2269 editor=cmdutil.commiteditor)
2275 editor=cmdutil.commiteditor)
2270 if opts.get('exact'):
2276 if opts.get('exact'):
2271 if hex(n) != nodeid:
2277 if hex(n) != nodeid:
2272 repo.rollback()
2278 repo.rollback()
2273 raise util.Abort(_('patch is damaged'
2279 raise util.Abort(_('patch is damaged'
2274 ' or loses information'))
2280 ' or loses information'))
2275 # Force a dirstate write so that the next transaction
2281 # Force a dirstate write so that the next transaction
2276 # backups an up-do-date file.
2282 # backups an up-do-date file.
2277 repo.dirstate.write()
2283 repo.dirstate.write()
2278 if n:
2284 if n:
2279 commitid = short(n)
2285 commitid = short(n)
2280
2286
2281 return commitid
2287 return commitid
2282 finally:
2288 finally:
2283 os.unlink(tmpname)
2289 os.unlink(tmpname)
2284
2290
2285 try:
2291 try:
2286 wlock = repo.wlock()
2292 wlock = repo.wlock()
2287 lock = repo.lock()
2293 lock = repo.lock()
2288 lastcommit = None
2294 lastcommit = None
2289 for p in patches:
2295 for p in patches:
2290 pf = os.path.join(d, p)
2296 pf = os.path.join(d, p)
2291
2297
2292 if pf == '-':
2298 if pf == '-':
2293 ui.status(_("applying patch from stdin\n"))
2299 ui.status(_("applying patch from stdin\n"))
2294 pf = sys.stdin
2300 pf = sys.stdin
2295 else:
2301 else:
2296 ui.status(_("applying %s\n") % p)
2302 ui.status(_("applying %s\n") % p)
2297 pf = url.open(ui, pf)
2303 pf = url.open(ui, pf)
2298
2304
2299 haspatch = False
2305 haspatch = False
2300 for hunk in patch.split(pf):
2306 for hunk in patch.split(pf):
2301 commitid = tryone(ui, hunk)
2307 commitid = tryone(ui, hunk)
2302 if commitid:
2308 if commitid:
2303 haspatch = True
2309 haspatch = True
2304 if lastcommit:
2310 if lastcommit:
2305 ui.status(_('applied %s\n') % lastcommit)
2311 ui.status(_('applied %s\n') % lastcommit)
2306 lastcommit = commitid
2312 lastcommit = commitid
2307
2313
2308 if not haspatch:
2314 if not haspatch:
2309 raise util.Abort(_('no diffs found'))
2315 raise util.Abort(_('no diffs found'))
2310
2316
2311 finally:
2317 finally:
2312 release(lock, wlock)
2318 release(lock, wlock)
2313
2319
2314 def incoming(ui, repo, source="default", **opts):
2320 def incoming(ui, repo, source="default", **opts):
2315 """show new changesets found in source
2321 """show new changesets found in source
2316
2322
2317 Show new changesets found in the specified path/URL or the default
2323 Show new changesets found in the specified path/URL or the default
2318 pull location. These are the changesets that would have been pulled
2324 pull location. These are the changesets that would have been pulled
2319 if a pull at the time you issued this command.
2325 if a pull at the time you issued this command.
2320
2326
2321 For remote repository, using --bundle avoids downloading the
2327 For remote repository, using --bundle avoids downloading the
2322 changesets twice if the incoming is followed by a pull.
2328 changesets twice if the incoming is followed by a pull.
2323
2329
2324 See pull for valid source format details.
2330 See pull for valid source format details.
2325
2331
2326 Returns 0 if there are incoming changes, 1 otherwise.
2332 Returns 0 if there are incoming changes, 1 otherwise.
2327 """
2333 """
2328 limit = cmdutil.loglimit(opts)
2334 limit = cmdutil.loglimit(opts)
2329 source, branches = hg.parseurl(ui.expandpath(source), opts.get('branch'))
2335 source, branches = hg.parseurl(ui.expandpath(source), opts.get('branch'))
2330 other = hg.repository(hg.remoteui(repo, opts), source)
2336 other = hg.repository(hg.remoteui(repo, opts), source)
2331 ui.status(_('comparing with %s\n') % url.hidepassword(source))
2337 ui.status(_('comparing with %s\n') % url.hidepassword(source))
2332 revs, checkout = hg.addbranchrevs(repo, other, branches, opts.get('rev'))
2338 revs, checkout = hg.addbranchrevs(repo, other, branches, opts.get('rev'))
2333 if revs:
2339 if revs:
2334 revs = [other.lookup(rev) for rev in revs]
2340 revs = [other.lookup(rev) for rev in revs]
2335
2341
2336 tmp = discovery.findcommonincoming(repo, other, heads=revs,
2342 tmp = discovery.findcommonincoming(repo, other, heads=revs,
2337 force=opts.get('force'))
2343 force=opts.get('force'))
2338 common, incoming, rheads = tmp
2344 common, incoming, rheads = tmp
2339 if not incoming:
2345 if not incoming:
2340 try:
2346 try:
2341 os.unlink(opts["bundle"])
2347 os.unlink(opts["bundle"])
2342 except:
2348 except:
2343 pass
2349 pass
2344 ui.status(_("no changes found\n"))
2350 ui.status(_("no changes found\n"))
2345 return 1
2351 return 1
2346
2352
2347 cleanup = None
2353 cleanup = None
2348 try:
2354 try:
2349 fname = opts["bundle"]
2355 fname = opts["bundle"]
2350 if fname or not other.local():
2356 if fname or not other.local():
2351 # create a bundle (uncompressed if other repo is not local)
2357 # create a bundle (uncompressed if other repo is not local)
2352
2358
2353 if revs is None and other.capable('changegroupsubset'):
2359 if revs is None and other.capable('changegroupsubset'):
2354 revs = rheads
2360 revs = rheads
2355
2361
2356 if revs is None:
2362 if revs is None:
2357 cg = other.changegroup(incoming, "incoming")
2363 cg = other.changegroup(incoming, "incoming")
2358 else:
2364 else:
2359 cg = other.changegroupsubset(incoming, revs, 'incoming')
2365 cg = other.changegroupsubset(incoming, revs, 'incoming')
2360 bundletype = other.local() and "HG10BZ" or "HG10UN"
2366 bundletype = other.local() and "HG10BZ" or "HG10UN"
2361 fname = cleanup = changegroup.writebundle(cg, fname, bundletype)
2367 fname = cleanup = changegroup.writebundle(cg, fname, bundletype)
2362 # keep written bundle?
2368 # keep written bundle?
2363 if opts["bundle"]:
2369 if opts["bundle"]:
2364 cleanup = None
2370 cleanup = None
2365 if not other.local():
2371 if not other.local():
2366 # use the created uncompressed bundlerepo
2372 # use the created uncompressed bundlerepo
2367 other = bundlerepo.bundlerepository(ui, repo.root, fname)
2373 other = bundlerepo.bundlerepository(ui, repo.root, fname)
2368
2374
2369 o = other.changelog.nodesbetween(incoming, revs)[0]
2375 o = other.changelog.nodesbetween(incoming, revs)[0]
2370 if opts.get('newest_first'):
2376 if opts.get('newest_first'):
2371 o.reverse()
2377 o.reverse()
2372 displayer = cmdutil.show_changeset(ui, other, opts)
2378 displayer = cmdutil.show_changeset(ui, other, opts)
2373 count = 0
2379 count = 0
2374 for n in o:
2380 for n in o:
2375 if limit is not None and count >= limit:
2381 if limit is not None and count >= limit:
2376 break
2382 break
2377 parents = [p for p in other.changelog.parents(n) if p != nullid]
2383 parents = [p for p in other.changelog.parents(n) if p != nullid]
2378 if opts.get('no_merges') and len(parents) == 2:
2384 if opts.get('no_merges') and len(parents) == 2:
2379 continue
2385 continue
2380 count += 1
2386 count += 1
2381 displayer.show(other[n])
2387 displayer.show(other[n])
2382 displayer.close()
2388 displayer.close()
2383 finally:
2389 finally:
2384 if hasattr(other, 'close'):
2390 if hasattr(other, 'close'):
2385 other.close()
2391 other.close()
2386 if cleanup:
2392 if cleanup:
2387 os.unlink(cleanup)
2393 os.unlink(cleanup)
2388
2394
2389 def init(ui, dest=".", **opts):
2395 def init(ui, dest=".", **opts):
2390 """create a new repository in the given directory
2396 """create a new repository in the given directory
2391
2397
2392 Initialize a new repository in the given directory. If the given
2398 Initialize a new repository in the given directory. If the given
2393 directory does not exist, it will be created.
2399 directory does not exist, it will be created.
2394
2400
2395 If no directory is given, the current directory is used.
2401 If no directory is given, the current directory is used.
2396
2402
2397 It is possible to specify an ``ssh://`` URL as the destination.
2403 It is possible to specify an ``ssh://`` URL as the destination.
2398 See :hg:`help urls` for more information.
2404 See :hg:`help urls` for more information.
2399
2405
2400 Returns 0 on success.
2406 Returns 0 on success.
2401 """
2407 """
2402 hg.repository(hg.remoteui(ui, opts), dest, create=1)
2408 hg.repository(hg.remoteui(ui, opts), dest, create=1)
2403
2409
2404 def locate(ui, repo, *pats, **opts):
2410 def locate(ui, repo, *pats, **opts):
2405 """locate files matching specific patterns
2411 """locate files matching specific patterns
2406
2412
2407 Print files under Mercurial control in the working directory whose
2413 Print files under Mercurial control in the working directory whose
2408 names match the given patterns.
2414 names match the given patterns.
2409
2415
2410 By default, this command searches all directories in the working
2416 By default, this command searches all directories in the working
2411 directory. To search just the current directory and its
2417 directory. To search just the current directory and its
2412 subdirectories, use "--include .".
2418 subdirectories, use "--include .".
2413
2419
2414 If no patterns are given to match, this command prints the names
2420 If no patterns are given to match, this command prints the names
2415 of all files under Mercurial control in the working directory.
2421 of all files under Mercurial control in the working directory.
2416
2422
2417 If you want to feed the output of this command into the "xargs"
2423 If you want to feed the output of this command into the "xargs"
2418 command, use the -0 option to both this command and "xargs". This
2424 command, use the -0 option to both this command and "xargs". This
2419 will avoid the problem of "xargs" treating single filenames that
2425 will avoid the problem of "xargs" treating single filenames that
2420 contain whitespace as multiple filenames.
2426 contain whitespace as multiple filenames.
2421
2427
2422 Returns 0 if a match is found, 1 otherwise.
2428 Returns 0 if a match is found, 1 otherwise.
2423 """
2429 """
2424 end = opts.get('print0') and '\0' or '\n'
2430 end = opts.get('print0') and '\0' or '\n'
2425 rev = opts.get('rev') or None
2431 rev = opts.get('rev') or None
2426
2432
2427 ret = 1
2433 ret = 1
2428 m = cmdutil.match(repo, pats, opts, default='relglob')
2434 m = cmdutil.match(repo, pats, opts, default='relglob')
2429 m.bad = lambda x, y: False
2435 m.bad = lambda x, y: False
2430 for abs in repo[rev].walk(m):
2436 for abs in repo[rev].walk(m):
2431 if not rev and abs not in repo.dirstate:
2437 if not rev and abs not in repo.dirstate:
2432 continue
2438 continue
2433 if opts.get('fullpath'):
2439 if opts.get('fullpath'):
2434 ui.write(repo.wjoin(abs), end)
2440 ui.write(repo.wjoin(abs), end)
2435 else:
2441 else:
2436 ui.write(((pats and m.rel(abs)) or abs), end)
2442 ui.write(((pats and m.rel(abs)) or abs), end)
2437 ret = 0
2443 ret = 0
2438
2444
2439 return ret
2445 return ret
2440
2446
2441 def log(ui, repo, *pats, **opts):
2447 def log(ui, repo, *pats, **opts):
2442 """show revision history of entire repository or files
2448 """show revision history of entire repository or files
2443
2449
2444 Print the revision history of the specified files or the entire
2450 Print the revision history of the specified files or the entire
2445 project.
2451 project.
2446
2452
2447 File history is shown without following rename or copy history of
2453 File history is shown without following rename or copy history of
2448 files. Use -f/--follow with a filename to follow history across
2454 files. Use -f/--follow with a filename to follow history across
2449 renames and copies. --follow without a filename will only show
2455 renames and copies. --follow without a filename will only show
2450 ancestors or descendants of the starting revision. --follow-first
2456 ancestors or descendants of the starting revision. --follow-first
2451 only follows the first parent of merge revisions.
2457 only follows the first parent of merge revisions.
2452
2458
2453 If no revision range is specified, the default is tip:0 unless
2459 If no revision range is specified, the default is tip:0 unless
2454 --follow is set, in which case the working directory parent is
2460 --follow is set, in which case the working directory parent is
2455 used as the starting revision. You can specify a revision set for
2461 used as the starting revision. You can specify a revision set for
2456 log, see :hg:`help revsets` for more information.
2462 log, see :hg:`help revsets` for more information.
2457
2463
2458 See :hg:`help dates` for a list of formats valid for -d/--date.
2464 See :hg:`help dates` for a list of formats valid for -d/--date.
2459
2465
2460 By default this command prints revision number and changeset id,
2466 By default this command prints revision number and changeset id,
2461 tags, non-trivial parents, user, date and time, and a summary for
2467 tags, non-trivial parents, user, date and time, and a summary for
2462 each commit. When the -v/--verbose switch is used, the list of
2468 each commit. When the -v/--verbose switch is used, the list of
2463 changed files and full commit message are shown.
2469 changed files and full commit message are shown.
2464
2470
2465 NOTE: log -p/--patch may generate unexpected diff output for merge
2471 NOTE: log -p/--patch may generate unexpected diff output for merge
2466 changesets, as it will only compare the merge changeset against
2472 changesets, as it will only compare the merge changeset against
2467 its first parent. Also, only files different from BOTH parents
2473 its first parent. Also, only files different from BOTH parents
2468 will appear in files:.
2474 will appear in files:.
2469
2475
2470 Returns 0 on success.
2476 Returns 0 on success.
2471 """
2477 """
2472
2478
2473 matchfn = cmdutil.match(repo, pats, opts)
2479 matchfn = cmdutil.match(repo, pats, opts)
2474 limit = cmdutil.loglimit(opts)
2480 limit = cmdutil.loglimit(opts)
2475 count = 0
2481 count = 0
2476
2482
2477 endrev = None
2483 endrev = None
2478 if opts.get('copies') and opts.get('rev'):
2484 if opts.get('copies') and opts.get('rev'):
2479 endrev = max(cmdutil.revrange(repo, opts.get('rev'))) + 1
2485 endrev = max(cmdutil.revrange(repo, opts.get('rev'))) + 1
2480
2486
2481 df = False
2487 df = False
2482 if opts["date"]:
2488 if opts["date"]:
2483 df = util.matchdate(opts["date"])
2489 df = util.matchdate(opts["date"])
2484
2490
2485 branches = opts.get('branch', []) + opts.get('only_branch', [])
2491 branches = opts.get('branch', []) + opts.get('only_branch', [])
2486 opts['branch'] = [repo.lookupbranch(b) for b in branches]
2492 opts['branch'] = [repo.lookupbranch(b) for b in branches]
2487
2493
2488 displayer = cmdutil.show_changeset(ui, repo, opts, True)
2494 displayer = cmdutil.show_changeset(ui, repo, opts, True)
2489 def prep(ctx, fns):
2495 def prep(ctx, fns):
2490 rev = ctx.rev()
2496 rev = ctx.rev()
2491 parents = [p for p in repo.changelog.parentrevs(rev)
2497 parents = [p for p in repo.changelog.parentrevs(rev)
2492 if p != nullrev]
2498 if p != nullrev]
2493 if opts.get('no_merges') and len(parents) == 2:
2499 if opts.get('no_merges') and len(parents) == 2:
2494 return
2500 return
2495 if opts.get('only_merges') and len(parents) != 2:
2501 if opts.get('only_merges') and len(parents) != 2:
2496 return
2502 return
2497 if opts.get('branch') and ctx.branch() not in opts['branch']:
2503 if opts.get('branch') and ctx.branch() not in opts['branch']:
2498 return
2504 return
2499 if df and not df(ctx.date()[0]):
2505 if df and not df(ctx.date()[0]):
2500 return
2506 return
2501 if opts['user'] and not [k for k in opts['user'] if k in ctx.user()]:
2507 if opts['user'] and not [k for k in opts['user'] if k in ctx.user()]:
2502 return
2508 return
2503 if opts.get('keyword'):
2509 if opts.get('keyword'):
2504 for k in [kw.lower() for kw in opts['keyword']]:
2510 for k in [kw.lower() for kw in opts['keyword']]:
2505 if (k in ctx.user().lower() or
2511 if (k in ctx.user().lower() or
2506 k in ctx.description().lower() or
2512 k in ctx.description().lower() or
2507 k in " ".join(ctx.files()).lower()):
2513 k in " ".join(ctx.files()).lower()):
2508 break
2514 break
2509 else:
2515 else:
2510 return
2516 return
2511
2517
2512 copies = None
2518 copies = None
2513 if opts.get('copies') and rev:
2519 if opts.get('copies') and rev:
2514 copies = []
2520 copies = []
2515 getrenamed = templatekw.getrenamedfn(repo, endrev=endrev)
2521 getrenamed = templatekw.getrenamedfn(repo, endrev=endrev)
2516 for fn in ctx.files():
2522 for fn in ctx.files():
2517 rename = getrenamed(fn, rev)
2523 rename = getrenamed(fn, rev)
2518 if rename:
2524 if rename:
2519 copies.append((fn, rename[0]))
2525 copies.append((fn, rename[0]))
2520
2526
2521 revmatchfn = None
2527 revmatchfn = None
2522 if opts.get('patch') or opts.get('stat'):
2528 if opts.get('patch') or opts.get('stat'):
2523 revmatchfn = cmdutil.match(repo, fns, default='path')
2529 revmatchfn = cmdutil.match(repo, fns, default='path')
2524
2530
2525 displayer.show(ctx, copies=copies, matchfn=revmatchfn)
2531 displayer.show(ctx, copies=copies, matchfn=revmatchfn)
2526
2532
2527 for ctx in cmdutil.walkchangerevs(repo, matchfn, opts, prep):
2533 for ctx in cmdutil.walkchangerevs(repo, matchfn, opts, prep):
2528 if count == limit:
2534 if count == limit:
2529 break
2535 break
2530 if displayer.flush(ctx.rev()):
2536 if displayer.flush(ctx.rev()):
2531 count += 1
2537 count += 1
2532 displayer.close()
2538 displayer.close()
2533
2539
2534 def manifest(ui, repo, node=None, rev=None):
2540 def manifest(ui, repo, node=None, rev=None):
2535 """output the current or given revision of the project manifest
2541 """output the current or given revision of the project manifest
2536
2542
2537 Print a list of version controlled files for the given revision.
2543 Print a list of version controlled files for the given revision.
2538 If no revision is given, the first parent of the working directory
2544 If no revision is given, the first parent of the working directory
2539 is used, or the null revision if no revision is checked out.
2545 is used, or the null revision if no revision is checked out.
2540
2546
2541 With -v, print file permissions, symlink and executable bits.
2547 With -v, print file permissions, symlink and executable bits.
2542 With --debug, print file revision hashes.
2548 With --debug, print file revision hashes.
2543
2549
2544 Returns 0 on success.
2550 Returns 0 on success.
2545 """
2551 """
2546
2552
2547 if rev and node:
2553 if rev and node:
2548 raise util.Abort(_("please specify just one revision"))
2554 raise util.Abort(_("please specify just one revision"))
2549
2555
2550 if not node:
2556 if not node:
2551 node = rev
2557 node = rev
2552
2558
2553 decor = {'l':'644 @ ', 'x':'755 * ', '':'644 '}
2559 decor = {'l':'644 @ ', 'x':'755 * ', '':'644 '}
2554 ctx = repo[node]
2560 ctx = repo[node]
2555 for f in ctx:
2561 for f in ctx:
2556 if ui.debugflag:
2562 if ui.debugflag:
2557 ui.write("%40s " % hex(ctx.manifest()[f]))
2563 ui.write("%40s " % hex(ctx.manifest()[f]))
2558 if ui.verbose:
2564 if ui.verbose:
2559 ui.write(decor[ctx.flags(f)])
2565 ui.write(decor[ctx.flags(f)])
2560 ui.write("%s\n" % f)
2566 ui.write("%s\n" % f)
2561
2567
2562 def merge(ui, repo, node=None, **opts):
2568 def merge(ui, repo, node=None, **opts):
2563 """merge working directory with another revision
2569 """merge working directory with another revision
2564
2570
2565 The current working directory is updated with all changes made in
2571 The current working directory is updated with all changes made in
2566 the requested revision since the last common predecessor revision.
2572 the requested revision since the last common predecessor revision.
2567
2573
2568 Files that changed between either parent are marked as changed for
2574 Files that changed between either parent are marked as changed for
2569 the next commit and a commit must be performed before any further
2575 the next commit and a commit must be performed before any further
2570 updates to the repository are allowed. The next commit will have
2576 updates to the repository are allowed. The next commit will have
2571 two parents.
2577 two parents.
2572
2578
2573 If no revision is specified, the working directory's parent is a
2579 If no revision is specified, the working directory's parent is a
2574 head revision, and the current branch contains exactly one other
2580 head revision, and the current branch contains exactly one other
2575 head, the other head is merged with by default. Otherwise, an
2581 head, the other head is merged with by default. Otherwise, an
2576 explicit revision with which to merge with must be provided.
2582 explicit revision with which to merge with must be provided.
2577
2583
2578 To undo an uncommitted merge, use :hg:`update --clean .` which
2584 To undo an uncommitted merge, use :hg:`update --clean .` which
2579 will check out a clean copy of the original merge parent, losing
2585 will check out a clean copy of the original merge parent, losing
2580 all changes.
2586 all changes.
2581
2587
2582 Returns 0 on success, 1 if there are unresolved files.
2588 Returns 0 on success, 1 if there are unresolved files.
2583 """
2589 """
2584
2590
2585 if opts.get('rev') and node:
2591 if opts.get('rev') and node:
2586 raise util.Abort(_("please specify just one revision"))
2592 raise util.Abort(_("please specify just one revision"))
2587 if not node:
2593 if not node:
2588 node = opts.get('rev')
2594 node = opts.get('rev')
2589
2595
2590 if not node:
2596 if not node:
2591 branch = repo.changectx(None).branch()
2597 branch = repo.changectx(None).branch()
2592 bheads = repo.branchheads(branch)
2598 bheads = repo.branchheads(branch)
2593 if len(bheads) > 2:
2599 if len(bheads) > 2:
2594 raise util.Abort(_(
2600 raise util.Abort(_(
2595 'branch \'%s\' has %d heads - '
2601 'branch \'%s\' has %d heads - '
2596 'please merge with an explicit rev\n'
2602 'please merge with an explicit rev\n'
2597 '(run \'hg heads .\' to see heads)')
2603 '(run \'hg heads .\' to see heads)')
2598 % (branch, len(bheads)))
2604 % (branch, len(bheads)))
2599
2605
2600 parent = repo.dirstate.parents()[0]
2606 parent = repo.dirstate.parents()[0]
2601 if len(bheads) == 1:
2607 if len(bheads) == 1:
2602 if len(repo.heads()) > 1:
2608 if len(repo.heads()) > 1:
2603 raise util.Abort(_(
2609 raise util.Abort(_(
2604 'branch \'%s\' has one head - '
2610 'branch \'%s\' has one head - '
2605 'please merge with an explicit rev\n'
2611 'please merge with an explicit rev\n'
2606 '(run \'hg heads\' to see all heads)')
2612 '(run \'hg heads\' to see all heads)')
2607 % branch)
2613 % branch)
2608 msg = _('there is nothing to merge')
2614 msg = _('there is nothing to merge')
2609 if parent != repo.lookup(repo[None].branch()):
2615 if parent != repo.lookup(repo[None].branch()):
2610 msg = _('%s - use "hg update" instead') % msg
2616 msg = _('%s - use "hg update" instead') % msg
2611 raise util.Abort(msg)
2617 raise util.Abort(msg)
2612
2618
2613 if parent not in bheads:
2619 if parent not in bheads:
2614 raise util.Abort(_('working dir not at a head rev - '
2620 raise util.Abort(_('working dir not at a head rev - '
2615 'use "hg update" or merge with an explicit rev'))
2621 'use "hg update" or merge with an explicit rev'))
2616 node = parent == bheads[0] and bheads[-1] or bheads[0]
2622 node = parent == bheads[0] and bheads[-1] or bheads[0]
2617
2623
2618 if opts.get('preview'):
2624 if opts.get('preview'):
2619 # find nodes that are ancestors of p2 but not of p1
2625 # find nodes that are ancestors of p2 but not of p1
2620 p1 = repo.lookup('.')
2626 p1 = repo.lookup('.')
2621 p2 = repo.lookup(node)
2627 p2 = repo.lookup(node)
2622 nodes = repo.changelog.findmissing(common=[p1], heads=[p2])
2628 nodes = repo.changelog.findmissing(common=[p1], heads=[p2])
2623
2629
2624 displayer = cmdutil.show_changeset(ui, repo, opts)
2630 displayer = cmdutil.show_changeset(ui, repo, opts)
2625 for node in nodes:
2631 for node in nodes:
2626 displayer.show(repo[node])
2632 displayer.show(repo[node])
2627 displayer.close()
2633 displayer.close()
2628 return 0
2634 return 0
2629
2635
2630 return hg.merge(repo, node, force=opts.get('force'))
2636 return hg.merge(repo, node, force=opts.get('force'))
2631
2637
2632 def outgoing(ui, repo, dest=None, **opts):
2638 def outgoing(ui, repo, dest=None, **opts):
2633 """show changesets not found in the destination
2639 """show changesets not found in the destination
2634
2640
2635 Show changesets not found in the specified destination repository
2641 Show changesets not found in the specified destination repository
2636 or the default push location. These are the changesets that would
2642 or the default push location. These are the changesets that would
2637 be pushed if a push was requested.
2643 be pushed if a push was requested.
2638
2644
2639 See pull for details of valid destination formats.
2645 See pull for details of valid destination formats.
2640
2646
2641 Returns 0 if there are outgoing changes, 1 otherwise.
2647 Returns 0 if there are outgoing changes, 1 otherwise.
2642 """
2648 """
2643 limit = cmdutil.loglimit(opts)
2649 limit = cmdutil.loglimit(opts)
2644 dest = ui.expandpath(dest or 'default-push', dest or 'default')
2650 dest = ui.expandpath(dest or 'default-push', dest or 'default')
2645 dest, branches = hg.parseurl(dest, opts.get('branch'))
2651 dest, branches = hg.parseurl(dest, opts.get('branch'))
2646 revs, checkout = hg.addbranchrevs(repo, repo, branches, opts.get('rev'))
2652 revs, checkout = hg.addbranchrevs(repo, repo, branches, opts.get('rev'))
2647 if revs:
2653 if revs:
2648 revs = [repo.lookup(rev) for rev in revs]
2654 revs = [repo.lookup(rev) for rev in revs]
2649
2655
2650 other = hg.repository(hg.remoteui(repo, opts), dest)
2656 other = hg.repository(hg.remoteui(repo, opts), dest)
2651 ui.status(_('comparing with %s\n') % url.hidepassword(dest))
2657 ui.status(_('comparing with %s\n') % url.hidepassword(dest))
2652 o = discovery.findoutgoing(repo, other, force=opts.get('force'))
2658 o = discovery.findoutgoing(repo, other, force=opts.get('force'))
2653 if not o:
2659 if not o:
2654 ui.status(_("no changes found\n"))
2660 ui.status(_("no changes found\n"))
2655 return 1
2661 return 1
2656 o = repo.changelog.nodesbetween(o, revs)[0]
2662 o = repo.changelog.nodesbetween(o, revs)[0]
2657 if opts.get('newest_first'):
2663 if opts.get('newest_first'):
2658 o.reverse()
2664 o.reverse()
2659 displayer = cmdutil.show_changeset(ui, repo, opts)
2665 displayer = cmdutil.show_changeset(ui, repo, opts)
2660 count = 0
2666 count = 0
2661 for n in o:
2667 for n in o:
2662 if limit is not None and count >= limit:
2668 if limit is not None and count >= limit:
2663 break
2669 break
2664 parents = [p for p in repo.changelog.parents(n) if p != nullid]
2670 parents = [p for p in repo.changelog.parents(n) if p != nullid]
2665 if opts.get('no_merges') and len(parents) == 2:
2671 if opts.get('no_merges') and len(parents) == 2:
2666 continue
2672 continue
2667 count += 1
2673 count += 1
2668 displayer.show(repo[n])
2674 displayer.show(repo[n])
2669 displayer.close()
2675 displayer.close()
2670
2676
2671 def parents(ui, repo, file_=None, **opts):
2677 def parents(ui, repo, file_=None, **opts):
2672 """show the parents of the working directory or revision
2678 """show the parents of the working directory or revision
2673
2679
2674 Print the working directory's parent revisions. If a revision is
2680 Print the working directory's parent revisions. If a revision is
2675 given via -r/--rev, the parent of that revision will be printed.
2681 given via -r/--rev, the parent of that revision will be printed.
2676 If a file argument is given, the revision in which the file was
2682 If a file argument is given, the revision in which the file was
2677 last changed (before the working directory revision or the
2683 last changed (before the working directory revision or the
2678 argument to --rev if given) is printed.
2684 argument to --rev if given) is printed.
2679
2685
2680 Returns 0 on success.
2686 Returns 0 on success.
2681 """
2687 """
2682 rev = opts.get('rev')
2688 rev = opts.get('rev')
2683 if rev:
2689 if rev:
2684 ctx = repo[rev]
2690 ctx = repo[rev]
2685 else:
2691 else:
2686 ctx = repo[None]
2692 ctx = repo[None]
2687
2693
2688 if file_:
2694 if file_:
2689 m = cmdutil.match(repo, (file_,), opts)
2695 m = cmdutil.match(repo, (file_,), opts)
2690 if m.anypats() or len(m.files()) != 1:
2696 if m.anypats() or len(m.files()) != 1:
2691 raise util.Abort(_('can only specify an explicit filename'))
2697 raise util.Abort(_('can only specify an explicit filename'))
2692 file_ = m.files()[0]
2698 file_ = m.files()[0]
2693 filenodes = []
2699 filenodes = []
2694 for cp in ctx.parents():
2700 for cp in ctx.parents():
2695 if not cp:
2701 if not cp:
2696 continue
2702 continue
2697 try:
2703 try:
2698 filenodes.append(cp.filenode(file_))
2704 filenodes.append(cp.filenode(file_))
2699 except error.LookupError:
2705 except error.LookupError:
2700 pass
2706 pass
2701 if not filenodes:
2707 if not filenodes:
2702 raise util.Abort(_("'%s' not found in manifest!") % file_)
2708 raise util.Abort(_("'%s' not found in manifest!") % file_)
2703 fl = repo.file(file_)
2709 fl = repo.file(file_)
2704 p = [repo.lookup(fl.linkrev(fl.rev(fn))) for fn in filenodes]
2710 p = [repo.lookup(fl.linkrev(fl.rev(fn))) for fn in filenodes]
2705 else:
2711 else:
2706 p = [cp.node() for cp in ctx.parents()]
2712 p = [cp.node() for cp in ctx.parents()]
2707
2713
2708 displayer = cmdutil.show_changeset(ui, repo, opts)
2714 displayer = cmdutil.show_changeset(ui, repo, opts)
2709 for n in p:
2715 for n in p:
2710 if n != nullid:
2716 if n != nullid:
2711 displayer.show(repo[n])
2717 displayer.show(repo[n])
2712 displayer.close()
2718 displayer.close()
2713
2719
2714 def paths(ui, repo, search=None):
2720 def paths(ui, repo, search=None):
2715 """show aliases for remote repositories
2721 """show aliases for remote repositories
2716
2722
2717 Show definition of symbolic path name NAME. If no name is given,
2723 Show definition of symbolic path name NAME. If no name is given,
2718 show definition of all available names.
2724 show definition of all available names.
2719
2725
2720 Path names are defined in the [paths] section of
2726 Path names are defined in the [paths] section of
2721 ``/etc/mercurial/hgrc`` and ``$HOME/.hgrc``. If run inside a
2727 ``/etc/mercurial/hgrc`` and ``$HOME/.hgrc``. If run inside a
2722 repository, ``.hg/hgrc`` is used, too.
2728 repository, ``.hg/hgrc`` is used, too.
2723
2729
2724 The path names ``default`` and ``default-push`` have a special
2730 The path names ``default`` and ``default-push`` have a special
2725 meaning. When performing a push or pull operation, they are used
2731 meaning. When performing a push or pull operation, they are used
2726 as fallbacks if no location is specified on the command-line.
2732 as fallbacks if no location is specified on the command-line.
2727 When ``default-push`` is set, it will be used for push and
2733 When ``default-push`` is set, it will be used for push and
2728 ``default`` will be used for pull; otherwise ``default`` is used
2734 ``default`` will be used for pull; otherwise ``default`` is used
2729 as the fallback for both. When cloning a repository, the clone
2735 as the fallback for both. When cloning a repository, the clone
2730 source is written as ``default`` in ``.hg/hgrc``. Note that
2736 source is written as ``default`` in ``.hg/hgrc``. Note that
2731 ``default`` and ``default-push`` apply to all inbound (e.g.
2737 ``default`` and ``default-push`` apply to all inbound (e.g.
2732 :hg:`incoming`) and outbound (e.g. :hg:`outgoing`, :hg:`email` and
2738 :hg:`incoming`) and outbound (e.g. :hg:`outgoing`, :hg:`email` and
2733 :hg:`bundle`) operations.
2739 :hg:`bundle`) operations.
2734
2740
2735 See :hg:`help urls` for more information.
2741 See :hg:`help urls` for more information.
2736
2742
2737 Returns 0 on success.
2743 Returns 0 on success.
2738 """
2744 """
2739 if search:
2745 if search:
2740 for name, path in ui.configitems("paths"):
2746 for name, path in ui.configitems("paths"):
2741 if name == search:
2747 if name == search:
2742 ui.write("%s\n" % url.hidepassword(path))
2748 ui.write("%s\n" % url.hidepassword(path))
2743 return
2749 return
2744 ui.warn(_("not found!\n"))
2750 ui.warn(_("not found!\n"))
2745 return 1
2751 return 1
2746 else:
2752 else:
2747 for name, path in ui.configitems("paths"):
2753 for name, path in ui.configitems("paths"):
2748 ui.write("%s = %s\n" % (name, url.hidepassword(path)))
2754 ui.write("%s = %s\n" % (name, url.hidepassword(path)))
2749
2755
2750 def postincoming(ui, repo, modheads, optupdate, checkout):
2756 def postincoming(ui, repo, modheads, optupdate, checkout):
2751 if modheads == 0:
2757 if modheads == 0:
2752 return
2758 return
2753 if optupdate:
2759 if optupdate:
2754 if (modheads <= 1 or len(repo.branchheads()) == 1) or checkout:
2760 if (modheads <= 1 or len(repo.branchheads()) == 1) or checkout:
2755 return hg.update(repo, checkout)
2761 return hg.update(repo, checkout)
2756 else:
2762 else:
2757 ui.status(_("not updating, since new heads added\n"))
2763 ui.status(_("not updating, since new heads added\n"))
2758 if modheads > 1:
2764 if modheads > 1:
2759 ui.status(_("(run 'hg heads' to see heads, 'hg merge' to merge)\n"))
2765 ui.status(_("(run 'hg heads' to see heads, 'hg merge' to merge)\n"))
2760 else:
2766 else:
2761 ui.status(_("(run 'hg update' to get a working copy)\n"))
2767 ui.status(_("(run 'hg update' to get a working copy)\n"))
2762
2768
2763 def pull(ui, repo, source="default", **opts):
2769 def pull(ui, repo, source="default", **opts):
2764 """pull changes from the specified source
2770 """pull changes from the specified source
2765
2771
2766 Pull changes from a remote repository to a local one.
2772 Pull changes from a remote repository to a local one.
2767
2773
2768 This finds all changes from the repository at the specified path
2774 This finds all changes from the repository at the specified path
2769 or URL and adds them to a local repository (the current one unless
2775 or URL and adds them to a local repository (the current one unless
2770 -R is specified). By default, this does not update the copy of the
2776 -R is specified). By default, this does not update the copy of the
2771 project in the working directory.
2777 project in the working directory.
2772
2778
2773 Use :hg:`incoming` if you want to see what would have been added
2779 Use :hg:`incoming` if you want to see what would have been added
2774 by a pull at the time you issued this command. If you then decide
2780 by a pull at the time you issued this command. If you then decide
2775 to add those changes to the repository, you should use :hg:`pull
2781 to add those changes to the repository, you should use :hg:`pull
2776 -r X` where ``X`` is the last changeset listed by :hg:`incoming`.
2782 -r X` where ``X`` is the last changeset listed by :hg:`incoming`.
2777
2783
2778 If SOURCE is omitted, the 'default' path will be used.
2784 If SOURCE is omitted, the 'default' path will be used.
2779 See :hg:`help urls` for more information.
2785 See :hg:`help urls` for more information.
2780
2786
2781 Returns 0 on success, 1 if an update had unresolved files.
2787 Returns 0 on success, 1 if an update had unresolved files.
2782 """
2788 """
2783 source, branches = hg.parseurl(ui.expandpath(source), opts.get('branch'))
2789 source, branches = hg.parseurl(ui.expandpath(source), opts.get('branch'))
2784 other = hg.repository(hg.remoteui(repo, opts), source)
2790 other = hg.repository(hg.remoteui(repo, opts), source)
2785 ui.status(_('pulling from %s\n') % url.hidepassword(source))
2791 ui.status(_('pulling from %s\n') % url.hidepassword(source))
2786 revs, checkout = hg.addbranchrevs(repo, other, branches, opts.get('rev'))
2792 revs, checkout = hg.addbranchrevs(repo, other, branches, opts.get('rev'))
2787 if revs:
2793 if revs:
2788 try:
2794 try:
2789 revs = [other.lookup(rev) for rev in revs]
2795 revs = [other.lookup(rev) for rev in revs]
2790 except error.CapabilityError:
2796 except error.CapabilityError:
2791 err = _("Other repository doesn't support revision lookup, "
2797 err = _("Other repository doesn't support revision lookup, "
2792 "so a rev cannot be specified.")
2798 "so a rev cannot be specified.")
2793 raise util.Abort(err)
2799 raise util.Abort(err)
2794
2800
2795 modheads = repo.pull(other, heads=revs, force=opts.get('force'))
2801 modheads = repo.pull(other, heads=revs, force=opts.get('force'))
2796 if checkout:
2802 if checkout:
2797 checkout = str(repo.changelog.rev(other.lookup(checkout)))
2803 checkout = str(repo.changelog.rev(other.lookup(checkout)))
2798 return postincoming(ui, repo, modheads, opts.get('update'), checkout)
2804 return postincoming(ui, repo, modheads, opts.get('update'), checkout)
2799
2805
2800 def push(ui, repo, dest=None, **opts):
2806 def push(ui, repo, dest=None, **opts):
2801 """push changes to the specified destination
2807 """push changes to the specified destination
2802
2808
2803 Push changesets from the local repository to the specified
2809 Push changesets from the local repository to the specified
2804 destination.
2810 destination.
2805
2811
2806 This operation is symmetrical to pull: it is identical to a pull
2812 This operation is symmetrical to pull: it is identical to a pull
2807 in the destination repository from the current one.
2813 in the destination repository from the current one.
2808
2814
2809 By default, push will not allow creation of new heads at the
2815 By default, push will not allow creation of new heads at the
2810 destination, since multiple heads would make it unclear which head
2816 destination, since multiple heads would make it unclear which head
2811 to use. In this situation, it is recommended to pull and merge
2817 to use. In this situation, it is recommended to pull and merge
2812 before pushing.
2818 before pushing.
2813
2819
2814 Use --new-branch if you want to allow push to create a new named
2820 Use --new-branch if you want to allow push to create a new named
2815 branch that is not present at the destination. This allows you to
2821 branch that is not present at the destination. This allows you to
2816 only create a new branch without forcing other changes.
2822 only create a new branch without forcing other changes.
2817
2823
2818 Use -f/--force to override the default behavior and push all
2824 Use -f/--force to override the default behavior and push all
2819 changesets on all branches.
2825 changesets on all branches.
2820
2826
2821 If -r/--rev is used, the specified revision and all its ancestors
2827 If -r/--rev is used, the specified revision and all its ancestors
2822 will be pushed to the remote repository.
2828 will be pushed to the remote repository.
2823
2829
2824 Please see :hg:`help urls` for important details about ``ssh://``
2830 Please see :hg:`help urls` for important details about ``ssh://``
2825 URLs. If DESTINATION is omitted, a default path will be used.
2831 URLs. If DESTINATION is omitted, a default path will be used.
2826
2832
2827 Returns 0 if push was successful, 1 if nothing to push.
2833 Returns 0 if push was successful, 1 if nothing to push.
2828 """
2834 """
2829 dest = ui.expandpath(dest or 'default-push', dest or 'default')
2835 dest = ui.expandpath(dest or 'default-push', dest or 'default')
2830 dest, branches = hg.parseurl(dest, opts.get('branch'))
2836 dest, branches = hg.parseurl(dest, opts.get('branch'))
2831 revs, checkout = hg.addbranchrevs(repo, repo, branches, opts.get('rev'))
2837 revs, checkout = hg.addbranchrevs(repo, repo, branches, opts.get('rev'))
2832 other = hg.repository(hg.remoteui(repo, opts), dest)
2838 other = hg.repository(hg.remoteui(repo, opts), dest)
2833 ui.status(_('pushing to %s\n') % url.hidepassword(dest))
2839 ui.status(_('pushing to %s\n') % url.hidepassword(dest))
2834 if revs:
2840 if revs:
2835 revs = [repo.lookup(rev) for rev in revs]
2841 revs = [repo.lookup(rev) for rev in revs]
2836
2842
2837 # push subrepos depth-first for coherent ordering
2843 # push subrepos depth-first for coherent ordering
2838 c = repo['']
2844 c = repo['']
2839 subs = c.substate # only repos that are committed
2845 subs = c.substate # only repos that are committed
2840 for s in sorted(subs):
2846 for s in sorted(subs):
2841 if not c.sub(s).push(opts.get('force')):
2847 if not c.sub(s).push(opts.get('force')):
2842 return False
2848 return False
2843
2849
2844 r = repo.push(other, opts.get('force'), revs=revs,
2850 r = repo.push(other, opts.get('force'), revs=revs,
2845 newbranch=opts.get('new_branch'))
2851 newbranch=opts.get('new_branch'))
2846 return r == 0
2852 return r == 0
2847
2853
2848 def recover(ui, repo):
2854 def recover(ui, repo):
2849 """roll back an interrupted transaction
2855 """roll back an interrupted transaction
2850
2856
2851 Recover from an interrupted commit or pull.
2857 Recover from an interrupted commit or pull.
2852
2858
2853 This command tries to fix the repository status after an
2859 This command tries to fix the repository status after an
2854 interrupted operation. It should only be necessary when Mercurial
2860 interrupted operation. It should only be necessary when Mercurial
2855 suggests it.
2861 suggests it.
2856
2862
2857 Returns 0 if successful, 1 if nothing to recover or verify fails.
2863 Returns 0 if successful, 1 if nothing to recover or verify fails.
2858 """
2864 """
2859 if repo.recover():
2865 if repo.recover():
2860 return hg.verify(repo)
2866 return hg.verify(repo)
2861 return 1
2867 return 1
2862
2868
2863 def remove(ui, repo, *pats, **opts):
2869 def remove(ui, repo, *pats, **opts):
2864 """remove the specified files on the next commit
2870 """remove the specified files on the next commit
2865
2871
2866 Schedule the indicated files for removal from the repository.
2872 Schedule the indicated files for removal from the repository.
2867
2873
2868 This only removes files from the current branch, not from the
2874 This only removes files from the current branch, not from the
2869 entire project history. -A/--after can be used to remove only
2875 entire project history. -A/--after can be used to remove only
2870 files that have already been deleted, -f/--force can be used to
2876 files that have already been deleted, -f/--force can be used to
2871 force deletion, and -Af can be used to remove files from the next
2877 force deletion, and -Af can be used to remove files from the next
2872 revision without deleting them from the working directory.
2878 revision without deleting them from the working directory.
2873
2879
2874 The following table details the behavior of remove for different
2880 The following table details the behavior of remove for different
2875 file states (columns) and option combinations (rows). The file
2881 file states (columns) and option combinations (rows). The file
2876 states are Added [A], Clean [C], Modified [M] and Missing [!] (as
2882 states are Added [A], Clean [C], Modified [M] and Missing [!] (as
2877 reported by :hg:`status`). The actions are Warn, Remove (from
2883 reported by :hg:`status`). The actions are Warn, Remove (from
2878 branch) and Delete (from disk)::
2884 branch) and Delete (from disk)::
2879
2885
2880 A C M !
2886 A C M !
2881 none W RD W R
2887 none W RD W R
2882 -f R RD RD R
2888 -f R RD RD R
2883 -A W W W R
2889 -A W W W R
2884 -Af R R R R
2890 -Af R R R R
2885
2891
2886 This command schedules the files to be removed at the next commit.
2892 This command schedules the files to be removed at the next commit.
2887 To undo a remove before that, see :hg:`revert`.
2893 To undo a remove before that, see :hg:`revert`.
2888
2894
2889 Returns 0 on success, 1 if any warnings encountered.
2895 Returns 0 on success, 1 if any warnings encountered.
2890 """
2896 """
2891
2897
2892 ret = 0
2898 ret = 0
2893 after, force = opts.get('after'), opts.get('force')
2899 after, force = opts.get('after'), opts.get('force')
2894 if not pats and not after:
2900 if not pats and not after:
2895 raise util.Abort(_('no files specified'))
2901 raise util.Abort(_('no files specified'))
2896
2902
2897 m = cmdutil.match(repo, pats, opts)
2903 m = cmdutil.match(repo, pats, opts)
2898 s = repo.status(match=m, clean=True)
2904 s = repo.status(match=m, clean=True)
2899 modified, added, deleted, clean = s[0], s[1], s[3], s[6]
2905 modified, added, deleted, clean = s[0], s[1], s[3], s[6]
2900
2906
2901 for f in m.files():
2907 for f in m.files():
2902 if f not in repo.dirstate and not os.path.isdir(m.rel(f)):
2908 if f not in repo.dirstate and not os.path.isdir(m.rel(f)):
2903 ui.warn(_('not removing %s: file is untracked\n') % m.rel(f))
2909 ui.warn(_('not removing %s: file is untracked\n') % m.rel(f))
2904 ret = 1
2910 ret = 1
2905
2911
2906 def warn(files, reason):
2912 def warn(files, reason):
2907 for f in files:
2913 for f in files:
2908 ui.warn(_('not removing %s: file %s (use -f to force removal)\n')
2914 ui.warn(_('not removing %s: file %s (use -f to force removal)\n')
2909 % (m.rel(f), reason))
2915 % (m.rel(f), reason))
2910 ret = 1
2916 ret = 1
2911
2917
2912 if force:
2918 if force:
2913 remove, forget = modified + deleted + clean, added
2919 remove, forget = modified + deleted + clean, added
2914 elif after:
2920 elif after:
2915 remove, forget = deleted, []
2921 remove, forget = deleted, []
2916 warn(modified + added + clean, _('still exists'))
2922 warn(modified + added + clean, _('still exists'))
2917 else:
2923 else:
2918 remove, forget = deleted + clean, []
2924 remove, forget = deleted + clean, []
2919 warn(modified, _('is modified'))
2925 warn(modified, _('is modified'))
2920 warn(added, _('has been marked for add'))
2926 warn(added, _('has been marked for add'))
2921
2927
2922 for f in sorted(remove + forget):
2928 for f in sorted(remove + forget):
2923 if ui.verbose or not m.exact(f):
2929 if ui.verbose or not m.exact(f):
2924 ui.status(_('removing %s\n') % m.rel(f))
2930 ui.status(_('removing %s\n') % m.rel(f))
2925
2931
2926 repo[None].forget(forget)
2932 repo[None].forget(forget)
2927 repo[None].remove(remove, unlink=not after)
2933 repo[None].remove(remove, unlink=not after)
2928 return ret
2934 return ret
2929
2935
2930 def rename(ui, repo, *pats, **opts):
2936 def rename(ui, repo, *pats, **opts):
2931 """rename files; equivalent of copy + remove
2937 """rename files; equivalent of copy + remove
2932
2938
2933 Mark dest as copies of sources; mark sources for deletion. If dest
2939 Mark dest as copies of sources; mark sources for deletion. If dest
2934 is a directory, copies are put in that directory. If dest is a
2940 is a directory, copies are put in that directory. If dest is a
2935 file, there can only be one source.
2941 file, there can only be one source.
2936
2942
2937 By default, this command copies the contents of files as they
2943 By default, this command copies the contents of files as they
2938 exist in the working directory. If invoked with -A/--after, the
2944 exist in the working directory. If invoked with -A/--after, the
2939 operation is recorded, but no copying is performed.
2945 operation is recorded, but no copying is performed.
2940
2946
2941 This command takes effect at the next commit. To undo a rename
2947 This command takes effect at the next commit. To undo a rename
2942 before that, see :hg:`revert`.
2948 before that, see :hg:`revert`.
2943
2949
2944 Returns 0 on success, 1 if errors are encountered.
2950 Returns 0 on success, 1 if errors are encountered.
2945 """
2951 """
2946 wlock = repo.wlock(False)
2952 wlock = repo.wlock(False)
2947 try:
2953 try:
2948 return cmdutil.copy(ui, repo, pats, opts, rename=True)
2954 return cmdutil.copy(ui, repo, pats, opts, rename=True)
2949 finally:
2955 finally:
2950 wlock.release()
2956 wlock.release()
2951
2957
2952 def resolve(ui, repo, *pats, **opts):
2958 def resolve(ui, repo, *pats, **opts):
2953 """redo merges or set/view the merge status of files
2959 """redo merges or set/view the merge status of files
2954
2960
2955 Merges with unresolved conflicts are often the result of
2961 Merges with unresolved conflicts are often the result of
2956 non-interactive merging using the ``internal:merge`` hgrc setting,
2962 non-interactive merging using the ``internal:merge`` hgrc setting,
2957 or a command-line merge tool like ``diff3``. The resolve command
2963 or a command-line merge tool like ``diff3``. The resolve command
2958 is used to manage the files involved in a merge, after :hg:`merge`
2964 is used to manage the files involved in a merge, after :hg:`merge`
2959 has been run, and before :hg:`commit` is run (i.e. the working
2965 has been run, and before :hg:`commit` is run (i.e. the working
2960 directory must have two parents).
2966 directory must have two parents).
2961
2967
2962 The resolve command can be used in the following ways:
2968 The resolve command can be used in the following ways:
2963
2969
2964 - :hg:`resolve FILE...`: attempt to re-merge the specified files,
2970 - :hg:`resolve FILE...`: attempt to re-merge the specified files,
2965 discarding any previous merge attempts. Re-merging is not
2971 discarding any previous merge attempts. Re-merging is not
2966 performed for files already marked as resolved. Use ``--all/-a``
2972 performed for files already marked as resolved. Use ``--all/-a``
2967 to selects all unresolved files.
2973 to selects all unresolved files.
2968
2974
2969 - :hg:`resolve -m [FILE]`: mark a file as having been resolved
2975 - :hg:`resolve -m [FILE]`: mark a file as having been resolved
2970 (e.g. after having manually fixed-up the files). The default is
2976 (e.g. after having manually fixed-up the files). The default is
2971 to mark all unresolved files.
2977 to mark all unresolved files.
2972
2978
2973 - :hg:`resolve -u [FILE]...`: mark a file as unresolved. The
2979 - :hg:`resolve -u [FILE]...`: mark a file as unresolved. The
2974 default is to mark all resolved files.
2980 default is to mark all resolved files.
2975
2981
2976 - :hg:`resolve -l`: list files which had or still have conflicts.
2982 - :hg:`resolve -l`: list files which had or still have conflicts.
2977 In the printed list, ``U`` = unresolved and ``R`` = resolved.
2983 In the printed list, ``U`` = unresolved and ``R`` = resolved.
2978
2984
2979 Note that Mercurial will not let you commit files with unresolved
2985 Note that Mercurial will not let you commit files with unresolved
2980 merge conflicts. You must use :hg:`resolve -m ...` before you can
2986 merge conflicts. You must use :hg:`resolve -m ...` before you can
2981 commit after a conflicting merge.
2987 commit after a conflicting merge.
2982
2988
2983 Returns 0 on success, 1 if any files fail a resolve attempt.
2989 Returns 0 on success, 1 if any files fail a resolve attempt.
2984 """
2990 """
2985
2991
2986 all, mark, unmark, show, nostatus = \
2992 all, mark, unmark, show, nostatus = \
2987 [opts.get(o) for o in 'all mark unmark list no_status'.split()]
2993 [opts.get(o) for o in 'all mark unmark list no_status'.split()]
2988
2994
2989 if (show and (mark or unmark)) or (mark and unmark):
2995 if (show and (mark or unmark)) or (mark and unmark):
2990 raise util.Abort(_("too many options specified"))
2996 raise util.Abort(_("too many options specified"))
2991 if pats and all:
2997 if pats and all:
2992 raise util.Abort(_("can't specify --all and patterns"))
2998 raise util.Abort(_("can't specify --all and patterns"))
2993 if not (all or pats or show or mark or unmark):
2999 if not (all or pats or show or mark or unmark):
2994 raise util.Abort(_('no files or directories specified; '
3000 raise util.Abort(_('no files or directories specified; '
2995 'use --all to remerge all files'))
3001 'use --all to remerge all files'))
2996
3002
2997 ms = mergemod.mergestate(repo)
3003 ms = mergemod.mergestate(repo)
2998 m = cmdutil.match(repo, pats, opts)
3004 m = cmdutil.match(repo, pats, opts)
2999 ret = 0
3005 ret = 0
3000
3006
3001 for f in ms:
3007 for f in ms:
3002 if m(f):
3008 if m(f):
3003 if show:
3009 if show:
3004 if nostatus:
3010 if nostatus:
3005 ui.write("%s\n" % f)
3011 ui.write("%s\n" % f)
3006 else:
3012 else:
3007 ui.write("%s %s\n" % (ms[f].upper(), f),
3013 ui.write("%s %s\n" % (ms[f].upper(), f),
3008 label='resolve.' +
3014 label='resolve.' +
3009 {'u': 'unresolved', 'r': 'resolved'}[ms[f]])
3015 {'u': 'unresolved', 'r': 'resolved'}[ms[f]])
3010 elif mark:
3016 elif mark:
3011 ms.mark(f, "r")
3017 ms.mark(f, "r")
3012 elif unmark:
3018 elif unmark:
3013 ms.mark(f, "u")
3019 ms.mark(f, "u")
3014 else:
3020 else:
3015 wctx = repo[None]
3021 wctx = repo[None]
3016 mctx = wctx.parents()[-1]
3022 mctx = wctx.parents()[-1]
3017
3023
3018 # backup pre-resolve (merge uses .orig for its own purposes)
3024 # backup pre-resolve (merge uses .orig for its own purposes)
3019 a = repo.wjoin(f)
3025 a = repo.wjoin(f)
3020 util.copyfile(a, a + ".resolve")
3026 util.copyfile(a, a + ".resolve")
3021
3027
3022 # resolve file
3028 # resolve file
3023 if ms.resolve(f, wctx, mctx):
3029 if ms.resolve(f, wctx, mctx):
3024 ret = 1
3030 ret = 1
3025
3031
3026 # replace filemerge's .orig file with our resolve file
3032 # replace filemerge's .orig file with our resolve file
3027 util.rename(a + ".resolve", a + ".orig")
3033 util.rename(a + ".resolve", a + ".orig")
3028 return ret
3034 return ret
3029
3035
3030 def revert(ui, repo, *pats, **opts):
3036 def revert(ui, repo, *pats, **opts):
3031 """restore individual files or directories to an earlier state
3037 """restore individual files or directories to an earlier state
3032
3038
3033 NOTE: This command is most likely not what you are looking for. revert
3039 NOTE: This command is most likely not what you are looking for. revert
3034 will partially overwrite content in the working directory without changing
3040 will partially overwrite content in the working directory without changing
3035 the working directory parents. Use :hg:`update -r rev` to check out earlier
3041 the working directory parents. Use :hg:`update -r rev` to check out earlier
3036 revisions, or :hg:`update --clean .` to undo a merge which has added
3042 revisions, or :hg:`update --clean .` to undo a merge which has added
3037 another parent.
3043 another parent.
3038
3044
3039 With no revision specified, revert the named files or directories
3045 With no revision specified, revert the named files or directories
3040 to the contents they had in the parent of the working directory.
3046 to the contents they had in the parent of the working directory.
3041 This restores the contents of the affected files to an unmodified
3047 This restores the contents of the affected files to an unmodified
3042 state and unschedules adds, removes, copies, and renames. If the
3048 state and unschedules adds, removes, copies, and renames. If the
3043 working directory has two parents, you must explicitly specify a
3049 working directory has two parents, you must explicitly specify a
3044 revision.
3050 revision.
3045
3051
3046 Using the -r/--rev option, revert the given files or directories
3052 Using the -r/--rev option, revert the given files or directories
3047 to their contents as of a specific revision. This can be helpful
3053 to their contents as of a specific revision. This can be helpful
3048 to "roll back" some or all of an earlier change. See :hg:`help
3054 to "roll back" some or all of an earlier change. See :hg:`help
3049 dates` for a list of formats valid for -d/--date.
3055 dates` for a list of formats valid for -d/--date.
3050
3056
3051 Revert modifies the working directory. It does not commit any
3057 Revert modifies the working directory. It does not commit any
3052 changes, or change the parent of the working directory. If you
3058 changes, or change the parent of the working directory. If you
3053 revert to a revision other than the parent of the working
3059 revert to a revision other than the parent of the working
3054 directory, the reverted files will thus appear modified
3060 directory, the reverted files will thus appear modified
3055 afterwards.
3061 afterwards.
3056
3062
3057 If a file has been deleted, it is restored. If the executable mode
3063 If a file has been deleted, it is restored. If the executable mode
3058 of a file was changed, it is reset.
3064 of a file was changed, it is reset.
3059
3065
3060 If names are given, all files matching the names are reverted.
3066 If names are given, all files matching the names are reverted.
3061 If no arguments are given, no files are reverted.
3067 If no arguments are given, no files are reverted.
3062
3068
3063 Modified files are saved with a .orig suffix before reverting.
3069 Modified files are saved with a .orig suffix before reverting.
3064 To disable these backups, use --no-backup.
3070 To disable these backups, use --no-backup.
3065
3071
3066 Returns 0 on success.
3072 Returns 0 on success.
3067 """
3073 """
3068
3074
3069 if opts.get("date"):
3075 if opts.get("date"):
3070 if opts.get("rev"):
3076 if opts.get("rev"):
3071 raise util.Abort(_("you can't specify a revision and a date"))
3077 raise util.Abort(_("you can't specify a revision and a date"))
3072 opts["rev"] = cmdutil.finddate(ui, repo, opts["date"])
3078 opts["rev"] = cmdutil.finddate(ui, repo, opts["date"])
3073
3079
3074 if not pats and not opts.get('all'):
3080 if not pats and not opts.get('all'):
3075 raise util.Abort(_('no files or directories specified; '
3081 raise util.Abort(_('no files or directories specified; '
3076 'use --all to revert the whole repo'))
3082 'use --all to revert the whole repo'))
3077
3083
3078 parent, p2 = repo.dirstate.parents()
3084 parent, p2 = repo.dirstate.parents()
3079 if not opts.get('rev') and p2 != nullid:
3085 if not opts.get('rev') and p2 != nullid:
3080 raise util.Abort(_('uncommitted merge - please provide a '
3086 raise util.Abort(_('uncommitted merge - please provide a '
3081 'specific revision'))
3087 'specific revision'))
3082 ctx = repo[opts.get('rev')]
3088 ctx = repo[opts.get('rev')]
3083 node = ctx.node()
3089 node = ctx.node()
3084 mf = ctx.manifest()
3090 mf = ctx.manifest()
3085 if node == parent:
3091 if node == parent:
3086 pmf = mf
3092 pmf = mf
3087 else:
3093 else:
3088 pmf = None
3094 pmf = None
3089
3095
3090 # need all matching names in dirstate and manifest of target rev,
3096 # need all matching names in dirstate and manifest of target rev,
3091 # so have to walk both. do not print errors if files exist in one
3097 # so have to walk both. do not print errors if files exist in one
3092 # but not other.
3098 # but not other.
3093
3099
3094 names = {}
3100 names = {}
3095
3101
3096 wlock = repo.wlock()
3102 wlock = repo.wlock()
3097 try:
3103 try:
3098 # walk dirstate.
3104 # walk dirstate.
3099
3105
3100 m = cmdutil.match(repo, pats, opts)
3106 m = cmdutil.match(repo, pats, opts)
3101 m.bad = lambda x, y: False
3107 m.bad = lambda x, y: False
3102 for abs in repo.walk(m):
3108 for abs in repo.walk(m):
3103 names[abs] = m.rel(abs), m.exact(abs)
3109 names[abs] = m.rel(abs), m.exact(abs)
3104
3110
3105 # walk target manifest.
3111 # walk target manifest.
3106
3112
3107 def badfn(path, msg):
3113 def badfn(path, msg):
3108 if path in names:
3114 if path in names:
3109 return
3115 return
3110 path_ = path + '/'
3116 path_ = path + '/'
3111 for f in names:
3117 for f in names:
3112 if f.startswith(path_):
3118 if f.startswith(path_):
3113 return
3119 return
3114 ui.warn("%s: %s\n" % (m.rel(path), msg))
3120 ui.warn("%s: %s\n" % (m.rel(path), msg))
3115
3121
3116 m = cmdutil.match(repo, pats, opts)
3122 m = cmdutil.match(repo, pats, opts)
3117 m.bad = badfn
3123 m.bad = badfn
3118 for abs in repo[node].walk(m):
3124 for abs in repo[node].walk(m):
3119 if abs not in names:
3125 if abs not in names:
3120 names[abs] = m.rel(abs), m.exact(abs)
3126 names[abs] = m.rel(abs), m.exact(abs)
3121
3127
3122 m = cmdutil.matchfiles(repo, names)
3128 m = cmdutil.matchfiles(repo, names)
3123 changes = repo.status(match=m)[:4]
3129 changes = repo.status(match=m)[:4]
3124 modified, added, removed, deleted = map(set, changes)
3130 modified, added, removed, deleted = map(set, changes)
3125
3131
3126 # if f is a rename, also revert the source
3132 # if f is a rename, also revert the source
3127 cwd = repo.getcwd()
3133 cwd = repo.getcwd()
3128 for f in added:
3134 for f in added:
3129 src = repo.dirstate.copied(f)
3135 src = repo.dirstate.copied(f)
3130 if src and src not in names and repo.dirstate[src] == 'r':
3136 if src and src not in names and repo.dirstate[src] == 'r':
3131 removed.add(src)
3137 removed.add(src)
3132 names[src] = (repo.pathto(src, cwd), True)
3138 names[src] = (repo.pathto(src, cwd), True)
3133
3139
3134 def removeforget(abs):
3140 def removeforget(abs):
3135 if repo.dirstate[abs] == 'a':
3141 if repo.dirstate[abs] == 'a':
3136 return _('forgetting %s\n')
3142 return _('forgetting %s\n')
3137 return _('removing %s\n')
3143 return _('removing %s\n')
3138
3144
3139 revert = ([], _('reverting %s\n'))
3145 revert = ([], _('reverting %s\n'))
3140 add = ([], _('adding %s\n'))
3146 add = ([], _('adding %s\n'))
3141 remove = ([], removeforget)
3147 remove = ([], removeforget)
3142 undelete = ([], _('undeleting %s\n'))
3148 undelete = ([], _('undeleting %s\n'))
3143
3149
3144 disptable = (
3150 disptable = (
3145 # dispatch table:
3151 # dispatch table:
3146 # file state
3152 # file state
3147 # action if in target manifest
3153 # action if in target manifest
3148 # action if not in target manifest
3154 # action if not in target manifest
3149 # make backup if in target manifest
3155 # make backup if in target manifest
3150 # make backup if not in target manifest
3156 # make backup if not in target manifest
3151 (modified, revert, remove, True, True),
3157 (modified, revert, remove, True, True),
3152 (added, revert, remove, True, False),
3158 (added, revert, remove, True, False),
3153 (removed, undelete, None, False, False),
3159 (removed, undelete, None, False, False),
3154 (deleted, revert, remove, False, False),
3160 (deleted, revert, remove, False, False),
3155 )
3161 )
3156
3162
3157 for abs, (rel, exact) in sorted(names.items()):
3163 for abs, (rel, exact) in sorted(names.items()):
3158 mfentry = mf.get(abs)
3164 mfentry = mf.get(abs)
3159 target = repo.wjoin(abs)
3165 target = repo.wjoin(abs)
3160 def handle(xlist, dobackup):
3166 def handle(xlist, dobackup):
3161 xlist[0].append(abs)
3167 xlist[0].append(abs)
3162 if dobackup and not opts.get('no_backup') and util.lexists(target):
3168 if dobackup and not opts.get('no_backup') and util.lexists(target):
3163 bakname = "%s.orig" % rel
3169 bakname = "%s.orig" % rel
3164 ui.note(_('saving current version of %s as %s\n') %
3170 ui.note(_('saving current version of %s as %s\n') %
3165 (rel, bakname))
3171 (rel, bakname))
3166 if not opts.get('dry_run'):
3172 if not opts.get('dry_run'):
3167 util.rename(target, bakname)
3173 util.rename(target, bakname)
3168 if ui.verbose or not exact:
3174 if ui.verbose or not exact:
3169 msg = xlist[1]
3175 msg = xlist[1]
3170 if not isinstance(msg, basestring):
3176 if not isinstance(msg, basestring):
3171 msg = msg(abs)
3177 msg = msg(abs)
3172 ui.status(msg % rel)
3178 ui.status(msg % rel)
3173 for table, hitlist, misslist, backuphit, backupmiss in disptable:
3179 for table, hitlist, misslist, backuphit, backupmiss in disptable:
3174 if abs not in table:
3180 if abs not in table:
3175 continue
3181 continue
3176 # file has changed in dirstate
3182 # file has changed in dirstate
3177 if mfentry:
3183 if mfentry:
3178 handle(hitlist, backuphit)
3184 handle(hitlist, backuphit)
3179 elif misslist is not None:
3185 elif misslist is not None:
3180 handle(misslist, backupmiss)
3186 handle(misslist, backupmiss)
3181 break
3187 break
3182 else:
3188 else:
3183 if abs not in repo.dirstate:
3189 if abs not in repo.dirstate:
3184 if mfentry:
3190 if mfentry:
3185 handle(add, True)
3191 handle(add, True)
3186 elif exact:
3192 elif exact:
3187 ui.warn(_('file not managed: %s\n') % rel)
3193 ui.warn(_('file not managed: %s\n') % rel)
3188 continue
3194 continue
3189 # file has not changed in dirstate
3195 # file has not changed in dirstate
3190 if node == parent:
3196 if node == parent:
3191 if exact:
3197 if exact:
3192 ui.warn(_('no changes needed to %s\n') % rel)
3198 ui.warn(_('no changes needed to %s\n') % rel)
3193 continue
3199 continue
3194 if pmf is None:
3200 if pmf is None:
3195 # only need parent manifest in this unlikely case,
3201 # only need parent manifest in this unlikely case,
3196 # so do not read by default
3202 # so do not read by default
3197 pmf = repo[parent].manifest()
3203 pmf = repo[parent].manifest()
3198 if abs in pmf:
3204 if abs in pmf:
3199 if mfentry:
3205 if mfentry:
3200 # if version of file is same in parent and target
3206 # if version of file is same in parent and target
3201 # manifests, do nothing
3207 # manifests, do nothing
3202 if (pmf[abs] != mfentry or
3208 if (pmf[abs] != mfentry or
3203 pmf.flags(abs) != mf.flags(abs)):
3209 pmf.flags(abs) != mf.flags(abs)):
3204 handle(revert, False)
3210 handle(revert, False)
3205 else:
3211 else:
3206 handle(remove, False)
3212 handle(remove, False)
3207
3213
3208 if not opts.get('dry_run'):
3214 if not opts.get('dry_run'):
3209 def checkout(f):
3215 def checkout(f):
3210 fc = ctx[f]
3216 fc = ctx[f]
3211 repo.wwrite(f, fc.data(), fc.flags())
3217 repo.wwrite(f, fc.data(), fc.flags())
3212
3218
3213 audit_path = util.path_auditor(repo.root)
3219 audit_path = util.path_auditor(repo.root)
3214 for f in remove[0]:
3220 for f in remove[0]:
3215 if repo.dirstate[f] == 'a':
3221 if repo.dirstate[f] == 'a':
3216 repo.dirstate.forget(f)
3222 repo.dirstate.forget(f)
3217 continue
3223 continue
3218 audit_path(f)
3224 audit_path(f)
3219 try:
3225 try:
3220 util.unlink(repo.wjoin(f))
3226 util.unlink(repo.wjoin(f))
3221 except OSError:
3227 except OSError:
3222 pass
3228 pass
3223 repo.dirstate.remove(f)
3229 repo.dirstate.remove(f)
3224
3230
3225 normal = None
3231 normal = None
3226 if node == parent:
3232 if node == parent:
3227 # We're reverting to our parent. If possible, we'd like status
3233 # We're reverting to our parent. If possible, we'd like status
3228 # to report the file as clean. We have to use normallookup for
3234 # to report the file as clean. We have to use normallookup for
3229 # merges to avoid losing information about merged/dirty files.
3235 # merges to avoid losing information about merged/dirty files.
3230 if p2 != nullid:
3236 if p2 != nullid:
3231 normal = repo.dirstate.normallookup
3237 normal = repo.dirstate.normallookup
3232 else:
3238 else:
3233 normal = repo.dirstate.normal
3239 normal = repo.dirstate.normal
3234 for f in revert[0]:
3240 for f in revert[0]:
3235 checkout(f)
3241 checkout(f)
3236 if normal:
3242 if normal:
3237 normal(f)
3243 normal(f)
3238
3244
3239 for f in add[0]:
3245 for f in add[0]:
3240 checkout(f)
3246 checkout(f)
3241 repo.dirstate.add(f)
3247 repo.dirstate.add(f)
3242
3248
3243 normal = repo.dirstate.normallookup
3249 normal = repo.dirstate.normallookup
3244 if node == parent and p2 == nullid:
3250 if node == parent and p2 == nullid:
3245 normal = repo.dirstate.normal
3251 normal = repo.dirstate.normal
3246 for f in undelete[0]:
3252 for f in undelete[0]:
3247 checkout(f)
3253 checkout(f)
3248 normal(f)
3254 normal(f)
3249
3255
3250 finally:
3256 finally:
3251 wlock.release()
3257 wlock.release()
3252
3258
3253 def rollback(ui, repo, **opts):
3259 def rollback(ui, repo, **opts):
3254 """roll back the last transaction (dangerous)
3260 """roll back the last transaction (dangerous)
3255
3261
3256 This command should be used with care. There is only one level of
3262 This command should be used with care. There is only one level of
3257 rollback, and there is no way to undo a rollback. It will also
3263 rollback, and there is no way to undo a rollback. It will also
3258 restore the dirstate at the time of the last transaction, losing
3264 restore the dirstate at the time of the last transaction, losing
3259 any dirstate changes since that time. This command does not alter
3265 any dirstate changes since that time. This command does not alter
3260 the working directory.
3266 the working directory.
3261
3267
3262 Transactions are used to encapsulate the effects of all commands
3268 Transactions are used to encapsulate the effects of all commands
3263 that create new changesets or propagate existing changesets into a
3269 that create new changesets or propagate existing changesets into a
3264 repository. For example, the following commands are transactional,
3270 repository. For example, the following commands are transactional,
3265 and their effects can be rolled back:
3271 and their effects can be rolled back:
3266
3272
3267 - commit
3273 - commit
3268 - import
3274 - import
3269 - pull
3275 - pull
3270 - push (with this repository as the destination)
3276 - push (with this repository as the destination)
3271 - unbundle
3277 - unbundle
3272
3278
3273 This command is not intended for use on public repositories. Once
3279 This command is not intended for use on public repositories. Once
3274 changes are visible for pull by other users, rolling a transaction
3280 changes are visible for pull by other users, rolling a transaction
3275 back locally is ineffective (someone else may already have pulled
3281 back locally is ineffective (someone else may already have pulled
3276 the changes). Furthermore, a race is possible with readers of the
3282 the changes). Furthermore, a race is possible with readers of the
3277 repository; for example an in-progress pull from the repository
3283 repository; for example an in-progress pull from the repository
3278 may fail if a rollback is performed.
3284 may fail if a rollback is performed.
3279
3285
3280 Returns 0 on success, 1 if no rollback data is available.
3286 Returns 0 on success, 1 if no rollback data is available.
3281 """
3287 """
3282 return repo.rollback(opts.get('dry_run'))
3288 return repo.rollback(opts.get('dry_run'))
3283
3289
3284 def root(ui, repo):
3290 def root(ui, repo):
3285 """print the root (top) of the current working directory
3291 """print the root (top) of the current working directory
3286
3292
3287 Print the root directory of the current repository.
3293 Print the root directory of the current repository.
3288
3294
3289 Returns 0 on success.
3295 Returns 0 on success.
3290 """
3296 """
3291 ui.write(repo.root + "\n")
3297 ui.write(repo.root + "\n")
3292
3298
3293 def serve(ui, repo, **opts):
3299 def serve(ui, repo, **opts):
3294 """start stand-alone webserver
3300 """start stand-alone webserver
3295
3301
3296 Start a local HTTP repository browser and pull server. You can use
3302 Start a local HTTP repository browser and pull server. You can use
3297 this for ad-hoc sharing and browing of repositories. It is
3303 this for ad-hoc sharing and browing of repositories. It is
3298 recommended to use a real web server to serve a repository for
3304 recommended to use a real web server to serve a repository for
3299 longer periods of time.
3305 longer periods of time.
3300
3306
3301 Please note that the server does not implement access control.
3307 Please note that the server does not implement access control.
3302 This means that, by default, anybody can read from the server and
3308 This means that, by default, anybody can read from the server and
3303 nobody can write to it by default. Set the ``web.allow_push``
3309 nobody can write to it by default. Set the ``web.allow_push``
3304 option to ``*`` to allow everybody to push to the server. You
3310 option to ``*`` to allow everybody to push to the server. You
3305 should use a real web server if you need to authenticate users.
3311 should use a real web server if you need to authenticate users.
3306
3312
3307 By default, the server logs accesses to stdout and errors to
3313 By default, the server logs accesses to stdout and errors to
3308 stderr. Use the -A/--accesslog and -E/--errorlog options to log to
3314 stderr. Use the -A/--accesslog and -E/--errorlog options to log to
3309 files.
3315 files.
3310
3316
3311 To have the server choose a free port number to listen on, specify
3317 To have the server choose a free port number to listen on, specify
3312 a port number of 0; in this case, the server will print the port
3318 a port number of 0; in this case, the server will print the port
3313 number it uses.
3319 number it uses.
3314
3320
3315 Returns 0 on success.
3321 Returns 0 on success.
3316 """
3322 """
3317
3323
3318 if opts["stdio"]:
3324 if opts["stdio"]:
3319 if repo is None:
3325 if repo is None:
3320 raise error.RepoError(_("There is no Mercurial repository here"
3326 raise error.RepoError(_("There is no Mercurial repository here"
3321 " (.hg not found)"))
3327 " (.hg not found)"))
3322 s = sshserver.sshserver(ui, repo)
3328 s = sshserver.sshserver(ui, repo)
3323 s.serve_forever()
3329 s.serve_forever()
3324
3330
3325 # this way we can check if something was given in the command-line
3331 # this way we can check if something was given in the command-line
3326 if opts.get('port'):
3332 if opts.get('port'):
3327 opts['port'] = int(opts.get('port'))
3333 opts['port'] = int(opts.get('port'))
3328
3334
3329 baseui = repo and repo.baseui or ui
3335 baseui = repo and repo.baseui or ui
3330 optlist = ("name templates style address port prefix ipv6"
3336 optlist = ("name templates style address port prefix ipv6"
3331 " accesslog errorlog certificate encoding")
3337 " accesslog errorlog certificate encoding")
3332 for o in optlist.split():
3338 for o in optlist.split():
3333 val = opts.get(o, '')
3339 val = opts.get(o, '')
3334 if val in (None, ''): # should check against default options instead
3340 if val in (None, ''): # should check against default options instead
3335 continue
3341 continue
3336 baseui.setconfig("web", o, val)
3342 baseui.setconfig("web", o, val)
3337 if repo and repo.ui != baseui:
3343 if repo and repo.ui != baseui:
3338 repo.ui.setconfig("web", o, val)
3344 repo.ui.setconfig("web", o, val)
3339
3345
3340 o = opts.get('web_conf') or opts.get('webdir_conf')
3346 o = opts.get('web_conf') or opts.get('webdir_conf')
3341 if not o:
3347 if not o:
3342 if not repo:
3348 if not repo:
3343 raise error.RepoError(_("There is no Mercurial repository"
3349 raise error.RepoError(_("There is no Mercurial repository"
3344 " here (.hg not found)"))
3350 " here (.hg not found)"))
3345 o = repo.root
3351 o = repo.root
3346
3352
3347 app = hgweb.hgweb(o, baseui=ui)
3353 app = hgweb.hgweb(o, baseui=ui)
3348
3354
3349 class service(object):
3355 class service(object):
3350 def init(self):
3356 def init(self):
3351 util.set_signal_handler()
3357 util.set_signal_handler()
3352 self.httpd = hgweb.server.create_server(ui, app)
3358 self.httpd = hgweb.server.create_server(ui, app)
3353
3359
3354 if opts['port'] and not ui.verbose:
3360 if opts['port'] and not ui.verbose:
3355 return
3361 return
3356
3362
3357 if self.httpd.prefix:
3363 if self.httpd.prefix:
3358 prefix = self.httpd.prefix.strip('/') + '/'
3364 prefix = self.httpd.prefix.strip('/') + '/'
3359 else:
3365 else:
3360 prefix = ''
3366 prefix = ''
3361
3367
3362 port = ':%d' % self.httpd.port
3368 port = ':%d' % self.httpd.port
3363 if port == ':80':
3369 if port == ':80':
3364 port = ''
3370 port = ''
3365
3371
3366 bindaddr = self.httpd.addr
3372 bindaddr = self.httpd.addr
3367 if bindaddr == '0.0.0.0':
3373 if bindaddr == '0.0.0.0':
3368 bindaddr = '*'
3374 bindaddr = '*'
3369 elif ':' in bindaddr: # IPv6
3375 elif ':' in bindaddr: # IPv6
3370 bindaddr = '[%s]' % bindaddr
3376 bindaddr = '[%s]' % bindaddr
3371
3377
3372 fqaddr = self.httpd.fqaddr
3378 fqaddr = self.httpd.fqaddr
3373 if ':' in fqaddr:
3379 if ':' in fqaddr:
3374 fqaddr = '[%s]' % fqaddr
3380 fqaddr = '[%s]' % fqaddr
3375 if opts['port']:
3381 if opts['port']:
3376 write = ui.status
3382 write = ui.status
3377 else:
3383 else:
3378 write = ui.write
3384 write = ui.write
3379 write(_('listening at http://%s%s/%s (bound to %s:%d)\n') %
3385 write(_('listening at http://%s%s/%s (bound to %s:%d)\n') %
3380 (fqaddr, port, prefix, bindaddr, self.httpd.port))
3386 (fqaddr, port, prefix, bindaddr, self.httpd.port))
3381
3387
3382 def run(self):
3388 def run(self):
3383 self.httpd.serve_forever()
3389 self.httpd.serve_forever()
3384
3390
3385 service = service()
3391 service = service()
3386
3392
3387 cmdutil.service(opts, initfn=service.init, runfn=service.run)
3393 cmdutil.service(opts, initfn=service.init, runfn=service.run)
3388
3394
3389 def status(ui, repo, *pats, **opts):
3395 def status(ui, repo, *pats, **opts):
3390 """show changed files in the working directory
3396 """show changed files in the working directory
3391
3397
3392 Show status of files in the repository. If names are given, only
3398 Show status of files in the repository. If names are given, only
3393 files that match are shown. Files that are clean or ignored or
3399 files that match are shown. Files that are clean or ignored or
3394 the source of a copy/move operation, are not listed unless
3400 the source of a copy/move operation, are not listed unless
3395 -c/--clean, -i/--ignored, -C/--copies or -A/--all are given.
3401 -c/--clean, -i/--ignored, -C/--copies or -A/--all are given.
3396 Unless options described with "show only ..." are given, the
3402 Unless options described with "show only ..." are given, the
3397 options -mardu are used.
3403 options -mardu are used.
3398
3404
3399 Option -q/--quiet hides untracked (unknown and ignored) files
3405 Option -q/--quiet hides untracked (unknown and ignored) files
3400 unless explicitly requested with -u/--unknown or -i/--ignored.
3406 unless explicitly requested with -u/--unknown or -i/--ignored.
3401
3407
3402 NOTE: status may appear to disagree with diff if permissions have
3408 NOTE: status may appear to disagree with diff if permissions have
3403 changed or a merge has occurred. The standard diff format does not
3409 changed or a merge has occurred. The standard diff format does not
3404 report permission changes and diff only reports changes relative
3410 report permission changes and diff only reports changes relative
3405 to one merge parent.
3411 to one merge parent.
3406
3412
3407 If one revision is given, it is used as the base revision.
3413 If one revision is given, it is used as the base revision.
3408 If two revisions are given, the differences between them are
3414 If two revisions are given, the differences between them are
3409 shown. The --change option can also be used as a shortcut to list
3415 shown. The --change option can also be used as a shortcut to list
3410 the changed files of a revision from its first parent.
3416 the changed files of a revision from its first parent.
3411
3417
3412 The codes used to show the status of files are::
3418 The codes used to show the status of files are::
3413
3419
3414 M = modified
3420 M = modified
3415 A = added
3421 A = added
3416 R = removed
3422 R = removed
3417 C = clean
3423 C = clean
3418 ! = missing (deleted by non-hg command, but still tracked)
3424 ! = missing (deleted by non-hg command, but still tracked)
3419 ? = not tracked
3425 ? = not tracked
3420 I = ignored
3426 I = ignored
3421 = origin of the previous file listed as A (added)
3427 = origin of the previous file listed as A (added)
3422
3428
3423 Returns 0 on success.
3429 Returns 0 on success.
3424 """
3430 """
3425
3431
3426 revs = opts.get('rev')
3432 revs = opts.get('rev')
3427 change = opts.get('change')
3433 change = opts.get('change')
3428
3434
3429 if revs and change:
3435 if revs and change:
3430 msg = _('cannot specify --rev and --change at the same time')
3436 msg = _('cannot specify --rev and --change at the same time')
3431 raise util.Abort(msg)
3437 raise util.Abort(msg)
3432 elif change:
3438 elif change:
3433 node2 = repo.lookup(change)
3439 node2 = repo.lookup(change)
3434 node1 = repo[node2].parents()[0].node()
3440 node1 = repo[node2].parents()[0].node()
3435 else:
3441 else:
3436 node1, node2 = cmdutil.revpair(repo, revs)
3442 node1, node2 = cmdutil.revpair(repo, revs)
3437
3443
3438 cwd = (pats and repo.getcwd()) or ''
3444 cwd = (pats and repo.getcwd()) or ''
3439 end = opts.get('print0') and '\0' or '\n'
3445 end = opts.get('print0') and '\0' or '\n'
3440 copy = {}
3446 copy = {}
3441 states = 'modified added removed deleted unknown ignored clean'.split()
3447 states = 'modified added removed deleted unknown ignored clean'.split()
3442 show = [k for k in states if opts.get(k)]
3448 show = [k for k in states if opts.get(k)]
3443 if opts.get('all'):
3449 if opts.get('all'):
3444 show += ui.quiet and (states[:4] + ['clean']) or states
3450 show += ui.quiet and (states[:4] + ['clean']) or states
3445 if not show:
3451 if not show:
3446 show = ui.quiet and states[:4] or states[:5]
3452 show = ui.quiet and states[:4] or states[:5]
3447
3453
3448 stat = repo.status(node1, node2, cmdutil.match(repo, pats, opts),
3454 stat = repo.status(node1, node2, cmdutil.match(repo, pats, opts),
3449 'ignored' in show, 'clean' in show, 'unknown' in show)
3455 'ignored' in show, 'clean' in show, 'unknown' in show)
3450 changestates = zip(states, 'MAR!?IC', stat)
3456 changestates = zip(states, 'MAR!?IC', stat)
3451
3457
3452 if (opts.get('all') or opts.get('copies')) and not opts.get('no_status'):
3458 if (opts.get('all') or opts.get('copies')) and not opts.get('no_status'):
3453 ctxn = repo[nullid]
3459 ctxn = repo[nullid]
3454 ctx1 = repo[node1]
3460 ctx1 = repo[node1]
3455 ctx2 = repo[node2]
3461 ctx2 = repo[node2]
3456 added = stat[1]
3462 added = stat[1]
3457 if node2 is None:
3463 if node2 is None:
3458 added = stat[0] + stat[1] # merged?
3464 added = stat[0] + stat[1] # merged?
3459
3465
3460 for k, v in copies.copies(repo, ctx1, ctx2, ctxn)[0].iteritems():
3466 for k, v in copies.copies(repo, ctx1, ctx2, ctxn)[0].iteritems():
3461 if k in added:
3467 if k in added:
3462 copy[k] = v
3468 copy[k] = v
3463 elif v in added:
3469 elif v in added:
3464 copy[v] = k
3470 copy[v] = k
3465
3471
3466 for state, char, files in changestates:
3472 for state, char, files in changestates:
3467 if state in show:
3473 if state in show:
3468 format = "%s %%s%s" % (char, end)
3474 format = "%s %%s%s" % (char, end)
3469 if opts.get('no_status'):
3475 if opts.get('no_status'):
3470 format = "%%s%s" % end
3476 format = "%%s%s" % end
3471
3477
3472 for f in files:
3478 for f in files:
3473 ui.write(format % repo.pathto(f, cwd),
3479 ui.write(format % repo.pathto(f, cwd),
3474 label='status.' + state)
3480 label='status.' + state)
3475 if f in copy:
3481 if f in copy:
3476 ui.write(' %s%s' % (repo.pathto(copy[f], cwd), end),
3482 ui.write(' %s%s' % (repo.pathto(copy[f], cwd), end),
3477 label='status.copied')
3483 label='status.copied')
3478
3484
3479 def summary(ui, repo, **opts):
3485 def summary(ui, repo, **opts):
3480 """summarize working directory state
3486 """summarize working directory state
3481
3487
3482 This generates a brief summary of the working directory state,
3488 This generates a brief summary of the working directory state,
3483 including parents, branch, commit status, and available updates.
3489 including parents, branch, commit status, and available updates.
3484
3490
3485 With the --remote option, this will check the default paths for
3491 With the --remote option, this will check the default paths for
3486 incoming and outgoing changes. This can be time-consuming.
3492 incoming and outgoing changes. This can be time-consuming.
3487
3493
3488 Returns 0 on success.
3494 Returns 0 on success.
3489 """
3495 """
3490
3496
3491 ctx = repo[None]
3497 ctx = repo[None]
3492 parents = ctx.parents()
3498 parents = ctx.parents()
3493 pnode = parents[0].node()
3499 pnode = parents[0].node()
3494
3500
3495 for p in parents:
3501 for p in parents:
3496 # label with log.changeset (instead of log.parent) since this
3502 # label with log.changeset (instead of log.parent) since this
3497 # shows a working directory parent *changeset*:
3503 # shows a working directory parent *changeset*:
3498 ui.write(_('parent: %d:%s ') % (p.rev(), str(p)),
3504 ui.write(_('parent: %d:%s ') % (p.rev(), str(p)),
3499 label='log.changeset')
3505 label='log.changeset')
3500 ui.write(' '.join(p.tags()), label='log.tag')
3506 ui.write(' '.join(p.tags()), label='log.tag')
3501 if p.rev() == -1:
3507 if p.rev() == -1:
3502 if not len(repo):
3508 if not len(repo):
3503 ui.write(_(' (empty repository)'))
3509 ui.write(_(' (empty repository)'))
3504 else:
3510 else:
3505 ui.write(_(' (no revision checked out)'))
3511 ui.write(_(' (no revision checked out)'))
3506 ui.write('\n')
3512 ui.write('\n')
3507 if p.description():
3513 if p.description():
3508 ui.status(' ' + p.description().splitlines()[0].strip() + '\n',
3514 ui.status(' ' + p.description().splitlines()[0].strip() + '\n',
3509 label='log.summary')
3515 label='log.summary')
3510
3516
3511 branch = ctx.branch()
3517 branch = ctx.branch()
3512 bheads = repo.branchheads(branch)
3518 bheads = repo.branchheads(branch)
3513 m = _('branch: %s\n') % branch
3519 m = _('branch: %s\n') % branch
3514 if branch != 'default':
3520 if branch != 'default':
3515 ui.write(m, label='log.branch')
3521 ui.write(m, label='log.branch')
3516 else:
3522 else:
3517 ui.status(m, label='log.branch')
3523 ui.status(m, label='log.branch')
3518
3524
3519 st = list(repo.status(unknown=True))[:6]
3525 st = list(repo.status(unknown=True))[:6]
3520
3526
3521 c = repo.dirstate.copies()
3527 c = repo.dirstate.copies()
3522 copied, renamed = [], []
3528 copied, renamed = [], []
3523 for d, s in c.iteritems():
3529 for d, s in c.iteritems():
3524 if s in st[2]:
3530 if s in st[2]:
3525 st[2].remove(s)
3531 st[2].remove(s)
3526 renamed.append(d)
3532 renamed.append(d)
3527 else:
3533 else:
3528 copied.append(d)
3534 copied.append(d)
3529 if d in st[1]:
3535 if d in st[1]:
3530 st[1].remove(d)
3536 st[1].remove(d)
3531 st.insert(3, renamed)
3537 st.insert(3, renamed)
3532 st.insert(4, copied)
3538 st.insert(4, copied)
3533
3539
3534 ms = mergemod.mergestate(repo)
3540 ms = mergemod.mergestate(repo)
3535 st.append([f for f in ms if ms[f] == 'u'])
3541 st.append([f for f in ms if ms[f] == 'u'])
3536
3542
3537 subs = [s for s in ctx.substate if ctx.sub(s).dirty()]
3543 subs = [s for s in ctx.substate if ctx.sub(s).dirty()]
3538 st.append(subs)
3544 st.append(subs)
3539
3545
3540 labels = [ui.label(_('%d modified'), 'status.modified'),
3546 labels = [ui.label(_('%d modified'), 'status.modified'),
3541 ui.label(_('%d added'), 'status.added'),
3547 ui.label(_('%d added'), 'status.added'),
3542 ui.label(_('%d removed'), 'status.removed'),
3548 ui.label(_('%d removed'), 'status.removed'),
3543 ui.label(_('%d renamed'), 'status.copied'),
3549 ui.label(_('%d renamed'), 'status.copied'),
3544 ui.label(_('%d copied'), 'status.copied'),
3550 ui.label(_('%d copied'), 'status.copied'),
3545 ui.label(_('%d deleted'), 'status.deleted'),
3551 ui.label(_('%d deleted'), 'status.deleted'),
3546 ui.label(_('%d unknown'), 'status.unknown'),
3552 ui.label(_('%d unknown'), 'status.unknown'),
3547 ui.label(_('%d ignored'), 'status.ignored'),
3553 ui.label(_('%d ignored'), 'status.ignored'),
3548 ui.label(_('%d unresolved'), 'resolve.unresolved'),
3554 ui.label(_('%d unresolved'), 'resolve.unresolved'),
3549 ui.label(_('%d subrepos'), 'status.modified')]
3555 ui.label(_('%d subrepos'), 'status.modified')]
3550 t = []
3556 t = []
3551 for s, l in zip(st, labels):
3557 for s, l in zip(st, labels):
3552 if s:
3558 if s:
3553 t.append(l % len(s))
3559 t.append(l % len(s))
3554
3560
3555 t = ', '.join(t)
3561 t = ', '.join(t)
3556 cleanworkdir = False
3562 cleanworkdir = False
3557
3563
3558 if len(parents) > 1:
3564 if len(parents) > 1:
3559 t += _(' (merge)')
3565 t += _(' (merge)')
3560 elif branch != parents[0].branch():
3566 elif branch != parents[0].branch():
3561 t += _(' (new branch)')
3567 t += _(' (new branch)')
3562 elif (parents[0].extra().get('close') and
3568 elif (parents[0].extra().get('close') and
3563 pnode in repo.branchheads(branch, closed=True)):
3569 pnode in repo.branchheads(branch, closed=True)):
3564 t += _(' (head closed)')
3570 t += _(' (head closed)')
3565 elif not (st[0] or st[1] or st[2] or st[3] or st[4] or st[9]):
3571 elif not (st[0] or st[1] or st[2] or st[3] or st[4] or st[9]):
3566 t += _(' (clean)')
3572 t += _(' (clean)')
3567 cleanworkdir = True
3573 cleanworkdir = True
3568 elif pnode not in bheads:
3574 elif pnode not in bheads:
3569 t += _(' (new branch head)')
3575 t += _(' (new branch head)')
3570
3576
3571 if cleanworkdir:
3577 if cleanworkdir:
3572 ui.status(_('commit: %s\n') % t.strip())
3578 ui.status(_('commit: %s\n') % t.strip())
3573 else:
3579 else:
3574 ui.write(_('commit: %s\n') % t.strip())
3580 ui.write(_('commit: %s\n') % t.strip())
3575
3581
3576 # all ancestors of branch heads - all ancestors of parent = new csets
3582 # all ancestors of branch heads - all ancestors of parent = new csets
3577 new = [0] * len(repo)
3583 new = [0] * len(repo)
3578 cl = repo.changelog
3584 cl = repo.changelog
3579 for a in [cl.rev(n) for n in bheads]:
3585 for a in [cl.rev(n) for n in bheads]:
3580 new[a] = 1
3586 new[a] = 1
3581 for a in cl.ancestors(*[cl.rev(n) for n in bheads]):
3587 for a in cl.ancestors(*[cl.rev(n) for n in bheads]):
3582 new[a] = 1
3588 new[a] = 1
3583 for a in [p.rev() for p in parents]:
3589 for a in [p.rev() for p in parents]:
3584 if a >= 0:
3590 if a >= 0:
3585 new[a] = 0
3591 new[a] = 0
3586 for a in cl.ancestors(*[p.rev() for p in parents]):
3592 for a in cl.ancestors(*[p.rev() for p in parents]):
3587 new[a] = 0
3593 new[a] = 0
3588 new = sum(new)
3594 new = sum(new)
3589
3595
3590 if new == 0:
3596 if new == 0:
3591 ui.status(_('update: (current)\n'))
3597 ui.status(_('update: (current)\n'))
3592 elif pnode not in bheads:
3598 elif pnode not in bheads:
3593 ui.write(_('update: %d new changesets (update)\n') % new)
3599 ui.write(_('update: %d new changesets (update)\n') % new)
3594 else:
3600 else:
3595 ui.write(_('update: %d new changesets, %d branch heads (merge)\n') %
3601 ui.write(_('update: %d new changesets, %d branch heads (merge)\n') %
3596 (new, len(bheads)))
3602 (new, len(bheads)))
3597
3603
3598 if opts.get('remote'):
3604 if opts.get('remote'):
3599 t = []
3605 t = []
3600 source, branches = hg.parseurl(ui.expandpath('default'))
3606 source, branches = hg.parseurl(ui.expandpath('default'))
3601 other = hg.repository(hg.remoteui(repo, {}), source)
3607 other = hg.repository(hg.remoteui(repo, {}), source)
3602 revs, checkout = hg.addbranchrevs(repo, other, branches, opts.get('rev'))
3608 revs, checkout = hg.addbranchrevs(repo, other, branches, opts.get('rev'))
3603 ui.debug('comparing with %s\n' % url.hidepassword(source))
3609 ui.debug('comparing with %s\n' % url.hidepassword(source))
3604 repo.ui.pushbuffer()
3610 repo.ui.pushbuffer()
3605 common, incoming, rheads = discovery.findcommonincoming(repo, other)
3611 common, incoming, rheads = discovery.findcommonincoming(repo, other)
3606 repo.ui.popbuffer()
3612 repo.ui.popbuffer()
3607 if incoming:
3613 if incoming:
3608 t.append(_('1 or more incoming'))
3614 t.append(_('1 or more incoming'))
3609
3615
3610 dest, branches = hg.parseurl(ui.expandpath('default-push', 'default'))
3616 dest, branches = hg.parseurl(ui.expandpath('default-push', 'default'))
3611 revs, checkout = hg.addbranchrevs(repo, repo, branches, None)
3617 revs, checkout = hg.addbranchrevs(repo, repo, branches, None)
3612 other = hg.repository(hg.remoteui(repo, {}), dest)
3618 other = hg.repository(hg.remoteui(repo, {}), dest)
3613 ui.debug('comparing with %s\n' % url.hidepassword(dest))
3619 ui.debug('comparing with %s\n' % url.hidepassword(dest))
3614 repo.ui.pushbuffer()
3620 repo.ui.pushbuffer()
3615 o = discovery.findoutgoing(repo, other)
3621 o = discovery.findoutgoing(repo, other)
3616 repo.ui.popbuffer()
3622 repo.ui.popbuffer()
3617 o = repo.changelog.nodesbetween(o, None)[0]
3623 o = repo.changelog.nodesbetween(o, None)[0]
3618 if o:
3624 if o:
3619 t.append(_('%d outgoing') % len(o))
3625 t.append(_('%d outgoing') % len(o))
3620
3626
3621 if t:
3627 if t:
3622 ui.write(_('remote: %s\n') % (', '.join(t)))
3628 ui.write(_('remote: %s\n') % (', '.join(t)))
3623 else:
3629 else:
3624 ui.status(_('remote: (synced)\n'))
3630 ui.status(_('remote: (synced)\n'))
3625
3631
3626 def tag(ui, repo, name1, *names, **opts):
3632 def tag(ui, repo, name1, *names, **opts):
3627 """add one or more tags for the current or given revision
3633 """add one or more tags for the current or given revision
3628
3634
3629 Name a particular revision using <name>.
3635 Name a particular revision using <name>.
3630
3636
3631 Tags are used to name particular revisions of the repository and are
3637 Tags are used to name particular revisions of the repository and are
3632 very useful to compare different revisions, to go back to significant
3638 very useful to compare different revisions, to go back to significant
3633 earlier versions or to mark branch points as releases, etc.
3639 earlier versions or to mark branch points as releases, etc.
3634
3640
3635 If no revision is given, the parent of the working directory is
3641 If no revision is given, the parent of the working directory is
3636 used, or tip if no revision is checked out.
3642 used, or tip if no revision is checked out.
3637
3643
3638 To facilitate version control, distribution, and merging of tags,
3644 To facilitate version control, distribution, and merging of tags,
3639 they are stored as a file named ".hgtags" which is managed
3645 they are stored as a file named ".hgtags" which is managed
3640 similarly to other project files and can be hand-edited if
3646 similarly to other project files and can be hand-edited if
3641 necessary. The file '.hg/localtags' is used for local tags (not
3647 necessary. The file '.hg/localtags' is used for local tags (not
3642 shared among repositories).
3648 shared among repositories).
3643
3649
3644 See :hg:`help dates` for a list of formats valid for -d/--date.
3650 See :hg:`help dates` for a list of formats valid for -d/--date.
3645
3651
3646 Since tag names have priority over branch names during revision
3652 Since tag names have priority over branch names during revision
3647 lookup, using an existing branch name as a tag name is discouraged.
3653 lookup, using an existing branch name as a tag name is discouraged.
3648
3654
3649 Returns 0 on success.
3655 Returns 0 on success.
3650 """
3656 """
3651
3657
3652 rev_ = "."
3658 rev_ = "."
3653 names = [t.strip() for t in (name1,) + names]
3659 names = [t.strip() for t in (name1,) + names]
3654 if len(names) != len(set(names)):
3660 if len(names) != len(set(names)):
3655 raise util.Abort(_('tag names must be unique'))
3661 raise util.Abort(_('tag names must be unique'))
3656 for n in names:
3662 for n in names:
3657 if n in ['tip', '.', 'null']:
3663 if n in ['tip', '.', 'null']:
3658 raise util.Abort(_('the name \'%s\' is reserved') % n)
3664 raise util.Abort(_('the name \'%s\' is reserved') % n)
3659 if not n:
3665 if not n:
3660 raise util.Abort(_('tag names cannot consist entirely of whitespace'))
3666 raise util.Abort(_('tag names cannot consist entirely of whitespace'))
3661 if opts.get('rev') and opts.get('remove'):
3667 if opts.get('rev') and opts.get('remove'):
3662 raise util.Abort(_("--rev and --remove are incompatible"))
3668 raise util.Abort(_("--rev and --remove are incompatible"))
3663 if opts.get('rev'):
3669 if opts.get('rev'):
3664 rev_ = opts['rev']
3670 rev_ = opts['rev']
3665 message = opts.get('message')
3671 message = opts.get('message')
3666 if opts.get('remove'):
3672 if opts.get('remove'):
3667 expectedtype = opts.get('local') and 'local' or 'global'
3673 expectedtype = opts.get('local') and 'local' or 'global'
3668 for n in names:
3674 for n in names:
3669 if not repo.tagtype(n):
3675 if not repo.tagtype(n):
3670 raise util.Abort(_('tag \'%s\' does not exist') % n)
3676 raise util.Abort(_('tag \'%s\' does not exist') % n)
3671 if repo.tagtype(n) != expectedtype:
3677 if repo.tagtype(n) != expectedtype:
3672 if expectedtype == 'global':
3678 if expectedtype == 'global':
3673 raise util.Abort(_('tag \'%s\' is not a global tag') % n)
3679 raise util.Abort(_('tag \'%s\' is not a global tag') % n)
3674 else:
3680 else:
3675 raise util.Abort(_('tag \'%s\' is not a local tag') % n)
3681 raise util.Abort(_('tag \'%s\' is not a local tag') % n)
3676 rev_ = nullid
3682 rev_ = nullid
3677 if not message:
3683 if not message:
3678 # we don't translate commit messages
3684 # we don't translate commit messages
3679 message = 'Removed tag %s' % ', '.join(names)
3685 message = 'Removed tag %s' % ', '.join(names)
3680 elif not opts.get('force'):
3686 elif not opts.get('force'):
3681 for n in names:
3687 for n in names:
3682 if n in repo.tags():
3688 if n in repo.tags():
3683 raise util.Abort(_('tag \'%s\' already exists '
3689 raise util.Abort(_('tag \'%s\' already exists '
3684 '(use -f to force)') % n)
3690 '(use -f to force)') % n)
3685 if not rev_ and repo.dirstate.parents()[1] != nullid:
3691 if not rev_ and repo.dirstate.parents()[1] != nullid:
3686 raise util.Abort(_('uncommitted merge - please provide a '
3692 raise util.Abort(_('uncommitted merge - please provide a '
3687 'specific revision'))
3693 'specific revision'))
3688 r = repo[rev_].node()
3694 r = repo[rev_].node()
3689
3695
3690 if not message:
3696 if not message:
3691 # we don't translate commit messages
3697 # we don't translate commit messages
3692 message = ('Added tag %s for changeset %s' %
3698 message = ('Added tag %s for changeset %s' %
3693 (', '.join(names), short(r)))
3699 (', '.join(names), short(r)))
3694
3700
3695 date = opts.get('date')
3701 date = opts.get('date')
3696 if date:
3702 if date:
3697 date = util.parsedate(date)
3703 date = util.parsedate(date)
3698
3704
3699 if opts.get('edit'):
3705 if opts.get('edit'):
3700 message = ui.edit(message, ui.username())
3706 message = ui.edit(message, ui.username())
3701
3707
3702 repo.tag(names, r, message, opts.get('local'), opts.get('user'), date)
3708 repo.tag(names, r, message, opts.get('local'), opts.get('user'), date)
3703
3709
3704 def tags(ui, repo):
3710 def tags(ui, repo):
3705 """list repository tags
3711 """list repository tags
3706
3712
3707 This lists both regular and local tags. When the -v/--verbose
3713 This lists both regular and local tags. When the -v/--verbose
3708 switch is used, a third column "local" is printed for local tags.
3714 switch is used, a third column "local" is printed for local tags.
3709
3715
3710 Returns 0 on success.
3716 Returns 0 on success.
3711 """
3717 """
3712
3718
3713 hexfunc = ui.debugflag and hex or short
3719 hexfunc = ui.debugflag and hex or short
3714 tagtype = ""
3720 tagtype = ""
3715
3721
3716 for t, n in reversed(repo.tagslist()):
3722 for t, n in reversed(repo.tagslist()):
3717 if ui.quiet:
3723 if ui.quiet:
3718 ui.write("%s\n" % t)
3724 ui.write("%s\n" % t)
3719 continue
3725 continue
3720
3726
3721 try:
3727 try:
3722 hn = hexfunc(n)
3728 hn = hexfunc(n)
3723 r = "%5d:%s" % (repo.changelog.rev(n), hn)
3729 r = "%5d:%s" % (repo.changelog.rev(n), hn)
3724 except error.LookupError:
3730 except error.LookupError:
3725 r = " ?:%s" % hn
3731 r = " ?:%s" % hn
3726 else:
3732 else:
3727 spaces = " " * (30 - encoding.colwidth(t))
3733 spaces = " " * (30 - encoding.colwidth(t))
3728 if ui.verbose:
3734 if ui.verbose:
3729 if repo.tagtype(t) == 'local':
3735 if repo.tagtype(t) == 'local':
3730 tagtype = " local"
3736 tagtype = " local"
3731 else:
3737 else:
3732 tagtype = ""
3738 tagtype = ""
3733 ui.write("%s%s %s%s\n" % (t, spaces, r, tagtype))
3739 ui.write("%s%s %s%s\n" % (t, spaces, r, tagtype))
3734
3740
3735 def tip(ui, repo, **opts):
3741 def tip(ui, repo, **opts):
3736 """show the tip revision
3742 """show the tip revision
3737
3743
3738 The tip revision (usually just called the tip) is the changeset
3744 The tip revision (usually just called the tip) is the changeset
3739 most recently added to the repository (and therefore the most
3745 most recently added to the repository (and therefore the most
3740 recently changed head).
3746 recently changed head).
3741
3747
3742 If you have just made a commit, that commit will be the tip. If
3748 If you have just made a commit, that commit will be the tip. If
3743 you have just pulled changes from another repository, the tip of
3749 you have just pulled changes from another repository, the tip of
3744 that repository becomes the current tip. The "tip" tag is special
3750 that repository becomes the current tip. The "tip" tag is special
3745 and cannot be renamed or assigned to a different changeset.
3751 and cannot be renamed or assigned to a different changeset.
3746
3752
3747 Returns 0 on success.
3753 Returns 0 on success.
3748 """
3754 """
3749 displayer = cmdutil.show_changeset(ui, repo, opts)
3755 displayer = cmdutil.show_changeset(ui, repo, opts)
3750 displayer.show(repo[len(repo) - 1])
3756 displayer.show(repo[len(repo) - 1])
3751 displayer.close()
3757 displayer.close()
3752
3758
3753 def unbundle(ui, repo, fname1, *fnames, **opts):
3759 def unbundle(ui, repo, fname1, *fnames, **opts):
3754 """apply one or more changegroup files
3760 """apply one or more changegroup files
3755
3761
3756 Apply one or more compressed changegroup files generated by the
3762 Apply one or more compressed changegroup files generated by the
3757 bundle command.
3763 bundle command.
3758
3764
3759 Returns 0 on success, 1 if an update has unresolved files.
3765 Returns 0 on success, 1 if an update has unresolved files.
3760 """
3766 """
3761 fnames = (fname1,) + fnames
3767 fnames = (fname1,) + fnames
3762
3768
3763 lock = repo.lock()
3769 lock = repo.lock()
3764 try:
3770 try:
3765 for fname in fnames:
3771 for fname in fnames:
3766 f = url.open(ui, fname)
3772 f = url.open(ui, fname)
3767 gen = changegroup.readbundle(f, fname)
3773 gen = changegroup.readbundle(f, fname)
3768 modheads = repo.addchangegroup(gen, 'unbundle', 'bundle:' + fname,
3774 modheads = repo.addchangegroup(gen, 'unbundle', 'bundle:' + fname,
3769 lock=lock)
3775 lock=lock)
3770 finally:
3776 finally:
3771 lock.release()
3777 lock.release()
3772
3778
3773 return postincoming(ui, repo, modheads, opts.get('update'), None)
3779 return postincoming(ui, repo, modheads, opts.get('update'), None)
3774
3780
3775 def update(ui, repo, node=None, rev=None, clean=False, date=None, check=False):
3781 def update(ui, repo, node=None, rev=None, clean=False, date=None, check=False):
3776 """update working directory (or switch revisions)
3782 """update working directory (or switch revisions)
3777
3783
3778 Update the repository's working directory to the specified
3784 Update the repository's working directory to the specified
3779 changeset.
3785 changeset.
3780
3786
3781 If no changeset is specified, attempt to update to the tip of the
3787 If no changeset is specified, attempt to update to the tip of the
3782 current branch. If this changeset is a descendant of the working
3788 current branch. If this changeset is a descendant of the working
3783 directory's parent, update to it, otherwise abort.
3789 directory's parent, update to it, otherwise abort.
3784
3790
3785 The following rules apply when the working directory contains
3791 The following rules apply when the working directory contains
3786 uncommitted changes:
3792 uncommitted changes:
3787
3793
3788 1. If neither -c/--check nor -C/--clean is specified, and if
3794 1. If neither -c/--check nor -C/--clean is specified, and if
3789 the requested changeset is an ancestor or descendant of
3795 the requested changeset is an ancestor or descendant of
3790 the working directory's parent, the uncommitted changes
3796 the working directory's parent, the uncommitted changes
3791 are merged into the requested changeset and the merged
3797 are merged into the requested changeset and the merged
3792 result is left uncommitted. If the requested changeset is
3798 result is left uncommitted. If the requested changeset is
3793 not an ancestor or descendant (that is, it is on another
3799 not an ancestor or descendant (that is, it is on another
3794 branch), the update is aborted and the uncommitted changes
3800 branch), the update is aborted and the uncommitted changes
3795 are preserved.
3801 are preserved.
3796
3802
3797 2. With the -c/--check option, the update is aborted and the
3803 2. With the -c/--check option, the update is aborted and the
3798 uncommitted changes are preserved.
3804 uncommitted changes are preserved.
3799
3805
3800 3. With the -C/--clean option, uncommitted changes are discarded and
3806 3. With the -C/--clean option, uncommitted changes are discarded and
3801 the working directory is updated to the requested changeset.
3807 the working directory is updated to the requested changeset.
3802
3808
3803 Use null as the changeset to remove the working directory (like
3809 Use null as the changeset to remove the working directory (like
3804 :hg:`clone -U`).
3810 :hg:`clone -U`).
3805
3811
3806 If you want to update just one file to an older changeset, use :hg:`revert`.
3812 If you want to update just one file to an older changeset, use :hg:`revert`.
3807
3813
3808 See :hg:`help dates` for a list of formats valid for -d/--date.
3814 See :hg:`help dates` for a list of formats valid for -d/--date.
3809
3815
3810 Returns 0 on success, 1 if there are unresolved files.
3816 Returns 0 on success, 1 if there are unresolved files.
3811 """
3817 """
3812 if rev and node:
3818 if rev and node:
3813 raise util.Abort(_("please specify just one revision"))
3819 raise util.Abort(_("please specify just one revision"))
3814
3820
3815 if not rev:
3821 if not rev:
3816 rev = node
3822 rev = node
3817
3823
3818 if check and clean:
3824 if check and clean:
3819 raise util.Abort(_("cannot specify both -c/--check and -C/--clean"))
3825 raise util.Abort(_("cannot specify both -c/--check and -C/--clean"))
3820
3826
3821 if check:
3827 if check:
3822 # we could use dirty() but we can ignore merge and branch trivia
3828 # we could use dirty() but we can ignore merge and branch trivia
3823 c = repo[None]
3829 c = repo[None]
3824 if c.modified() or c.added() or c.removed():
3830 if c.modified() or c.added() or c.removed():
3825 raise util.Abort(_("uncommitted local changes"))
3831 raise util.Abort(_("uncommitted local changes"))
3826
3832
3827 if date:
3833 if date:
3828 if rev:
3834 if rev:
3829 raise util.Abort(_("you can't specify a revision and a date"))
3835 raise util.Abort(_("you can't specify a revision and a date"))
3830 rev = cmdutil.finddate(ui, repo, date)
3836 rev = cmdutil.finddate(ui, repo, date)
3831
3837
3832 if clean or check:
3838 if clean or check:
3833 return hg.clean(repo, rev)
3839 return hg.clean(repo, rev)
3834 else:
3840 else:
3835 return hg.update(repo, rev)
3841 return hg.update(repo, rev)
3836
3842
3837 def verify(ui, repo):
3843 def verify(ui, repo):
3838 """verify the integrity of the repository
3844 """verify the integrity of the repository
3839
3845
3840 Verify the integrity of the current repository.
3846 Verify the integrity of the current repository.
3841
3847
3842 This will perform an extensive check of the repository's
3848 This will perform an extensive check of the repository's
3843 integrity, validating the hashes and checksums of each entry in
3849 integrity, validating the hashes and checksums of each entry in
3844 the changelog, manifest, and tracked files, as well as the
3850 the changelog, manifest, and tracked files, as well as the
3845 integrity of their crosslinks and indices.
3851 integrity of their crosslinks and indices.
3846
3852
3847 Returns 0 on success, 1 if errors are encountered.
3853 Returns 0 on success, 1 if errors are encountered.
3848 """
3854 """
3849 return hg.verify(repo)
3855 return hg.verify(repo)
3850
3856
3851 def version_(ui):
3857 def version_(ui):
3852 """output version and copyright information"""
3858 """output version and copyright information"""
3853 ui.write(_("Mercurial Distributed SCM (version %s)\n")
3859 ui.write(_("Mercurial Distributed SCM (version %s)\n")
3854 % util.version())
3860 % util.version())
3855 ui.status(_(
3861 ui.status(_(
3856 "\nCopyright (C) 2005-2010 Matt Mackall <mpm@selenic.com> and others\n"
3862 "\nCopyright (C) 2005-2010 Matt Mackall <mpm@selenic.com> and others\n"
3857 "This is free software; see the source for copying conditions. "
3863 "This is free software; see the source for copying conditions. "
3858 "There is NO\nwarranty; "
3864 "There is NO\nwarranty; "
3859 "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
3865 "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
3860 ))
3866 ))
3861
3867
3862 # Command options and aliases are listed here, alphabetically
3868 # Command options and aliases are listed here, alphabetically
3863
3869
3864 globalopts = [
3870 globalopts = [
3865 ('R', 'repository', '',
3871 ('R', 'repository', '',
3866 _('repository root directory or name of overlay bundle file'),
3872 _('repository root directory or name of overlay bundle file'),
3867 _('REPO')),
3873 _('REPO')),
3868 ('', 'cwd', '',
3874 ('', 'cwd', '',
3869 _('change working directory'), _('DIR')),
3875 _('change working directory'), _('DIR')),
3870 ('y', 'noninteractive', None,
3876 ('y', 'noninteractive', None,
3871 _('do not prompt, assume \'yes\' for any required answers')),
3877 _('do not prompt, assume \'yes\' for any required answers')),
3872 ('q', 'quiet', None, _('suppress output')),
3878 ('q', 'quiet', None, _('suppress output')),
3873 ('v', 'verbose', None, _('enable additional output')),
3879 ('v', 'verbose', None, _('enable additional output')),
3874 ('', 'config', [],
3880 ('', 'config', [],
3875 _('set/override config option (use \'section.name=value\')'),
3881 _('set/override config option (use \'section.name=value\')'),
3876 _('CONFIG')),
3882 _('CONFIG')),
3877 ('', 'debug', None, _('enable debugging output')),
3883 ('', 'debug', None, _('enable debugging output')),
3878 ('', 'debugger', None, _('start debugger')),
3884 ('', 'debugger', None, _('start debugger')),
3879 ('', 'encoding', encoding.encoding, _('set the charset encoding'),
3885 ('', 'encoding', encoding.encoding, _('set the charset encoding'),
3880 _('ENCODE')),
3886 _('ENCODE')),
3881 ('', 'encodingmode', encoding.encodingmode,
3887 ('', 'encodingmode', encoding.encodingmode,
3882 _('set the charset encoding mode'), _('MODE')),
3888 _('set the charset encoding mode'), _('MODE')),
3883 ('', 'traceback', None, _('always print a traceback on exception')),
3889 ('', 'traceback', None, _('always print a traceback on exception')),
3884 ('', 'time', None, _('time how long the command takes')),
3890 ('', 'time', None, _('time how long the command takes')),
3885 ('', 'profile', None, _('print command execution profile')),
3891 ('', 'profile', None, _('print command execution profile')),
3886 ('', 'version', None, _('output version information and exit')),
3892 ('', 'version', None, _('output version information and exit')),
3887 ('h', 'help', None, _('display help and exit')),
3893 ('h', 'help', None, _('display help and exit')),
3888 ]
3894 ]
3889
3895
3890 dryrunopts = [('n', 'dry-run', None,
3896 dryrunopts = [('n', 'dry-run', None,
3891 _('do not perform actions, just print output'))]
3897 _('do not perform actions, just print output'))]
3892
3898
3893 remoteopts = [
3899 remoteopts = [
3894 ('e', 'ssh', '',
3900 ('e', 'ssh', '',
3895 _('specify ssh command to use'), _('CMD')),
3901 _('specify ssh command to use'), _('CMD')),
3896 ('', 'remotecmd', '',
3902 ('', 'remotecmd', '',
3897 _('specify hg command to run on the remote side'), _('CMD')),
3903 _('specify hg command to run on the remote side'), _('CMD')),
3898 ]
3904 ]
3899
3905
3900 walkopts = [
3906 walkopts = [
3901 ('I', 'include', [],
3907 ('I', 'include', [],
3902 _('include names matching the given patterns'), _('PATTERN')),
3908 _('include names matching the given patterns'), _('PATTERN')),
3903 ('X', 'exclude', [],
3909 ('X', 'exclude', [],
3904 _('exclude names matching the given patterns'), _('PATTERN')),
3910 _('exclude names matching the given patterns'), _('PATTERN')),
3905 ]
3911 ]
3906
3912
3907 commitopts = [
3913 commitopts = [
3908 ('m', 'message', '',
3914 ('m', 'message', '',
3909 _('use text as commit message'), _('TEXT')),
3915 _('use text as commit message'), _('TEXT')),
3910 ('l', 'logfile', '',
3916 ('l', 'logfile', '',
3911 _('read commit message from file'), _('FILE')),
3917 _('read commit message from file'), _('FILE')),
3912 ]
3918 ]
3913
3919
3914 commitopts2 = [
3920 commitopts2 = [
3915 ('d', 'date', '',
3921 ('d', 'date', '',
3916 _('record datecode as commit date'), _('DATE')),
3922 _('record datecode as commit date'), _('DATE')),
3917 ('u', 'user', '',
3923 ('u', 'user', '',
3918 _('record the specified user as committer'), _('USER')),
3924 _('record the specified user as committer'), _('USER')),
3919 ]
3925 ]
3920
3926
3921 templateopts = [
3927 templateopts = [
3922 ('', 'style', '',
3928 ('', 'style', '',
3923 _('display using template map file'), _('STYLE')),
3929 _('display using template map file'), _('STYLE')),
3924 ('', 'template', '',
3930 ('', 'template', '',
3925 _('display with template'), _('TEMPLATE')),
3931 _('display with template'), _('TEMPLATE')),
3926 ]
3932 ]
3927
3933
3928 logopts = [
3934 logopts = [
3929 ('p', 'patch', None, _('show patch')),
3935 ('p', 'patch', None, _('show patch')),
3930 ('g', 'git', None, _('use git extended diff format')),
3936 ('g', 'git', None, _('use git extended diff format')),
3931 ('l', 'limit', '',
3937 ('l', 'limit', '',
3932 _('limit number of changes displayed'), _('NUM')),
3938 _('limit number of changes displayed'), _('NUM')),
3933 ('M', 'no-merges', None, _('do not show merges')),
3939 ('M', 'no-merges', None, _('do not show merges')),
3934 ('', 'stat', None, _('output diffstat-style summary of changes')),
3940 ('', 'stat', None, _('output diffstat-style summary of changes')),
3935 ] + templateopts
3941 ] + templateopts
3936
3942
3937 diffopts = [
3943 diffopts = [
3938 ('a', 'text', None, _('treat all files as text')),
3944 ('a', 'text', None, _('treat all files as text')),
3939 ('g', 'git', None, _('use git extended diff format')),
3945 ('g', 'git', None, _('use git extended diff format')),
3940 ('', 'nodates', None, _('omit dates from diff headers'))
3946 ('', 'nodates', None, _('omit dates from diff headers'))
3941 ]
3947 ]
3942
3948
3943 diffopts2 = [
3949 diffopts2 = [
3944 ('p', 'show-function', None, _('show which function each change is in')),
3950 ('p', 'show-function', None, _('show which function each change is in')),
3945 ('', 'reverse', None, _('produce a diff that undoes the changes')),
3951 ('', 'reverse', None, _('produce a diff that undoes the changes')),
3946 ('w', 'ignore-all-space', None,
3952 ('w', 'ignore-all-space', None,
3947 _('ignore white space when comparing lines')),
3953 _('ignore white space when comparing lines')),
3948 ('b', 'ignore-space-change', None,
3954 ('b', 'ignore-space-change', None,
3949 _('ignore changes in the amount of white space')),
3955 _('ignore changes in the amount of white space')),
3950 ('B', 'ignore-blank-lines', None,
3956 ('B', 'ignore-blank-lines', None,
3951 _('ignore changes whose lines are all blank')),
3957 _('ignore changes whose lines are all blank')),
3952 ('U', 'unified', '',
3958 ('U', 'unified', '',
3953 _('number of lines of context to show'), _('NUM')),
3959 _('number of lines of context to show'), _('NUM')),
3954 ('', 'stat', None, _('output diffstat-style summary of changes')),
3960 ('', 'stat', None, _('output diffstat-style summary of changes')),
3955 ]
3961 ]
3956
3962
3957 similarityopts = [
3963 similarityopts = [
3958 ('s', 'similarity', '',
3964 ('s', 'similarity', '',
3959 _('guess renamed files by similarity (0<=s<=100)'), _('SIMILARITY'))
3965 _('guess renamed files by similarity (0<=s<=100)'), _('SIMILARITY'))
3960 ]
3966 ]
3961
3967
3962 table = {
3968 table = {
3963 "^add": (add, walkopts + dryrunopts, _('[OPTION]... [FILE]...')),
3969 "^add": (add, walkopts + dryrunopts, _('[OPTION]... [FILE]...')),
3964 "addremove":
3970 "addremove":
3965 (addremove, similarityopts + walkopts + dryrunopts,
3971 (addremove, similarityopts + walkopts + dryrunopts,
3966 _('[OPTION]... [FILE]...')),
3972 _('[OPTION]... [FILE]...')),
3967 "^annotate|blame":
3973 "^annotate|blame":
3968 (annotate,
3974 (annotate,
3969 [('r', 'rev', '',
3975 [('r', 'rev', '',
3970 _('annotate the specified revision'), _('REV')),
3976 _('annotate the specified revision'), _('REV')),
3971 ('', 'follow', None,
3977 ('', 'follow', None,
3972 _('follow copies/renames and list the filename (DEPRECATED)')),
3978 _('follow copies/renames and list the filename (DEPRECATED)')),
3973 ('', 'no-follow', None, _("don't follow copies and renames")),
3979 ('', 'no-follow', None, _("don't follow copies and renames")),
3974 ('a', 'text', None, _('treat all files as text')),
3980 ('a', 'text', None, _('treat all files as text')),
3975 ('u', 'user', None, _('list the author (long with -v)')),
3981 ('u', 'user', None, _('list the author (long with -v)')),
3976 ('f', 'file', None, _('list the filename')),
3982 ('f', 'file', None, _('list the filename')),
3977 ('d', 'date', None, _('list the date (short with -q)')),
3983 ('d', 'date', None, _('list the date (short with -q)')),
3978 ('n', 'number', None, _('list the revision number (default)')),
3984 ('n', 'number', None, _('list the revision number (default)')),
3979 ('c', 'changeset', None, _('list the changeset')),
3985 ('c', 'changeset', None, _('list the changeset')),
3980 ('l', 'line-number', None,
3986 ('l', 'line-number', None,
3981 _('show line number at the first appearance'))
3987 _('show line number at the first appearance'))
3982 ] + walkopts,
3988 ] + walkopts,
3983 _('[-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE...')),
3989 _('[-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE...')),
3984 "archive":
3990 "archive":
3985 (archive,
3991 (archive,
3986 [('', 'no-decode', None, _('do not pass files through decoders')),
3992 [('', 'no-decode', None, _('do not pass files through decoders')),
3987 ('p', 'prefix', '',
3993 ('p', 'prefix', '',
3988 _('directory prefix for files in archive'), _('PREFIX')),
3994 _('directory prefix for files in archive'), _('PREFIX')),
3989 ('r', 'rev', '',
3995 ('r', 'rev', '',
3990 _('revision to distribute'), _('REV')),
3996 _('revision to distribute'), _('REV')),
3991 ('t', 'type', '',
3997 ('t', 'type', '',
3992 _('type of distribution to create'), _('TYPE')),
3998 _('type of distribution to create'), _('TYPE')),
3993 ] + walkopts,
3999 ] + walkopts,
3994 _('[OPTION]... DEST')),
4000 _('[OPTION]... DEST')),
3995 "backout":
4001 "backout":
3996 (backout,
4002 (backout,
3997 [('', 'merge', None,
4003 [('', 'merge', None,
3998 _('merge with old dirstate parent after backout')),
4004 _('merge with old dirstate parent after backout')),
3999 ('', 'parent', '',
4005 ('', 'parent', '',
4000 _('parent to choose when backing out merge'), _('REV')),
4006 _('parent to choose when backing out merge'), _('REV')),
4001 ('r', 'rev', '',
4007 ('r', 'rev', '',
4002 _('revision to backout'), _('REV')),
4008 _('revision to backout'), _('REV')),
4003 ] + walkopts + commitopts + commitopts2,
4009 ] + walkopts + commitopts + commitopts2,
4004 _('[OPTION]... [-r] REV')),
4010 _('[OPTION]... [-r] REV')),
4005 "bisect":
4011 "bisect":
4006 (bisect,
4012 (bisect,
4007 [('r', 'reset', False, _('reset bisect state')),
4013 [('r', 'reset', False, _('reset bisect state')),
4008 ('g', 'good', False, _('mark changeset good')),
4014 ('g', 'good', False, _('mark changeset good')),
4009 ('b', 'bad', False, _('mark changeset bad')),
4015 ('b', 'bad', False, _('mark changeset bad')),
4010 ('s', 'skip', False, _('skip testing changeset')),
4016 ('s', 'skip', False, _('skip testing changeset')),
4011 ('c', 'command', '',
4017 ('c', 'command', '',
4012 _('use command to check changeset state'), _('CMD')),
4018 _('use command to check changeset state'), _('CMD')),
4013 ('U', 'noupdate', False, _('do not update to target'))],
4019 ('U', 'noupdate', False, _('do not update to target'))],
4014 _("[-gbsr] [-U] [-c CMD] [REV]")),
4020 _("[-gbsr] [-U] [-c CMD] [REV]")),
4015 "branch":
4021 "branch":
4016 (branch,
4022 (branch,
4017 [('f', 'force', None,
4023 [('f', 'force', None,
4018 _('set branch name even if it shadows an existing branch')),
4024 _('set branch name even if it shadows an existing branch')),
4019 ('C', 'clean', None, _('reset branch name to parent branch name'))],
4025 ('C', 'clean', None, _('reset branch name to parent branch name'))],
4020 _('[-fC] [NAME]')),
4026 _('[-fC] [NAME]')),
4021 "branches":
4027 "branches":
4022 (branches,
4028 (branches,
4023 [('a', 'active', False,
4029 [('a', 'active', False,
4024 _('show only branches that have unmerged heads')),
4030 _('show only branches that have unmerged heads')),
4025 ('c', 'closed', False,
4031 ('c', 'closed', False,
4026 _('show normal and closed branches'))],
4032 _('show normal and closed branches'))],
4027 _('[-ac]')),
4033 _('[-ac]')),
4028 "bundle":
4034 "bundle":
4029 (bundle,
4035 (bundle,
4030 [('f', 'force', None,
4036 [('f', 'force', None,
4031 _('run even when the destination is unrelated')),
4037 _('run even when the destination is unrelated')),
4032 ('r', 'rev', [],
4038 ('r', 'rev', [],
4033 _('a changeset intended to be added to the destination'),
4039 _('a changeset intended to be added to the destination'),
4034 _('REV')),
4040 _('REV')),
4035 ('b', 'branch', [],
4041 ('b', 'branch', [],
4036 _('a specific branch you would like to bundle'),
4042 _('a specific branch you would like to bundle'),
4037 _('BRANCH')),
4043 _('BRANCH')),
4038 ('', 'base', [],
4044 ('', 'base', [],
4039 _('a base changeset assumed to be available at the destination'),
4045 _('a base changeset assumed to be available at the destination'),
4040 _('REV')),
4046 _('REV')),
4041 ('a', 'all', None, _('bundle all changesets in the repository')),
4047 ('a', 'all', None, _('bundle all changesets in the repository')),
4042 ('t', 'type', 'bzip2',
4048 ('t', 'type', 'bzip2',
4043 _('bundle compression type to use'), _('TYPE')),
4049 _('bundle compression type to use'), _('TYPE')),
4044 ] + remoteopts,
4050 ] + remoteopts,
4045 _('[-f] [-t TYPE] [-a] [-r REV]... [--base REV]... FILE [DEST]')),
4051 _('[-f] [-t TYPE] [-a] [-r REV]... [--base REV]... FILE [DEST]')),
4046 "cat":
4052 "cat":
4047 (cat,
4053 (cat,
4048 [('o', 'output', '',
4054 [('o', 'output', '',
4049 _('print output to file with formatted name'), _('FORMAT')),
4055 _('print output to file with formatted name'), _('FORMAT')),
4050 ('r', 'rev', '',
4056 ('r', 'rev', '',
4051 _('print the given revision'), _('REV')),
4057 _('print the given revision'), _('REV')),
4052 ('', 'decode', None, _('apply any matching decode filter')),
4058 ('', 'decode', None, _('apply any matching decode filter')),
4053 ] + walkopts,
4059 ] + walkopts,
4054 _('[OPTION]... FILE...')),
4060 _('[OPTION]... FILE...')),
4055 "^clone":
4061 "^clone":
4056 (clone,
4062 (clone,
4057 [('U', 'noupdate', None,
4063 [('U', 'noupdate', None,
4058 _('the clone will include an empty working copy (only a repository)')),
4064 _('the clone will include an empty working copy (only a repository)')),
4059 ('u', 'updaterev', '',
4065 ('u', 'updaterev', '',
4060 _('revision, tag or branch to check out'), _('REV')),
4066 _('revision, tag or branch to check out'), _('REV')),
4061 ('r', 'rev', [],
4067 ('r', 'rev', [],
4062 _('include the specified changeset'), _('REV')),
4068 _('include the specified changeset'), _('REV')),
4063 ('b', 'branch', [],
4069 ('b', 'branch', [],
4064 _('clone only the specified branch'), _('BRANCH')),
4070 _('clone only the specified branch'), _('BRANCH')),
4065 ('', 'pull', None, _('use pull protocol to copy metadata')),
4071 ('', 'pull', None, _('use pull protocol to copy metadata')),
4066 ('', 'uncompressed', None,
4072 ('', 'uncompressed', None,
4067 _('use uncompressed transfer (fast over LAN)')),
4073 _('use uncompressed transfer (fast over LAN)')),
4068 ] + remoteopts,
4074 ] + remoteopts,
4069 _('[OPTION]... SOURCE [DEST]')),
4075 _('[OPTION]... SOURCE [DEST]')),
4070 "^commit|ci":
4076 "^commit|ci":
4071 (commit,
4077 (commit,
4072 [('A', 'addremove', None,
4078 [('A', 'addremove', None,
4073 _('mark new/missing files as added/removed before committing')),
4079 _('mark new/missing files as added/removed before committing')),
4074 ('', 'close-branch', None,
4080 ('', 'close-branch', None,
4075 _('mark a branch as closed, hiding it from the branch list')),
4081 _('mark a branch as closed, hiding it from the branch list')),
4076 ] + walkopts + commitopts + commitopts2,
4082 ] + walkopts + commitopts + commitopts2,
4077 _('[OPTION]... [FILE]...')),
4083 _('[OPTION]... [FILE]...')),
4078 "copy|cp":
4084 "copy|cp":
4079 (copy,
4085 (copy,
4080 [('A', 'after', None, _('record a copy that has already occurred')),
4086 [('A', 'after', None, _('record a copy that has already occurred')),
4081 ('f', 'force', None,
4087 ('f', 'force', None,
4082 _('forcibly copy over an existing managed file')),
4088 _('forcibly copy over an existing managed file')),
4083 ] + walkopts + dryrunopts,
4089 ] + walkopts + dryrunopts,
4084 _('[OPTION]... [SOURCE]... DEST')),
4090 _('[OPTION]... [SOURCE]... DEST')),
4085 "debugancestor": (debugancestor, [], _('[INDEX] REV1 REV2')),
4091 "debugancestor": (debugancestor, [], _('[INDEX] REV1 REV2')),
4086 "debugbuilddag":
4092 "debugbuilddag":
4087 (debugbuilddag,
4093 (debugbuilddag,
4088 [('m', 'mergeable-file', None, _('add single file mergeable changes')),
4094 [('m', 'mergeable-file', None, _('add single file mergeable changes')),
4089 ('a', 'appended-file', None, _('add single file all revs append to')),
4095 ('a', 'appended-file', None, _('add single file all revs append to')),
4090 ('o', 'overwritten-file', None, _('add single file all revs overwrite')),
4096 ('o', 'overwritten-file', None, _('add single file all revs overwrite')),
4091 ('n', 'new-file', None, _('add new file at each rev')),
4097 ('n', 'new-file', None, _('add new file at each rev')),
4092 ],
4098 ],
4093 _('[OPTION]... TEXT')),
4099 _('[OPTION]... TEXT')),
4094 "debugcheckstate": (debugcheckstate, [], ''),
4100 "debugcheckstate": (debugcheckstate, [], ''),
4095 "debugcommands": (debugcommands, [], _('[COMMAND]')),
4101 "debugcommands": (debugcommands, [], _('[COMMAND]')),
4096 "debugcomplete":
4102 "debugcomplete":
4097 (debugcomplete,
4103 (debugcomplete,
4098 [('o', 'options', None, _('show the command options'))],
4104 [('o', 'options', None, _('show the command options'))],
4099 _('[-o] CMD')),
4105 _('[-o] CMD')),
4100 "debugdag":
4106 "debugdag":
4101 (debugdag,
4107 (debugdag,
4102 [('t', 'tags', None, _('use tags as labels')),
4108 [('t', 'tags', None, _('use tags as labels')),
4103 ('b', 'branches', None, _('annotate with branch names')),
4109 ('b', 'branches', None, _('annotate with branch names')),
4104 ('', 'dots', None, _('use dots for runs')),
4110 ('', 'dots', None, _('use dots for runs')),
4105 ('s', 'spaces', None, _('separate elements by spaces')),
4111 ('s', 'spaces', None, _('separate elements by spaces')),
4106 ],
4112 ],
4107 _('[OPTION]... [FILE [REV]...]')),
4113 _('[OPTION]... [FILE [REV]...]')),
4108 "debugdate":
4114 "debugdate":
4109 (debugdate,
4115 (debugdate,
4110 [('e', 'extended', None, _('try extended date formats'))],
4116 [('e', 'extended', None, _('try extended date formats'))],
4111 _('[-e] DATE [RANGE]')),
4117 _('[-e] DATE [RANGE]')),
4112 "debugdata": (debugdata, [], _('FILE REV')),
4118 "debugdata": (debugdata, [], _('FILE REV')),
4113 "debugfsinfo": (debugfsinfo, [], _('[PATH]')),
4119 "debugfsinfo": (debugfsinfo, [], _('[PATH]')),
4114 "debugindex": (debugindex, [], _('FILE')),
4120 "debugindex": (debugindex, [], _('FILE')),
4115 "debugindexdot": (debugindexdot, [], _('FILE')),
4121 "debugindexdot": (debugindexdot, [], _('FILE')),
4116 "debuginstall": (debuginstall, [], ''),
4122 "debuginstall": (debuginstall, [], ''),
4117 "debugpushkey": (debugpushkey, [], _('REPO NAMESPACE [KEY OLD NEW]')),
4123 "debugpushkey": (debugpushkey, [], _('REPO NAMESPACE [KEY OLD NEW]')),
4118 "debugrebuildstate":
4124 "debugrebuildstate":
4119 (debugrebuildstate,
4125 (debugrebuildstate,
4120 [('r', 'rev', '',
4126 [('r', 'rev', '',
4121 _('revision to rebuild to'), _('REV'))],
4127 _('revision to rebuild to'), _('REV'))],
4122 _('[-r REV] [REV]')),
4128 _('[-r REV] [REV]')),
4123 "debugrename":
4129 "debugrename":
4124 (debugrename,
4130 (debugrename,
4125 [('r', 'rev', '',
4131 [('r', 'rev', '',
4126 _('revision to debug'), _('REV'))],
4132 _('revision to debug'), _('REV'))],
4127 _('[-r REV] FILE')),
4133 _('[-r REV] FILE')),
4128 "debugrevspec":
4134 "debugrevspec":
4129 (debugrevspec, [], ('REVSPEC')),
4135 (debugrevspec, [], ('REVSPEC')),
4130 "debugsetparents":
4136 "debugsetparents":
4131 (debugsetparents, [], _('REV1 [REV2]')),
4137 (debugsetparents, [], _('REV1 [REV2]')),
4132 "debugstate":
4138 "debugstate":
4133 (debugstate,
4139 (debugstate,
4134 [('', 'nodates', None, _('do not display the saved mtime'))],
4140 [('', 'nodates', None, _('do not display the saved mtime'))],
4135 _('[OPTION]...')),
4141 _('[OPTION]...')),
4136 "debugsub":
4142 "debugsub":
4137 (debugsub,
4143 (debugsub,
4138 [('r', 'rev', '',
4144 [('r', 'rev', '',
4139 _('revision to check'), _('REV'))],
4145 _('revision to check'), _('REV'))],
4140 _('[-r REV] [REV]')),
4146 _('[-r REV] [REV]')),
4141 "debugwalk": (debugwalk, walkopts, _('[OPTION]... [FILE]...')),
4147 "debugwalk": (debugwalk, walkopts, _('[OPTION]... [FILE]...')),
4142 "^diff":
4148 "^diff":
4143 (diff,
4149 (diff,
4144 [('r', 'rev', [],
4150 [('r', 'rev', [],
4145 _('revision'), _('REV')),
4151 _('revision'), _('REV')),
4146 ('c', 'change', '',
4152 ('c', 'change', '',
4147 _('change made by revision'), _('REV'))
4153 _('change made by revision'), _('REV'))
4148 ] + diffopts + diffopts2 + walkopts,
4154 ] + diffopts + diffopts2 + walkopts,
4149 _('[OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...')),
4155 _('[OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...')),
4150 "^export":
4156 "^export":
4151 (export,
4157 (export,
4152 [('o', 'output', '',
4158 [('o', 'output', '',
4153 _('print output to file with formatted name'), _('FORMAT')),
4159 _('print output to file with formatted name'), _('FORMAT')),
4154 ('', 'switch-parent', None, _('diff against the second parent')),
4160 ('', 'switch-parent', None, _('diff against the second parent')),
4155 ('r', 'rev', [],
4161 ('r', 'rev', [],
4156 _('revisions to export'), _('REV')),
4162 _('revisions to export'), _('REV')),
4157 ] + diffopts,
4163 ] + diffopts,
4158 _('[OPTION]... [-o OUTFILESPEC] REV...')),
4164 _('[OPTION]... [-o OUTFILESPEC] REV...')),
4159 "^forget":
4165 "^forget":
4160 (forget,
4166 (forget,
4161 [] + walkopts,
4167 [] + walkopts,
4162 _('[OPTION]... FILE...')),
4168 _('[OPTION]... FILE...')),
4163 "grep":
4169 "grep":
4164 (grep,
4170 (grep,
4165 [('0', 'print0', None, _('end fields with NUL')),
4171 [('0', 'print0', None, _('end fields with NUL')),
4166 ('', 'all', None, _('print all revisions that match')),
4172 ('', 'all', None, _('print all revisions that match')),
4167 ('f', 'follow', None,
4173 ('f', 'follow', None,
4168 _('follow changeset history,'
4174 _('follow changeset history,'
4169 ' or file history across copies and renames')),
4175 ' or file history across copies and renames')),
4170 ('i', 'ignore-case', None, _('ignore case when matching')),
4176 ('i', 'ignore-case', None, _('ignore case when matching')),
4171 ('l', 'files-with-matches', None,
4177 ('l', 'files-with-matches', None,
4172 _('print only filenames and revisions that match')),
4178 _('print only filenames and revisions that match')),
4173 ('n', 'line-number', None, _('print matching line numbers')),
4179 ('n', 'line-number', None, _('print matching line numbers')),
4174 ('r', 'rev', [],
4180 ('r', 'rev', [],
4175 _('only search files changed within revision range'), _('REV')),
4181 _('only search files changed within revision range'), _('REV')),
4176 ('u', 'user', None, _('list the author (long with -v)')),
4182 ('u', 'user', None, _('list the author (long with -v)')),
4177 ('d', 'date', None, _('list the date (short with -q)')),
4183 ('d', 'date', None, _('list the date (short with -q)')),
4178 ] + walkopts,
4184 ] + walkopts,
4179 _('[OPTION]... PATTERN [FILE]...')),
4185 _('[OPTION]... PATTERN [FILE]...')),
4180 "heads":
4186 "heads":
4181 (heads,
4187 (heads,
4182 [('r', 'rev', '',
4188 [('r', 'rev', '',
4183 _('show only heads which are descendants of REV'), _('REV')),
4189 _('show only heads which are descendants of REV'), _('REV')),
4184 ('t', 'topo', False, _('show topological heads only')),
4190 ('t', 'topo', False, _('show topological heads only')),
4185 ('a', 'active', False,
4191 ('a', 'active', False,
4186 _('show active branchheads only (DEPRECATED)')),
4192 _('show active branchheads only (DEPRECATED)')),
4187 ('c', 'closed', False,
4193 ('c', 'closed', False,
4188 _('show normal and closed branch heads')),
4194 _('show normal and closed branch heads')),
4189 ] + templateopts,
4195 ] + templateopts,
4190 _('[-ac] [-r REV] [REV]...')),
4196 _('[-ac] [-r REV] [REV]...')),
4191 "help": (help_, [], _('[TOPIC]')),
4197 "help": (help_, [], _('[TOPIC]')),
4192 "identify|id":
4198 "identify|id":
4193 (identify,
4199 (identify,
4194 [('r', 'rev', '',
4200 [('r', 'rev', '',
4195 _('identify the specified revision'), _('REV')),
4201 _('identify the specified revision'), _('REV')),
4196 ('n', 'num', None, _('show local revision number')),
4202 ('n', 'num', None, _('show local revision number')),
4197 ('i', 'id', None, _('show global revision id')),
4203 ('i', 'id', None, _('show global revision id')),
4198 ('b', 'branch', None, _('show branch')),
4204 ('b', 'branch', None, _('show branch')),
4199 ('t', 'tags', None, _('show tags'))],
4205 ('t', 'tags', None, _('show tags'))],
4200 _('[-nibt] [-r REV] [SOURCE]')),
4206 _('[-nibt] [-r REV] [SOURCE]')),
4201 "import|patch":
4207 "import|patch":
4202 (import_,
4208 (import_,
4203 [('p', 'strip', 1,
4209 [('p', 'strip', 1,
4204 _('directory strip option for patch. This has the same '
4210 _('directory strip option for patch. This has the same '
4205 'meaning as the corresponding patch option'),
4211 'meaning as the corresponding patch option'),
4206 _('NUM')),
4212 _('NUM')),
4207 ('b', 'base', '',
4213 ('b', 'base', '',
4208 _('base path'), _('PATH')),
4214 _('base path'), _('PATH')),
4209 ('f', 'force', None,
4215 ('f', 'force', None,
4210 _('skip check for outstanding uncommitted changes')),
4216 _('skip check for outstanding uncommitted changes')),
4211 ('', 'no-commit', None,
4217 ('', 'no-commit', None,
4212 _("don't commit, just update the working directory")),
4218 _("don't commit, just update the working directory")),
4213 ('', 'exact', None,
4219 ('', 'exact', None,
4214 _('apply patch to the nodes from which it was generated')),
4220 _('apply patch to the nodes from which it was generated')),
4215 ('', 'import-branch', None,
4221 ('', 'import-branch', None,
4216 _('use any branch information in patch (implied by --exact)'))] +
4222 _('use any branch information in patch (implied by --exact)'))] +
4217 commitopts + commitopts2 + similarityopts,
4223 commitopts + commitopts2 + similarityopts,
4218 _('[OPTION]... PATCH...')),
4224 _('[OPTION]... PATCH...')),
4219 "incoming|in":
4225 "incoming|in":
4220 (incoming,
4226 (incoming,
4221 [('f', 'force', None,
4227 [('f', 'force', None,
4222 _('run even if remote repository is unrelated')),
4228 _('run even if remote repository is unrelated')),
4223 ('n', 'newest-first', None, _('show newest record first')),
4229 ('n', 'newest-first', None, _('show newest record first')),
4224 ('', 'bundle', '',
4230 ('', 'bundle', '',
4225 _('file to store the bundles into'), _('FILE')),
4231 _('file to store the bundles into'), _('FILE')),
4226 ('r', 'rev', [],
4232 ('r', 'rev', [],
4227 _('a remote changeset intended to be added'), _('REV')),
4233 _('a remote changeset intended to be added'), _('REV')),
4228 ('b', 'branch', [],
4234 ('b', 'branch', [],
4229 _('a specific branch you would like to pull'), _('BRANCH')),
4235 _('a specific branch you would like to pull'), _('BRANCH')),
4230 ] + logopts + remoteopts,
4236 ] + logopts + remoteopts,
4231 _('[-p] [-n] [-M] [-f] [-r REV]...'
4237 _('[-p] [-n] [-M] [-f] [-r REV]...'
4232 ' [--bundle FILENAME] [SOURCE]')),
4238 ' [--bundle FILENAME] [SOURCE]')),
4233 "^init":
4239 "^init":
4234 (init,
4240 (init,
4235 remoteopts,
4241 remoteopts,
4236 _('[-e CMD] [--remotecmd CMD] [DEST]')),
4242 _('[-e CMD] [--remotecmd CMD] [DEST]')),
4237 "locate":
4243 "locate":
4238 (locate,
4244 (locate,
4239 [('r', 'rev', '',
4245 [('r', 'rev', '',
4240 _('search the repository as it is in REV'), _('REV')),
4246 _('search the repository as it is in REV'), _('REV')),
4241 ('0', 'print0', None,
4247 ('0', 'print0', None,
4242 _('end filenames with NUL, for use with xargs')),
4248 _('end filenames with NUL, for use with xargs')),
4243 ('f', 'fullpath', None,
4249 ('f', 'fullpath', None,
4244 _('print complete paths from the filesystem root')),
4250 _('print complete paths from the filesystem root')),
4245 ] + walkopts,
4251 ] + walkopts,
4246 _('[OPTION]... [PATTERN]...')),
4252 _('[OPTION]... [PATTERN]...')),
4247 "^log|history":
4253 "^log|history":
4248 (log,
4254 (log,
4249 [('f', 'follow', None,
4255 [('f', 'follow', None,
4250 _('follow changeset history,'
4256 _('follow changeset history,'
4251 ' or file history across copies and renames')),
4257 ' or file history across copies and renames')),
4252 ('', 'follow-first', None,
4258 ('', 'follow-first', None,
4253 _('only follow the first parent of merge changesets')),
4259 _('only follow the first parent of merge changesets')),
4254 ('d', 'date', '',
4260 ('d', 'date', '',
4255 _('show revisions matching date spec'), _('DATE')),
4261 _('show revisions matching date spec'), _('DATE')),
4256 ('C', 'copies', None, _('show copied files')),
4262 ('C', 'copies', None, _('show copied files')),
4257 ('k', 'keyword', [],
4263 ('k', 'keyword', [],
4258 _('do case-insensitive search for a given text'), _('TEXT')),
4264 _('do case-insensitive search for a given text'), _('TEXT')),
4259 ('r', 'rev', [],
4265 ('r', 'rev', [],
4260 _('show the specified revision or range'), _('REV')),
4266 _('show the specified revision or range'), _('REV')),
4261 ('', 'removed', None, _('include revisions where files were removed')),
4267 ('', 'removed', None, _('include revisions where files were removed')),
4262 ('m', 'only-merges', None, _('show only merges')),
4268 ('m', 'only-merges', None, _('show only merges')),
4263 ('u', 'user', [],
4269 ('u', 'user', [],
4264 _('revisions committed by user'), _('USER')),
4270 _('revisions committed by user'), _('USER')),
4265 ('', 'only-branch', [],
4271 ('', 'only-branch', [],
4266 _('show only changesets within the given named branch (DEPRECATED)'),
4272 _('show only changesets within the given named branch (DEPRECATED)'),
4267 _('BRANCH')),
4273 _('BRANCH')),
4268 ('b', 'branch', [],
4274 ('b', 'branch', [],
4269 _('show changesets within the given named branch'), _('BRANCH')),
4275 _('show changesets within the given named branch'), _('BRANCH')),
4270 ('P', 'prune', [],
4276 ('P', 'prune', [],
4271 _('do not display revision or any of its ancestors'), _('REV')),
4277 _('do not display revision or any of its ancestors'), _('REV')),
4272 ] + logopts + walkopts,
4278 ] + logopts + walkopts,
4273 _('[OPTION]... [FILE]')),
4279 _('[OPTION]... [FILE]')),
4274 "manifest":
4280 "manifest":
4275 (manifest,
4281 (manifest,
4276 [('r', 'rev', '',
4282 [('r', 'rev', '',
4277 _('revision to display'), _('REV'))],
4283 _('revision to display'), _('REV'))],
4278 _('[-r REV]')),
4284 _('[-r REV]')),
4279 "^merge":
4285 "^merge":
4280 (merge,
4286 (merge,
4281 [('f', 'force', None, _('force a merge with outstanding changes')),
4287 [('f', 'force', None, _('force a merge with outstanding changes')),
4282 ('r', 'rev', '',
4288 ('r', 'rev', '',
4283 _('revision to merge'), _('REV')),
4289 _('revision to merge'), _('REV')),
4284 ('P', 'preview', None,
4290 ('P', 'preview', None,
4285 _('review revisions to merge (no merge is performed)'))],
4291 _('review revisions to merge (no merge is performed)'))],
4286 _('[-P] [-f] [[-r] REV]')),
4292 _('[-P] [-f] [[-r] REV]')),
4287 "outgoing|out":
4293 "outgoing|out":
4288 (outgoing,
4294 (outgoing,
4289 [('f', 'force', None,
4295 [('f', 'force', None,
4290 _('run even when the destination is unrelated')),
4296 _('run even when the destination is unrelated')),
4291 ('r', 'rev', [],
4297 ('r', 'rev', [],
4292 _('a changeset intended to be included in the destination'),
4298 _('a changeset intended to be included in the destination'),
4293 _('REV')),
4299 _('REV')),
4294 ('n', 'newest-first', None, _('show newest record first')),
4300 ('n', 'newest-first', None, _('show newest record first')),
4295 ('b', 'branch', [],
4301 ('b', 'branch', [],
4296 _('a specific branch you would like to push'), _('BRANCH')),
4302 _('a specific branch you would like to push'), _('BRANCH')),
4297 ] + logopts + remoteopts,
4303 ] + logopts + remoteopts,
4298 _('[-M] [-p] [-n] [-f] [-r REV]... [DEST]')),
4304 _('[-M] [-p] [-n] [-f] [-r REV]... [DEST]')),
4299 "parents":
4305 "parents":
4300 (parents,
4306 (parents,
4301 [('r', 'rev', '',
4307 [('r', 'rev', '',
4302 _('show parents of the specified revision'), _('REV')),
4308 _('show parents of the specified revision'), _('REV')),
4303 ] + templateopts,
4309 ] + templateopts,
4304 _('[-r REV] [FILE]')),
4310 _('[-r REV] [FILE]')),
4305 "paths": (paths, [], _('[NAME]')),
4311 "paths": (paths, [], _('[NAME]')),
4306 "^pull":
4312 "^pull":
4307 (pull,
4313 (pull,
4308 [('u', 'update', None,
4314 [('u', 'update', None,
4309 _('update to new branch head if changesets were pulled')),
4315 _('update to new branch head if changesets were pulled')),
4310 ('f', 'force', None,
4316 ('f', 'force', None,
4311 _('run even when remote repository is unrelated')),
4317 _('run even when remote repository is unrelated')),
4312 ('r', 'rev', [],
4318 ('r', 'rev', [],
4313 _('a remote changeset intended to be added'), _('REV')),
4319 _('a remote changeset intended to be added'), _('REV')),
4314 ('b', 'branch', [],
4320 ('b', 'branch', [],
4315 _('a specific branch you would like to pull'), _('BRANCH')),
4321 _('a specific branch you would like to pull'), _('BRANCH')),
4316 ] + remoteopts,
4322 ] + remoteopts,
4317 _('[-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]')),
4323 _('[-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]')),
4318 "^push":
4324 "^push":
4319 (push,
4325 (push,
4320 [('f', 'force', None, _('force push')),
4326 [('f', 'force', None, _('force push')),
4321 ('r', 'rev', [],
4327 ('r', 'rev', [],
4322 _('a changeset intended to be included in the destination'),
4328 _('a changeset intended to be included in the destination'),
4323 _('REV')),
4329 _('REV')),
4324 ('b', 'branch', [],
4330 ('b', 'branch', [],
4325 _('a specific branch you would like to push'), _('BRANCH')),
4331 _('a specific branch you would like to push'), _('BRANCH')),
4326 ('', 'new-branch', False, _('allow pushing a new branch')),
4332 ('', 'new-branch', False, _('allow pushing a new branch')),
4327 ] + remoteopts,
4333 ] + remoteopts,
4328 _('[-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]')),
4334 _('[-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]')),
4329 "recover": (recover, []),
4335 "recover": (recover, []),
4330 "^remove|rm":
4336 "^remove|rm":
4331 (remove,
4337 (remove,
4332 [('A', 'after', None, _('record delete for missing files')),
4338 [('A', 'after', None, _('record delete for missing files')),
4333 ('f', 'force', None,
4339 ('f', 'force', None,
4334 _('remove (and delete) file even if added or modified')),
4340 _('remove (and delete) file even if added or modified')),
4335 ] + walkopts,
4341 ] + walkopts,
4336 _('[OPTION]... FILE...')),
4342 _('[OPTION]... FILE...')),
4337 "rename|mv":
4343 "rename|mv":
4338 (rename,
4344 (rename,
4339 [('A', 'after', None, _('record a rename that has already occurred')),
4345 [('A', 'after', None, _('record a rename that has already occurred')),
4340 ('f', 'force', None,
4346 ('f', 'force', None,
4341 _('forcibly copy over an existing managed file')),
4347 _('forcibly copy over an existing managed file')),
4342 ] + walkopts + dryrunopts,
4348 ] + walkopts + dryrunopts,
4343 _('[OPTION]... SOURCE... DEST')),
4349 _('[OPTION]... SOURCE... DEST')),
4344 "resolve":
4350 "resolve":
4345 (resolve,
4351 (resolve,
4346 [('a', 'all', None, _('select all unresolved files')),
4352 [('a', 'all', None, _('select all unresolved files')),
4347 ('l', 'list', None, _('list state of files needing merge')),
4353 ('l', 'list', None, _('list state of files needing merge')),
4348 ('m', 'mark', None, _('mark files as resolved')),
4354 ('m', 'mark', None, _('mark files as resolved')),
4349 ('u', 'unmark', None, _('mark files as unresolved')),
4355 ('u', 'unmark', None, _('mark files as unresolved')),
4350 ('n', 'no-status', None, _('hide status prefix'))]
4356 ('n', 'no-status', None, _('hide status prefix'))]
4351 + walkopts,
4357 + walkopts,
4352 _('[OPTION]... [FILE]...')),
4358 _('[OPTION]... [FILE]...')),
4353 "revert":
4359 "revert":
4354 (revert,
4360 (revert,
4355 [('a', 'all', None, _('revert all changes when no arguments given')),
4361 [('a', 'all', None, _('revert all changes when no arguments given')),
4356 ('d', 'date', '',
4362 ('d', 'date', '',
4357 _('tipmost revision matching date'), _('DATE')),
4363 _('tipmost revision matching date'), _('DATE')),
4358 ('r', 'rev', '',
4364 ('r', 'rev', '',
4359 _('revert to the specified revision'), _('REV')),
4365 _('revert to the specified revision'), _('REV')),
4360 ('', 'no-backup', None, _('do not save backup copies of files')),
4366 ('', 'no-backup', None, _('do not save backup copies of files')),
4361 ] + walkopts + dryrunopts,
4367 ] + walkopts + dryrunopts,
4362 _('[OPTION]... [-r REV] [NAME]...')),
4368 _('[OPTION]... [-r REV] [NAME]...')),
4363 "rollback": (rollback, dryrunopts),
4369 "rollback": (rollback, dryrunopts),
4364 "root": (root, []),
4370 "root": (root, []),
4365 "^serve":
4371 "^serve":
4366 (serve,
4372 (serve,
4367 [('A', 'accesslog', '',
4373 [('A', 'accesslog', '',
4368 _('name of access log file to write to'), _('FILE')),
4374 _('name of access log file to write to'), _('FILE')),
4369 ('d', 'daemon', None, _('run server in background')),
4375 ('d', 'daemon', None, _('run server in background')),
4370 ('', 'daemon-pipefds', '',
4376 ('', 'daemon-pipefds', '',
4371 _('used internally by daemon mode'), _('NUM')),
4377 _('used internally by daemon mode'), _('NUM')),
4372 ('E', 'errorlog', '',
4378 ('E', 'errorlog', '',
4373 _('name of error log file to write to'), _('FILE')),
4379 _('name of error log file to write to'), _('FILE')),
4374 # use string type, then we can check if something was passed
4380 # use string type, then we can check if something was passed
4375 ('p', 'port', '',
4381 ('p', 'port', '',
4376 _('port to listen on (default: 8000)'), _('PORT')),
4382 _('port to listen on (default: 8000)'), _('PORT')),
4377 ('a', 'address', '',
4383 ('a', 'address', '',
4378 _('address to listen on (default: all interfaces)'), _('ADDR')),
4384 _('address to listen on (default: all interfaces)'), _('ADDR')),
4379 ('', 'prefix', '',
4385 ('', 'prefix', '',
4380 _('prefix path to serve from (default: server root)'), _('PREFIX')),
4386 _('prefix path to serve from (default: server root)'), _('PREFIX')),
4381 ('n', 'name', '',
4387 ('n', 'name', '',
4382 _('name to show in web pages (default: working directory)'),
4388 _('name to show in web pages (default: working directory)'),
4383 _('NAME')),
4389 _('NAME')),
4384 ('', 'web-conf', '',
4390 ('', 'web-conf', '',
4385 _('name of the hgweb config file (serve more than one repository)'),
4391 _('name of the hgweb config file (serve more than one repository)'),
4386 _('FILE')),
4392 _('FILE')),
4387 ('', 'webdir-conf', '',
4393 ('', 'webdir-conf', '',
4388 _('name of the hgweb config file (DEPRECATED)'), _('FILE')),
4394 _('name of the hgweb config file (DEPRECATED)'), _('FILE')),
4389 ('', 'pid-file', '',
4395 ('', 'pid-file', '',
4390 _('name of file to write process ID to'), _('FILE')),
4396 _('name of file to write process ID to'), _('FILE')),
4391 ('', 'stdio', None, _('for remote clients')),
4397 ('', 'stdio', None, _('for remote clients')),
4392 ('t', 'templates', '',
4398 ('t', 'templates', '',
4393 _('web templates to use'), _('TEMPLATE')),
4399 _('web templates to use'), _('TEMPLATE')),
4394 ('', 'style', '',
4400 ('', 'style', '',
4395 _('template style to use'), _('STYLE')),
4401 _('template style to use'), _('STYLE')),
4396 ('6', 'ipv6', None, _('use IPv6 in addition to IPv4')),
4402 ('6', 'ipv6', None, _('use IPv6 in addition to IPv4')),
4397 ('', 'certificate', '',
4403 ('', 'certificate', '',
4398 _('SSL certificate file'), _('FILE'))],
4404 _('SSL certificate file'), _('FILE'))],
4399 _('[OPTION]...')),
4405 _('[OPTION]...')),
4400 "showconfig|debugconfig":
4406 "showconfig|debugconfig":
4401 (showconfig,
4407 (showconfig,
4402 [('u', 'untrusted', None, _('show untrusted configuration options'))],
4408 [('u', 'untrusted', None, _('show untrusted configuration options'))],
4403 _('[-u] [NAME]...')),
4409 _('[-u] [NAME]...')),
4404 "^summary|sum":
4410 "^summary|sum":
4405 (summary,
4411 (summary,
4406 [('', 'remote', None, _('check for push and pull'))], '[--remote]'),
4412 [('', 'remote', None, _('check for push and pull'))], '[--remote]'),
4407 "^status|st":
4413 "^status|st":
4408 (status,
4414 (status,
4409 [('A', 'all', None, _('show status of all files')),
4415 [('A', 'all', None, _('show status of all files')),
4410 ('m', 'modified', None, _('show only modified files')),
4416 ('m', 'modified', None, _('show only modified files')),
4411 ('a', 'added', None, _('show only added files')),
4417 ('a', 'added', None, _('show only added files')),
4412 ('r', 'removed', None, _('show only removed files')),
4418 ('r', 'removed', None, _('show only removed files')),
4413 ('d', 'deleted', None, _('show only deleted (but tracked) files')),
4419 ('d', 'deleted', None, _('show only deleted (but tracked) files')),
4414 ('c', 'clean', None, _('show only files without changes')),
4420 ('c', 'clean', None, _('show only files without changes')),
4415 ('u', 'unknown', None, _('show only unknown (not tracked) files')),
4421 ('u', 'unknown', None, _('show only unknown (not tracked) files')),
4416 ('i', 'ignored', None, _('show only ignored files')),
4422 ('i', 'ignored', None, _('show only ignored files')),
4417 ('n', 'no-status', None, _('hide status prefix')),
4423 ('n', 'no-status', None, _('hide status prefix')),
4418 ('C', 'copies', None, _('show source of copied files')),
4424 ('C', 'copies', None, _('show source of copied files')),
4419 ('0', 'print0', None,
4425 ('0', 'print0', None,
4420 _('end filenames with NUL, for use with xargs')),
4426 _('end filenames with NUL, for use with xargs')),
4421 ('', 'rev', [],
4427 ('', 'rev', [],
4422 _('show difference from revision'), _('REV')),
4428 _('show difference from revision'), _('REV')),
4423 ('', 'change', '',
4429 ('', 'change', '',
4424 _('list the changed files of a revision'), _('REV')),
4430 _('list the changed files of a revision'), _('REV')),
4425 ] + walkopts,
4431 ] + walkopts,
4426 _('[OPTION]... [FILE]...')),
4432 _('[OPTION]... [FILE]...')),
4427 "tag":
4433 "tag":
4428 (tag,
4434 (tag,
4429 [('f', 'force', None, _('replace existing tag')),
4435 [('f', 'force', None, _('replace existing tag')),
4430 ('l', 'local', None, _('make the tag local')),
4436 ('l', 'local', None, _('make the tag local')),
4431 ('r', 'rev', '',
4437 ('r', 'rev', '',
4432 _('revision to tag'), _('REV')),
4438 _('revision to tag'), _('REV')),
4433 ('', 'remove', None, _('remove a tag')),
4439 ('', 'remove', None, _('remove a tag')),
4434 # -l/--local is already there, commitopts cannot be used
4440 # -l/--local is already there, commitopts cannot be used
4435 ('e', 'edit', None, _('edit commit message')),
4441 ('e', 'edit', None, _('edit commit message')),
4436 ('m', 'message', '',
4442 ('m', 'message', '',
4437 _('use <text> as commit message'), _('TEXT')),
4443 _('use <text> as commit message'), _('TEXT')),
4438 ] + commitopts2,
4444 ] + commitopts2,
4439 _('[-f] [-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME...')),
4445 _('[-f] [-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME...')),
4440 "tags": (tags, [], ''),
4446 "tags": (tags, [], ''),
4441 "tip":
4447 "tip":
4442 (tip,
4448 (tip,
4443 [('p', 'patch', None, _('show patch')),
4449 [('p', 'patch', None, _('show patch')),
4444 ('g', 'git', None, _('use git extended diff format')),
4450 ('g', 'git', None, _('use git extended diff format')),
4445 ] + templateopts,
4451 ] + templateopts,
4446 _('[-p] [-g]')),
4452 _('[-p] [-g]')),
4447 "unbundle":
4453 "unbundle":
4448 (unbundle,
4454 (unbundle,
4449 [('u', 'update', None,
4455 [('u', 'update', None,
4450 _('update to new branch head if changesets were unbundled'))],
4456 _('update to new branch head if changesets were unbundled'))],
4451 _('[-u] FILE...')),
4457 _('[-u] FILE...')),
4452 "^update|up|checkout|co":
4458 "^update|up|checkout|co":
4453 (update,
4459 (update,
4454 [('C', 'clean', None, _('discard uncommitted changes (no backup)')),
4460 [('C', 'clean', None, _('discard uncommitted changes (no backup)')),
4455 ('c', 'check', None, _('check for uncommitted changes')),
4461 ('c', 'check', None, _('check for uncommitted changes')),
4456 ('d', 'date', '',
4462 ('d', 'date', '',
4457 _('tipmost revision matching date'), _('DATE')),
4463 _('tipmost revision matching date'), _('DATE')),
4458 ('r', 'rev', '',
4464 ('r', 'rev', '',
4459 _('revision'), _('REV'))],
4465 _('revision'), _('REV'))],
4460 _('[-c] [-C] [-d DATE] [[-r] REV]')),
4466 _('[-c] [-C] [-d DATE] [[-r] REV]')),
4461 "verify": (verify, []),
4467 "verify": (verify, []),
4462 "version": (version_, []),
4468 "version": (version_, []),
4463 }
4469 }
4464
4470
4465 norepo = ("clone init version help debugcommands debugcomplete debugdata"
4471 norepo = ("clone init version help debugcommands debugcomplete debugdata"
4466 " debugindex debugindexdot debugdate debuginstall debugfsinfo"
4472 " debugindex debugindexdot debugdate debuginstall debugfsinfo"
4467 " debugpushkey")
4473 " debugpushkey")
4468 optionalrepo = ("identify paths serve showconfig debugancestor debugdag")
4474 optionalrepo = ("identify paths serve showconfig debugancestor debugdag")
@@ -1,343 +1,393 b''
1 $ hg init a
1 $ hg init a
2 $ cd a
2 $ cd a
3 $ echo 'root' >root
3 $ echo 'root' >root
4 $ hg add root
4 $ hg add root
5 $ hg commit -d '0 0' -m "Adding root node"
5 $ hg commit -d '0 0' -m "Adding root node"
6
6
7 $ echo 'a' >a
7 $ echo 'a' >a
8 $ hg add a
8 $ hg add a
9 $ hg branch a
9 $ hg branch a
10 marked working directory as branch a
10 marked working directory as branch a
11 $ hg commit -d '1 0' -m "Adding a branch"
11 $ hg commit -d '1 0' -m "Adding a branch"
12
12
13 $ hg branch q
13 $ hg branch q
14 marked working directory as branch q
14 marked working directory as branch q
15 $ echo 'aa' >a
15 $ echo 'aa' >a
16 $ hg branch -C
16 $ hg branch -C
17 reset working directory to branch a
17 reset working directory to branch a
18 $ hg commit -d '2 0' -m "Adding to a branch"
18 $ hg commit -d '2 0' -m "Adding to a branch"
19
19
20 $ hg update -C 0
20 $ hg update -C 0
21 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
21 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
22 $ echo 'b' >b
22 $ echo 'b' >b
23 $ hg add b
23 $ hg add b
24 $ hg branch b
24 $ hg branch b
25 marked working directory as branch b
25 marked working directory as branch b
26 $ hg commit -d '2 0' -m "Adding b branch"
26 $ hg commit -d '2 0' -m "Adding b branch"
27
27
28 $ echo 'bh1' >bh1
28 $ echo 'bh1' >bh1
29 $ hg add bh1
29 $ hg add bh1
30 $ hg commit -d '3 0' -m "Adding b branch head 1"
30 $ hg commit -d '3 0' -m "Adding b branch head 1"
31
31
32 $ hg update -C 2
32 $ hg update -C 2
33 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
33 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
34 $ echo 'bh2' >bh2
34 $ echo 'bh2' >bh2
35 $ hg add bh2
35 $ hg add bh2
36 $ hg commit -d '4 0' -m "Adding b branch head 2"
36 $ hg commit -d '4 0' -m "Adding b branch head 2"
37
37
38 $ echo 'c' >c
38 $ echo 'c' >c
39 $ hg add c
39 $ hg add c
40 $ hg branch c
40 $ hg branch c
41 marked working directory as branch c
41 marked working directory as branch c
42 $ hg commit -d '5 0' -m "Adding c branch"
42 $ hg commit -d '5 0' -m "Adding c branch"
43
43
44 $ hg branch tip
44 $ hg branch tip
45 abort: the name 'tip' is reserved
45 abort: the name 'tip' is reserved
46 $ hg branch null
46 $ hg branch null
47 abort: the name 'null' is reserved
47 abort: the name 'null' is reserved
48 $ hg branch .
48 $ hg branch .
49 abort: the name '.' is reserved
49 abort: the name '.' is reserved
50
50
51 $ echo 'd' >d
51 $ echo 'd' >d
52 $ hg add d
52 $ hg add d
53 $ hg branch 'a branch name much longer than the default justification used by branches'
53 $ hg branch 'a branch name much longer than the default justification used by branches'
54 marked working directory as branch a branch name much longer than the default justification used by branches
54 marked working directory as branch a branch name much longer than the default justification used by branches
55 $ hg commit -d '6 0' -m "Adding d branch"
55 $ hg commit -d '6 0' -m "Adding d branch"
56
56
57 $ hg branches
57 $ hg branches
58 a branch name much longer than the default justification used by branches 7:10ff5895aa57
58 a branch name much longer than the default justification used by branches 7:10ff5895aa57
59 b 4:aee39cd168d0
59 b 4:aee39cd168d0
60 c 6:589736a22561 (inactive)
60 c 6:589736a22561 (inactive)
61 a 5:d8cbc61dbaa6 (inactive)
61 a 5:d8cbc61dbaa6 (inactive)
62 default 0:19709c5a4e75 (inactive)
62 default 0:19709c5a4e75 (inactive)
63
63
64 -------
64 -------
65
65
66 $ hg branches -a
66 $ hg branches -a
67 a branch name much longer than the default justification used by branches 7:10ff5895aa57
67 a branch name much longer than the default justification used by branches 7:10ff5895aa57
68 b 4:aee39cd168d0
68 b 4:aee39cd168d0
69
69
70 --- Branch a
70 --- Branch a
71
71
72 $ hg log -b a
72 $ hg log -b a
73 changeset: 5:d8cbc61dbaa6
73 changeset: 5:d8cbc61dbaa6
74 branch: a
74 branch: a
75 parent: 2:881fe2b92ad0
75 parent: 2:881fe2b92ad0
76 user: test
76 user: test
77 date: Thu Jan 01 00:00:04 1970 +0000
77 date: Thu Jan 01 00:00:04 1970 +0000
78 summary: Adding b branch head 2
78 summary: Adding b branch head 2
79
79
80 changeset: 2:881fe2b92ad0
80 changeset: 2:881fe2b92ad0
81 branch: a
81 branch: a
82 user: test
82 user: test
83 date: Thu Jan 01 00:00:02 1970 +0000
83 date: Thu Jan 01 00:00:02 1970 +0000
84 summary: Adding to a branch
84 summary: Adding to a branch
85
85
86 changeset: 1:dd6b440dd85a
86 changeset: 1:dd6b440dd85a
87 branch: a
87 branch: a
88 user: test
88 user: test
89 date: Thu Jan 01 00:00:01 1970 +0000
89 date: Thu Jan 01 00:00:01 1970 +0000
90 summary: Adding a branch
90 summary: Adding a branch
91
91
92
92
93 ---- Branch b
93 ---- Branch b
94
94
95 $ hg log -b b
95 $ hg log -b b
96 changeset: 4:aee39cd168d0
96 changeset: 4:aee39cd168d0
97 branch: b
97 branch: b
98 user: test
98 user: test
99 date: Thu Jan 01 00:00:03 1970 +0000
99 date: Thu Jan 01 00:00:03 1970 +0000
100 summary: Adding b branch head 1
100 summary: Adding b branch head 1
101
101
102 changeset: 3:ac22033332d1
102 changeset: 3:ac22033332d1
103 branch: b
103 branch: b
104 parent: 0:19709c5a4e75
104 parent: 0:19709c5a4e75
105 user: test
105 user: test
106 date: Thu Jan 01 00:00:02 1970 +0000
106 date: Thu Jan 01 00:00:02 1970 +0000
107 summary: Adding b branch
107 summary: Adding b branch
108
108
109
109
110 ---- going to test branch closing
110 ---- going to test branch closing
111
111
112 $ hg branches
112 $ hg branches
113 a branch name much longer than the default justification used by branches 7:10ff5895aa57
113 a branch name much longer than the default justification used by branches 7:10ff5895aa57
114 b 4:aee39cd168d0
114 b 4:aee39cd168d0
115 c 6:589736a22561 (inactive)
115 c 6:589736a22561 (inactive)
116 a 5:d8cbc61dbaa6 (inactive)
116 a 5:d8cbc61dbaa6 (inactive)
117 default 0:19709c5a4e75 (inactive)
117 default 0:19709c5a4e75 (inactive)
118 $ hg up -C b
118 $ hg up -C b
119 2 files updated, 0 files merged, 4 files removed, 0 files unresolved
119 2 files updated, 0 files merged, 4 files removed, 0 files unresolved
120 $ echo 'xxx1' >> b
120 $ echo 'xxx1' >> b
121 $ hg commit -d '7 0' -m 'adding cset to branch b'
121 $ hg commit -d '7 0' -m 'adding cset to branch b'
122 $ hg up -C aee39cd168d0
122 $ hg up -C aee39cd168d0
123 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
123 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
124 $ echo 'xxx2' >> b
124 $ echo 'xxx2' >> b
125 $ hg commit -d '8 0' -m 'adding head to branch b'
125 $ hg commit -d '8 0' -m 'adding head to branch b'
126 created new head
126 created new head
127 $ echo 'xxx3' >> b
127 $ echo 'xxx3' >> b
128 $ hg commit -d '9 0' -m 'adding another cset to branch b'
128 $ hg commit -d '9 0' -m 'adding another cset to branch b'
129 $ hg branches
129 $ hg branches
130 b 10:bfbe841b666e
130 b 10:bfbe841b666e
131 a branch name much longer than the default justification used by branches 7:10ff5895aa57
131 a branch name much longer than the default justification used by branches 7:10ff5895aa57
132 c 6:589736a22561 (inactive)
132 c 6:589736a22561 (inactive)
133 a 5:d8cbc61dbaa6 (inactive)
133 a 5:d8cbc61dbaa6 (inactive)
134 default 0:19709c5a4e75 (inactive)
134 default 0:19709c5a4e75 (inactive)
135 $ hg heads --closed
135 $ hg heads --closed
136 changeset: 10:bfbe841b666e
136 changeset: 10:bfbe841b666e
137 branch: b
137 branch: b
138 tag: tip
138 tag: tip
139 user: test
139 user: test
140 date: Thu Jan 01 00:00:09 1970 +0000
140 date: Thu Jan 01 00:00:09 1970 +0000
141 summary: adding another cset to branch b
141 summary: adding another cset to branch b
142
142
143 changeset: 8:eebb944467c9
143 changeset: 8:eebb944467c9
144 branch: b
144 branch: b
145 parent: 4:aee39cd168d0
145 parent: 4:aee39cd168d0
146 user: test
146 user: test
147 date: Thu Jan 01 00:00:07 1970 +0000
147 date: Thu Jan 01 00:00:07 1970 +0000
148 summary: adding cset to branch b
148 summary: adding cset to branch b
149
149
150 changeset: 7:10ff5895aa57
150 changeset: 7:10ff5895aa57
151 branch: a branch name much longer than the default justification used by branches
151 branch: a branch name much longer than the default justification used by branches
152 user: test
152 user: test
153 date: Thu Jan 01 00:00:06 1970 +0000
153 date: Thu Jan 01 00:00:06 1970 +0000
154 summary: Adding d branch
154 summary: Adding d branch
155
155
156 changeset: 6:589736a22561
156 changeset: 6:589736a22561
157 branch: c
157 branch: c
158 user: test
158 user: test
159 date: Thu Jan 01 00:00:05 1970 +0000
159 date: Thu Jan 01 00:00:05 1970 +0000
160 summary: Adding c branch
160 summary: Adding c branch
161
161
162 changeset: 5:d8cbc61dbaa6
162 changeset: 5:d8cbc61dbaa6
163 branch: a
163 branch: a
164 parent: 2:881fe2b92ad0
164 parent: 2:881fe2b92ad0
165 user: test
165 user: test
166 date: Thu Jan 01 00:00:04 1970 +0000
166 date: Thu Jan 01 00:00:04 1970 +0000
167 summary: Adding b branch head 2
167 summary: Adding b branch head 2
168
168
169 changeset: 0:19709c5a4e75
169 changeset: 0:19709c5a4e75
170 user: test
170 user: test
171 date: Thu Jan 01 00:00:00 1970 +0000
171 date: Thu Jan 01 00:00:00 1970 +0000
172 summary: Adding root node
172 summary: Adding root node
173
173
174 $ hg heads
174 $ hg heads
175 changeset: 10:bfbe841b666e
175 changeset: 10:bfbe841b666e
176 branch: b
176 branch: b
177 tag: tip
177 tag: tip
178 user: test
178 user: test
179 date: Thu Jan 01 00:00:09 1970 +0000
179 date: Thu Jan 01 00:00:09 1970 +0000
180 summary: adding another cset to branch b
180 summary: adding another cset to branch b
181
181
182 changeset: 8:eebb944467c9
182 changeset: 8:eebb944467c9
183 branch: b
183 branch: b
184 parent: 4:aee39cd168d0
184 parent: 4:aee39cd168d0
185 user: test
185 user: test
186 date: Thu Jan 01 00:00:07 1970 +0000
186 date: Thu Jan 01 00:00:07 1970 +0000
187 summary: adding cset to branch b
187 summary: adding cset to branch b
188
188
189 changeset: 7:10ff5895aa57
189 changeset: 7:10ff5895aa57
190 branch: a branch name much longer than the default justification used by branches
190 branch: a branch name much longer than the default justification used by branches
191 user: test
191 user: test
192 date: Thu Jan 01 00:00:06 1970 +0000
192 date: Thu Jan 01 00:00:06 1970 +0000
193 summary: Adding d branch
193 summary: Adding d branch
194
194
195 changeset: 6:589736a22561
195 changeset: 6:589736a22561
196 branch: c
196 branch: c
197 user: test
197 user: test
198 date: Thu Jan 01 00:00:05 1970 +0000
198 date: Thu Jan 01 00:00:05 1970 +0000
199 summary: Adding c branch
199 summary: Adding c branch
200
200
201 changeset: 5:d8cbc61dbaa6
201 changeset: 5:d8cbc61dbaa6
202 branch: a
202 branch: a
203 parent: 2:881fe2b92ad0
203 parent: 2:881fe2b92ad0
204 user: test
204 user: test
205 date: Thu Jan 01 00:00:04 1970 +0000
205 date: Thu Jan 01 00:00:04 1970 +0000
206 summary: Adding b branch head 2
206 summary: Adding b branch head 2
207
207
208 changeset: 0:19709c5a4e75
208 changeset: 0:19709c5a4e75
209 user: test
209 user: test
210 date: Thu Jan 01 00:00:00 1970 +0000
210 date: Thu Jan 01 00:00:00 1970 +0000
211 summary: Adding root node
211 summary: Adding root node
212
212
213 $ hg commit -d '9 0' --close-branch -m 'prune bad branch'
213 $ hg commit -d '9 0' --close-branch -m 'prune bad branch'
214 $ hg branches -a
214 $ hg branches -a
215 b 8:eebb944467c9
215 b 8:eebb944467c9
216 a branch name much longer than the default justification used by branches 7:10ff5895aa57
216 a branch name much longer than the default justification used by branches 7:10ff5895aa57
217 $ hg up -C b
217 $ hg up -C b
218 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
218 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
219 $ hg commit -d '9 0' --close-branch -m 'close this part branch too'
219 $ hg commit -d '9 0' --close-branch -m 'close this part branch too'
220
220
221 --- b branch should be inactive
221 --- b branch should be inactive
222
222
223 $ hg branches
223 $ hg branches
224 a branch name much longer than the default justification used by branches 7:10ff5895aa57
224 a branch name much longer than the default justification used by branches 7:10ff5895aa57
225 c 6:589736a22561 (inactive)
225 c 6:589736a22561 (inactive)
226 a 5:d8cbc61dbaa6 (inactive)
226 a 5:d8cbc61dbaa6 (inactive)
227 default 0:19709c5a4e75 (inactive)
227 default 0:19709c5a4e75 (inactive)
228 $ hg branches -c
228 $ hg branches -c
229 a branch name much longer than the default justification used by branches 7:10ff5895aa57
229 a branch name much longer than the default justification used by branches 7:10ff5895aa57
230 b 12:2da6583810df (closed)
230 b 12:2da6583810df (closed)
231 c 6:589736a22561 (inactive)
231 c 6:589736a22561 (inactive)
232 a 5:d8cbc61dbaa6 (inactive)
232 a 5:d8cbc61dbaa6 (inactive)
233 default 0:19709c5a4e75 (inactive)
233 default 0:19709c5a4e75 (inactive)
234 $ hg branches -a
234 $ hg branches -a
235 a branch name much longer than the default justification used by branches 7:10ff5895aa57
235 a branch name much longer than the default justification used by branches 7:10ff5895aa57
236 $ hg heads b
236 $ hg heads b
237 no open branch heads found on branches b
237 no open branch heads found on branches b
238 $ hg heads --closed b
238 $ hg heads --closed b
239 changeset: 12:2da6583810df
239 changeset: 12:2da6583810df
240 branch: b
240 branch: b
241 tag: tip
241 tag: tip
242 parent: 8:eebb944467c9
242 parent: 8:eebb944467c9
243 user: test
243 user: test
244 date: Thu Jan 01 00:00:09 1970 +0000
244 date: Thu Jan 01 00:00:09 1970 +0000
245 summary: close this part branch too
245 summary: close this part branch too
246
246
247 changeset: 11:c84627f3c15d
247 changeset: 11:c84627f3c15d
248 branch: b
248 branch: b
249 user: test
249 user: test
250 date: Thu Jan 01 00:00:09 1970 +0000
250 date: Thu Jan 01 00:00:09 1970 +0000
251 summary: prune bad branch
251 summary: prune bad branch
252
252
253 $ echo 'xxx4' >> b
253 $ echo 'xxx4' >> b
254 $ hg commit -d '9 0' -m 'reopen branch with a change'
254 $ hg commit -d '9 0' -m 'reopen branch with a change'
255 reopening closed branch head 12
255 reopening closed branch head 12
256
256
257 --- branch b is back in action
257 --- branch b is back in action
258
258
259 $ hg branches -a
259 $ hg branches -a
260 b 13:6ac12926b8c3
260 b 13:6ac12926b8c3
261 a branch name much longer than the default justification used by branches 7:10ff5895aa57
261 a branch name much longer than the default justification used by branches 7:10ff5895aa57
262
262
263 ---- test heads listings
263 ---- test heads listings
264
264
265 $ hg heads
265 $ hg heads
266 changeset: 13:6ac12926b8c3
266 changeset: 13:6ac12926b8c3
267 branch: b
267 branch: b
268 tag: tip
268 tag: tip
269 user: test
269 user: test
270 date: Thu Jan 01 00:00:09 1970 +0000
270 date: Thu Jan 01 00:00:09 1970 +0000
271 summary: reopen branch with a change
271 summary: reopen branch with a change
272
272
273 changeset: 7:10ff5895aa57
273 changeset: 7:10ff5895aa57
274 branch: a branch name much longer than the default justification used by branches
274 branch: a branch name much longer than the default justification used by branches
275 user: test
275 user: test
276 date: Thu Jan 01 00:00:06 1970 +0000
276 date: Thu Jan 01 00:00:06 1970 +0000
277 summary: Adding d branch
277 summary: Adding d branch
278
278
279 changeset: 6:589736a22561
279 changeset: 6:589736a22561
280 branch: c
280 branch: c
281 user: test
281 user: test
282 date: Thu Jan 01 00:00:05 1970 +0000
282 date: Thu Jan 01 00:00:05 1970 +0000
283 summary: Adding c branch
283 summary: Adding c branch
284
284
285 changeset: 5:d8cbc61dbaa6
285 changeset: 5:d8cbc61dbaa6
286 branch: a
286 branch: a
287 parent: 2:881fe2b92ad0
287 parent: 2:881fe2b92ad0
288 user: test
288 user: test
289 date: Thu Jan 01 00:00:04 1970 +0000
289 date: Thu Jan 01 00:00:04 1970 +0000
290 summary: Adding b branch head 2
290 summary: Adding b branch head 2
291
291
292 changeset: 0:19709c5a4e75
292 changeset: 0:19709c5a4e75
293 user: test
293 user: test
294 date: Thu Jan 01 00:00:00 1970 +0000
294 date: Thu Jan 01 00:00:00 1970 +0000
295 summary: Adding root node
295 summary: Adding root node
296
296
297
297
298 branch default
298 branch default
299
299
300 $ hg heads default
300 $ hg heads default
301 changeset: 0:19709c5a4e75
301 changeset: 0:19709c5a4e75
302 user: test
302 user: test
303 date: Thu Jan 01 00:00:00 1970 +0000
303 date: Thu Jan 01 00:00:00 1970 +0000
304 summary: Adding root node
304 summary: Adding root node
305
305
306
306
307 branch a
307 branch a
308
308
309 $ hg heads a
309 $ hg heads a
310 changeset: 5:d8cbc61dbaa6
310 changeset: 5:d8cbc61dbaa6
311 branch: a
311 branch: a
312 parent: 2:881fe2b92ad0
312 parent: 2:881fe2b92ad0
313 user: test
313 user: test
314 date: Thu Jan 01 00:00:04 1970 +0000
314 date: Thu Jan 01 00:00:04 1970 +0000
315 summary: Adding b branch head 2
315 summary: Adding b branch head 2
316
316
317 $ hg heads --active a
317 $ hg heads --active a
318 no open branch heads found on branches a
318 no open branch heads found on branches a
319
319
320 branch b
320 branch b
321
321
322 $ hg heads b
322 $ hg heads b
323 changeset: 13:6ac12926b8c3
323 changeset: 13:6ac12926b8c3
324 branch: b
324 branch: b
325 tag: tip
325 tag: tip
326 user: test
326 user: test
327 date: Thu Jan 01 00:00:09 1970 +0000
327 date: Thu Jan 01 00:00:09 1970 +0000
328 summary: reopen branch with a change
328 summary: reopen branch with a change
329
329
330 $ hg heads --closed b
330 $ hg heads --closed b
331 changeset: 13:6ac12926b8c3
331 changeset: 13:6ac12926b8c3
332 branch: b
332 branch: b
333 tag: tip
333 tag: tip
334 user: test
334 user: test
335 date: Thu Jan 01 00:00:09 1970 +0000
335 date: Thu Jan 01 00:00:09 1970 +0000
336 summary: reopen branch with a change
336 summary: reopen branch with a change
337
337
338 changeset: 11:c84627f3c15d
338 changeset: 11:c84627f3c15d
339 branch: b
339 branch: b
340 user: test
340 user: test
341 date: Thu Jan 01 00:00:09 1970 +0000
341 date: Thu Jan 01 00:00:09 1970 +0000
342 summary: prune bad branch
342 summary: prune bad branch
343
343
344 default branch colors:
345
346 $ echo "[extensions]" >> $HGRCPATH
347 $ echo "color =" >> $HGRCPATH
348
349 $ hg up -C c
350 3 files updated, 0 files merged, 2 files removed, 0 files unresolved
351 $ hg commit -d '9 0' --close-branch -m 'reclosing this branch'
352 $ hg up -C b
353 2 files updated, 0 files merged, 3 files removed, 0 files unresolved
354 $ hg branches --color=always
355 b  13:6ac12926b8c3
356 a branch name much longer than the default justification used by branches 7:10ff5895aa57
357 a  5:d8cbc61dbaa6 (inactive)
358 default  0:19709c5a4e75 (inactive)
359
360 default closed branch color:
361
362 $ hg branches --color=always --closed
363 b  13:6ac12926b8c3
364 a branch name much longer than the default justification used by branches 7:10ff5895aa57
365 c  14:717d2e6fabe1 (closed)
366 a  5:d8cbc61dbaa6 (inactive)
367 default  0:19709c5a4e75 (inactive)
368
369 $ echo "[extensions]" >> $HGRCPATH
370 $ echo "color =" >> $HGRCPATH
371 $ echo "[color]" >> $HGRCPATH
372 $ echo "branches.active = green" >> $HGRCPATH
373 $ echo "branches.closed = blue" >> $HGRCPATH
374 $ echo "branches.current = red" >> $HGRCPATH
375 $ echo "branches.inactive = magenta" >> $HGRCPATH
376 $ echo "log.changeset = cyan" >> $HGRCPATH
377
378 custom branch colors:
379
380 $ hg branches --color=always
381 b  13:6ac12926b8c3
382 a branch name much longer than the default justification used by branches 7:10ff5895aa57
383 a  5:d8cbc61dbaa6 (inactive)
384 default  0:19709c5a4e75 (inactive)
385
386 custom closed branch color:
387
388 $ hg branches --color=always --closed
389 b  13:6ac12926b8c3
390 a branch name much longer than the default justification used by branches 7:10ff5895aa57
391 c  14:717d2e6fabe1 (closed)
392 a  5:d8cbc61dbaa6 (inactive)
393 default  0:19709c5a4e75 (inactive)
General Comments 0
You need to be logged in to leave comments. Login now