##// END OF EJS Templates
phases: add a phases command to display and manipulate phases
Pierre-Yves David -
r15830:8ed112ed default
parent child Browse files
Show More
@@ -1,5703 +1,5756
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, bin, nullid, nullrev, short
8 from node import hex, bin, 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, difflib, time, tempfile, errno
11 import os, re, difflib, time, tempfile, errno
12 import hg, scmutil, util, revlog, extensions, copies, error, bookmarks
12 import hg, scmutil, util, revlog, extensions, copies, error, bookmarks
13 import patch, help, url, encoding, templatekw, discovery
13 import patch, help, url, encoding, templatekw, discovery
14 import archival, changegroup, cmdutil, hbisect
14 import archival, changegroup, cmdutil, hbisect
15 import sshserver, hgweb, hgweb.server, commandserver
15 import sshserver, hgweb, hgweb.server, commandserver
16 import match as matchmod
16 import match as matchmod
17 import merge as mergemod
17 import merge as mergemod
18 import minirst, revset, fileset
18 import minirst, revset, fileset
19 import dagparser, context, simplemerge
19 import dagparser, context, simplemerge
20 import random, setdiscovery, treediscovery, dagutil
20 import random, setdiscovery, treediscovery, dagutil
21 import phases as phasesmod
21
22
22 table = {}
23 table = {}
23
24
24 command = cmdutil.command(table)
25 command = cmdutil.command(table)
25
26
26 # common command options
27 # common command options
27
28
28 globalopts = [
29 globalopts = [
29 ('R', 'repository', '',
30 ('R', 'repository', '',
30 _('repository root directory or name of overlay bundle file'),
31 _('repository root directory or name of overlay bundle file'),
31 _('REPO')),
32 _('REPO')),
32 ('', 'cwd', '',
33 ('', 'cwd', '',
33 _('change working directory'), _('DIR')),
34 _('change working directory'), _('DIR')),
34 ('y', 'noninteractive', None,
35 ('y', 'noninteractive', None,
35 _('do not prompt, automatically pick the first choice for all prompts')),
36 _('do not prompt, automatically pick the first choice for all prompts')),
36 ('q', 'quiet', None, _('suppress output')),
37 ('q', 'quiet', None, _('suppress output')),
37 ('v', 'verbose', None, _('enable additional output')),
38 ('v', 'verbose', None, _('enable additional output')),
38 ('', 'config', [],
39 ('', 'config', [],
39 _('set/override config option (use \'section.name=value\')'),
40 _('set/override config option (use \'section.name=value\')'),
40 _('CONFIG')),
41 _('CONFIG')),
41 ('', 'debug', None, _('enable debugging output')),
42 ('', 'debug', None, _('enable debugging output')),
42 ('', 'debugger', None, _('start debugger')),
43 ('', 'debugger', None, _('start debugger')),
43 ('', 'encoding', encoding.encoding, _('set the charset encoding'),
44 ('', 'encoding', encoding.encoding, _('set the charset encoding'),
44 _('ENCODE')),
45 _('ENCODE')),
45 ('', 'encodingmode', encoding.encodingmode,
46 ('', 'encodingmode', encoding.encodingmode,
46 _('set the charset encoding mode'), _('MODE')),
47 _('set the charset encoding mode'), _('MODE')),
47 ('', 'traceback', None, _('always print a traceback on exception')),
48 ('', 'traceback', None, _('always print a traceback on exception')),
48 ('', 'time', None, _('time how long the command takes')),
49 ('', 'time', None, _('time how long the command takes')),
49 ('', 'profile', None, _('print command execution profile')),
50 ('', 'profile', None, _('print command execution profile')),
50 ('', 'version', None, _('output version information and exit')),
51 ('', 'version', None, _('output version information and exit')),
51 ('h', 'help', None, _('display help and exit')),
52 ('h', 'help', None, _('display help and exit')),
52 ]
53 ]
53
54
54 dryrunopts = [('n', 'dry-run', None,
55 dryrunopts = [('n', 'dry-run', None,
55 _('do not perform actions, just print output'))]
56 _('do not perform actions, just print output'))]
56
57
57 remoteopts = [
58 remoteopts = [
58 ('e', 'ssh', '',
59 ('e', 'ssh', '',
59 _('specify ssh command to use'), _('CMD')),
60 _('specify ssh command to use'), _('CMD')),
60 ('', 'remotecmd', '',
61 ('', 'remotecmd', '',
61 _('specify hg command to run on the remote side'), _('CMD')),
62 _('specify hg command to run on the remote side'), _('CMD')),
62 ('', 'insecure', None,
63 ('', 'insecure', None,
63 _('do not verify server certificate (ignoring web.cacerts config)')),
64 _('do not verify server certificate (ignoring web.cacerts config)')),
64 ]
65 ]
65
66
66 walkopts = [
67 walkopts = [
67 ('I', 'include', [],
68 ('I', 'include', [],
68 _('include names matching the given patterns'), _('PATTERN')),
69 _('include names matching the given patterns'), _('PATTERN')),
69 ('X', 'exclude', [],
70 ('X', 'exclude', [],
70 _('exclude names matching the given patterns'), _('PATTERN')),
71 _('exclude names matching the given patterns'), _('PATTERN')),
71 ]
72 ]
72
73
73 commitopts = [
74 commitopts = [
74 ('m', 'message', '',
75 ('m', 'message', '',
75 _('use text as commit message'), _('TEXT')),
76 _('use text as commit message'), _('TEXT')),
76 ('l', 'logfile', '',
77 ('l', 'logfile', '',
77 _('read commit message from file'), _('FILE')),
78 _('read commit message from file'), _('FILE')),
78 ]
79 ]
79
80
80 commitopts2 = [
81 commitopts2 = [
81 ('d', 'date', '',
82 ('d', 'date', '',
82 _('record the specified date as commit date'), _('DATE')),
83 _('record the specified date as commit date'), _('DATE')),
83 ('u', 'user', '',
84 ('u', 'user', '',
84 _('record the specified user as committer'), _('USER')),
85 _('record the specified user as committer'), _('USER')),
85 ]
86 ]
86
87
87 templateopts = [
88 templateopts = [
88 ('', 'style', '',
89 ('', 'style', '',
89 _('display using template map file'), _('STYLE')),
90 _('display using template map file'), _('STYLE')),
90 ('', 'template', '',
91 ('', 'template', '',
91 _('display with template'), _('TEMPLATE')),
92 _('display with template'), _('TEMPLATE')),
92 ]
93 ]
93
94
94 logopts = [
95 logopts = [
95 ('p', 'patch', None, _('show patch')),
96 ('p', 'patch', None, _('show patch')),
96 ('g', 'git', None, _('use git extended diff format')),
97 ('g', 'git', None, _('use git extended diff format')),
97 ('l', 'limit', '',
98 ('l', 'limit', '',
98 _('limit number of changes displayed'), _('NUM')),
99 _('limit number of changes displayed'), _('NUM')),
99 ('M', 'no-merges', None, _('do not show merges')),
100 ('M', 'no-merges', None, _('do not show merges')),
100 ('', 'stat', None, _('output diffstat-style summary of changes')),
101 ('', 'stat', None, _('output diffstat-style summary of changes')),
101 ] + templateopts
102 ] + templateopts
102
103
103 diffopts = [
104 diffopts = [
104 ('a', 'text', None, _('treat all files as text')),
105 ('a', 'text', None, _('treat all files as text')),
105 ('g', 'git', None, _('use git extended diff format')),
106 ('g', 'git', None, _('use git extended diff format')),
106 ('', 'nodates', None, _('omit dates from diff headers'))
107 ('', 'nodates', None, _('omit dates from diff headers'))
107 ]
108 ]
108
109
109 diffwsopts = [
110 diffwsopts = [
110 ('w', 'ignore-all-space', None,
111 ('w', 'ignore-all-space', None,
111 _('ignore white space when comparing lines')),
112 _('ignore white space when comparing lines')),
112 ('b', 'ignore-space-change', None,
113 ('b', 'ignore-space-change', None,
113 _('ignore changes in the amount of white space')),
114 _('ignore changes in the amount of white space')),
114 ('B', 'ignore-blank-lines', None,
115 ('B', 'ignore-blank-lines', None,
115 _('ignore changes whose lines are all blank')),
116 _('ignore changes whose lines are all blank')),
116 ]
117 ]
117
118
118 diffopts2 = [
119 diffopts2 = [
119 ('p', 'show-function', None, _('show which function each change is in')),
120 ('p', 'show-function', None, _('show which function each change is in')),
120 ('', 'reverse', None, _('produce a diff that undoes the changes')),
121 ('', 'reverse', None, _('produce a diff that undoes the changes')),
121 ] + diffwsopts + [
122 ] + diffwsopts + [
122 ('U', 'unified', '',
123 ('U', 'unified', '',
123 _('number of lines of context to show'), _('NUM')),
124 _('number of lines of context to show'), _('NUM')),
124 ('', 'stat', None, _('output diffstat-style summary of changes')),
125 ('', 'stat', None, _('output diffstat-style summary of changes')),
125 ]
126 ]
126
127
127 mergetoolopts = [
128 mergetoolopts = [
128 ('t', 'tool', '', _('specify merge tool')),
129 ('t', 'tool', '', _('specify merge tool')),
129 ]
130 ]
130
131
131 similarityopts = [
132 similarityopts = [
132 ('s', 'similarity', '',
133 ('s', 'similarity', '',
133 _('guess renamed files by similarity (0<=s<=100)'), _('SIMILARITY'))
134 _('guess renamed files by similarity (0<=s<=100)'), _('SIMILARITY'))
134 ]
135 ]
135
136
136 subrepoopts = [
137 subrepoopts = [
137 ('S', 'subrepos', None,
138 ('S', 'subrepos', None,
138 _('recurse into subrepositories'))
139 _('recurse into subrepositories'))
139 ]
140 ]
140
141
141 # Commands start here, listed alphabetically
142 # Commands start here, listed alphabetically
142
143
143 @command('^add',
144 @command('^add',
144 walkopts + subrepoopts + dryrunopts,
145 walkopts + subrepoopts + dryrunopts,
145 _('[OPTION]... [FILE]...'))
146 _('[OPTION]... [FILE]...'))
146 def add(ui, repo, *pats, **opts):
147 def add(ui, repo, *pats, **opts):
147 """add the specified files on the next commit
148 """add the specified files on the next commit
148
149
149 Schedule files to be version controlled and added to the
150 Schedule files to be version controlled and added to the
150 repository.
151 repository.
151
152
152 The files will be added to the repository at the next commit. To
153 The files will be added to the repository at the next commit. To
153 undo an add before that, see :hg:`forget`.
154 undo an add before that, see :hg:`forget`.
154
155
155 If no names are given, add all files to the repository.
156 If no names are given, add all files to the repository.
156
157
157 .. container:: verbose
158 .. container:: verbose
158
159
159 An example showing how new (unknown) files are added
160 An example showing how new (unknown) files are added
160 automatically by :hg:`add`::
161 automatically by :hg:`add`::
161
162
162 $ ls
163 $ ls
163 foo.c
164 foo.c
164 $ hg status
165 $ hg status
165 ? foo.c
166 ? foo.c
166 $ hg add
167 $ hg add
167 adding foo.c
168 adding foo.c
168 $ hg status
169 $ hg status
169 A foo.c
170 A foo.c
170
171
171 Returns 0 if all files are successfully added.
172 Returns 0 if all files are successfully added.
172 """
173 """
173
174
174 m = scmutil.match(repo[None], pats, opts)
175 m = scmutil.match(repo[None], pats, opts)
175 rejected = cmdutil.add(ui, repo, m, opts.get('dry_run'),
176 rejected = cmdutil.add(ui, repo, m, opts.get('dry_run'),
176 opts.get('subrepos'), prefix="")
177 opts.get('subrepos'), prefix="")
177 return rejected and 1 or 0
178 return rejected and 1 or 0
178
179
179 @command('addremove',
180 @command('addremove',
180 similarityopts + walkopts + dryrunopts,
181 similarityopts + walkopts + dryrunopts,
181 _('[OPTION]... [FILE]...'))
182 _('[OPTION]... [FILE]...'))
182 def addremove(ui, repo, *pats, **opts):
183 def addremove(ui, repo, *pats, **opts):
183 """add all new files, delete all missing files
184 """add all new files, delete all missing files
184
185
185 Add all new files and remove all missing files from the
186 Add all new files and remove all missing files from the
186 repository.
187 repository.
187
188
188 New files are ignored if they match any of the patterns in
189 New files are ignored if they match any of the patterns in
189 ``.hgignore``. As with add, these changes take effect at the next
190 ``.hgignore``. As with add, these changes take effect at the next
190 commit.
191 commit.
191
192
192 Use the -s/--similarity option to detect renamed files. With a
193 Use the -s/--similarity option to detect renamed files. With a
193 parameter greater than 0, this compares every removed file with
194 parameter greater than 0, this compares every removed file with
194 every added file and records those similar enough as renames. This
195 every added file and records those similar enough as renames. This
195 option takes a percentage between 0 (disabled) and 100 (files must
196 option takes a percentage between 0 (disabled) and 100 (files must
196 be identical) as its parameter. Detecting renamed files this way
197 be identical) as its parameter. Detecting renamed files this way
197 can be expensive. After using this option, :hg:`status -C` can be
198 can be expensive. After using this option, :hg:`status -C` can be
198 used to check which files were identified as moved or renamed.
199 used to check which files were identified as moved or renamed.
199
200
200 Returns 0 if all files are successfully added.
201 Returns 0 if all files are successfully added.
201 """
202 """
202 try:
203 try:
203 sim = float(opts.get('similarity') or 100)
204 sim = float(opts.get('similarity') or 100)
204 except ValueError:
205 except ValueError:
205 raise util.Abort(_('similarity must be a number'))
206 raise util.Abort(_('similarity must be a number'))
206 if sim < 0 or sim > 100:
207 if sim < 0 or sim > 100:
207 raise util.Abort(_('similarity must be between 0 and 100'))
208 raise util.Abort(_('similarity must be between 0 and 100'))
208 return scmutil.addremove(repo, pats, opts, similarity=sim / 100.0)
209 return scmutil.addremove(repo, pats, opts, similarity=sim / 100.0)
209
210
210 @command('^annotate|blame',
211 @command('^annotate|blame',
211 [('r', 'rev', '', _('annotate the specified revision'), _('REV')),
212 [('r', 'rev', '', _('annotate the specified revision'), _('REV')),
212 ('', 'follow', None,
213 ('', 'follow', None,
213 _('follow copies/renames and list the filename (DEPRECATED)')),
214 _('follow copies/renames and list the filename (DEPRECATED)')),
214 ('', 'no-follow', None, _("don't follow copies and renames")),
215 ('', 'no-follow', None, _("don't follow copies and renames")),
215 ('a', 'text', None, _('treat all files as text')),
216 ('a', 'text', None, _('treat all files as text')),
216 ('u', 'user', None, _('list the author (long with -v)')),
217 ('u', 'user', None, _('list the author (long with -v)')),
217 ('f', 'file', None, _('list the filename')),
218 ('f', 'file', None, _('list the filename')),
218 ('d', 'date', None, _('list the date (short with -q)')),
219 ('d', 'date', None, _('list the date (short with -q)')),
219 ('n', 'number', None, _('list the revision number (default)')),
220 ('n', 'number', None, _('list the revision number (default)')),
220 ('c', 'changeset', None, _('list the changeset')),
221 ('c', 'changeset', None, _('list the changeset')),
221 ('l', 'line-number', None, _('show line number at the first appearance'))
222 ('l', 'line-number', None, _('show line number at the first appearance'))
222 ] + diffwsopts + walkopts,
223 ] + diffwsopts + walkopts,
223 _('[-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE...'))
224 _('[-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE...'))
224 def annotate(ui, repo, *pats, **opts):
225 def annotate(ui, repo, *pats, **opts):
225 """show changeset information by line for each file
226 """show changeset information by line for each file
226
227
227 List changes in files, showing the revision id responsible for
228 List changes in files, showing the revision id responsible for
228 each line
229 each line
229
230
230 This command is useful for discovering when a change was made and
231 This command is useful for discovering when a change was made and
231 by whom.
232 by whom.
232
233
233 Without the -a/--text option, annotate will avoid processing files
234 Without the -a/--text option, annotate will avoid processing files
234 it detects as binary. With -a, annotate will annotate the file
235 it detects as binary. With -a, annotate will annotate the file
235 anyway, although the results will probably be neither useful
236 anyway, although the results will probably be neither useful
236 nor desirable.
237 nor desirable.
237
238
238 Returns 0 on success.
239 Returns 0 on success.
239 """
240 """
240 if opts.get('follow'):
241 if opts.get('follow'):
241 # --follow is deprecated and now just an alias for -f/--file
242 # --follow is deprecated and now just an alias for -f/--file
242 # to mimic the behavior of Mercurial before version 1.5
243 # to mimic the behavior of Mercurial before version 1.5
243 opts['file'] = True
244 opts['file'] = True
244
245
245 datefunc = ui.quiet and util.shortdate or util.datestr
246 datefunc = ui.quiet and util.shortdate or util.datestr
246 getdate = util.cachefunc(lambda x: datefunc(x[0].date()))
247 getdate = util.cachefunc(lambda x: datefunc(x[0].date()))
247
248
248 if not pats:
249 if not pats:
249 raise util.Abort(_('at least one filename or pattern is required'))
250 raise util.Abort(_('at least one filename or pattern is required'))
250
251
251 hexfn = ui.debugflag and hex or short
252 hexfn = ui.debugflag and hex or short
252
253
253 opmap = [('user', ' ', lambda x: ui.shortuser(x[0].user())),
254 opmap = [('user', ' ', lambda x: ui.shortuser(x[0].user())),
254 ('number', ' ', lambda x: str(x[0].rev())),
255 ('number', ' ', lambda x: str(x[0].rev())),
255 ('changeset', ' ', lambda x: hexfn(x[0].node())),
256 ('changeset', ' ', lambda x: hexfn(x[0].node())),
256 ('date', ' ', getdate),
257 ('date', ' ', getdate),
257 ('file', ' ', lambda x: x[0].path()),
258 ('file', ' ', lambda x: x[0].path()),
258 ('line_number', ':', lambda x: str(x[1])),
259 ('line_number', ':', lambda x: str(x[1])),
259 ]
260 ]
260
261
261 if (not opts.get('user') and not opts.get('changeset')
262 if (not opts.get('user') and not opts.get('changeset')
262 and not opts.get('date') and not opts.get('file')):
263 and not opts.get('date') and not opts.get('file')):
263 opts['number'] = True
264 opts['number'] = True
264
265
265 linenumber = opts.get('line_number') is not None
266 linenumber = opts.get('line_number') is not None
266 if linenumber and (not opts.get('changeset')) and (not opts.get('number')):
267 if linenumber and (not opts.get('changeset')) and (not opts.get('number')):
267 raise util.Abort(_('at least one of -n/-c is required for -l'))
268 raise util.Abort(_('at least one of -n/-c is required for -l'))
268
269
269 funcmap = [(func, sep) for op, sep, func in opmap if opts.get(op)]
270 funcmap = [(func, sep) for op, sep, func in opmap if opts.get(op)]
270 funcmap[0] = (funcmap[0][0], '') # no separator in front of first column
271 funcmap[0] = (funcmap[0][0], '') # no separator in front of first column
271
272
272 def bad(x, y):
273 def bad(x, y):
273 raise util.Abort("%s: %s" % (x, y))
274 raise util.Abort("%s: %s" % (x, y))
274
275
275 ctx = scmutil.revsingle(repo, opts.get('rev'))
276 ctx = scmutil.revsingle(repo, opts.get('rev'))
276 m = scmutil.match(ctx, pats, opts)
277 m = scmutil.match(ctx, pats, opts)
277 m.bad = bad
278 m.bad = bad
278 follow = not opts.get('no_follow')
279 follow = not opts.get('no_follow')
279 diffopts = patch.diffopts(ui, opts, section='annotate')
280 diffopts = patch.diffopts(ui, opts, section='annotate')
280 for abs in ctx.walk(m):
281 for abs in ctx.walk(m):
281 fctx = ctx[abs]
282 fctx = ctx[abs]
282 if not opts.get('text') and util.binary(fctx.data()):
283 if not opts.get('text') and util.binary(fctx.data()):
283 ui.write(_("%s: binary file\n") % ((pats and m.rel(abs)) or abs))
284 ui.write(_("%s: binary file\n") % ((pats and m.rel(abs)) or abs))
284 continue
285 continue
285
286
286 lines = fctx.annotate(follow=follow, linenumber=linenumber,
287 lines = fctx.annotate(follow=follow, linenumber=linenumber,
287 diffopts=diffopts)
288 diffopts=diffopts)
288 pieces = []
289 pieces = []
289
290
290 for f, sep in funcmap:
291 for f, sep in funcmap:
291 l = [f(n) for n, dummy in lines]
292 l = [f(n) for n, dummy in lines]
292 if l:
293 if l:
293 sized = [(x, encoding.colwidth(x)) for x in l]
294 sized = [(x, encoding.colwidth(x)) for x in l]
294 ml = max([w for x, w in sized])
295 ml = max([w for x, w in sized])
295 pieces.append(["%s%s%s" % (sep, ' ' * (ml - w), x)
296 pieces.append(["%s%s%s" % (sep, ' ' * (ml - w), x)
296 for x, w in sized])
297 for x, w in sized])
297
298
298 if pieces:
299 if pieces:
299 for p, l in zip(zip(*pieces), lines):
300 for p, l in zip(zip(*pieces), lines):
300 ui.write("%s: %s" % ("".join(p), l[1]))
301 ui.write("%s: %s" % ("".join(p), l[1]))
301
302
302 if lines and not lines[-1][1].endswith('\n'):
303 if lines and not lines[-1][1].endswith('\n'):
303 ui.write('\n')
304 ui.write('\n')
304
305
305 @command('archive',
306 @command('archive',
306 [('', 'no-decode', None, _('do not pass files through decoders')),
307 [('', 'no-decode', None, _('do not pass files through decoders')),
307 ('p', 'prefix', '', _('directory prefix for files in archive'),
308 ('p', 'prefix', '', _('directory prefix for files in archive'),
308 _('PREFIX')),
309 _('PREFIX')),
309 ('r', 'rev', '', _('revision to distribute'), _('REV')),
310 ('r', 'rev', '', _('revision to distribute'), _('REV')),
310 ('t', 'type', '', _('type of distribution to create'), _('TYPE')),
311 ('t', 'type', '', _('type of distribution to create'), _('TYPE')),
311 ] + subrepoopts + walkopts,
312 ] + subrepoopts + walkopts,
312 _('[OPTION]... DEST'))
313 _('[OPTION]... DEST'))
313 def archive(ui, repo, dest, **opts):
314 def archive(ui, repo, dest, **opts):
314 '''create an unversioned archive of a repository revision
315 '''create an unversioned archive of a repository revision
315
316
316 By default, the revision used is the parent of the working
317 By default, the revision used is the parent of the working
317 directory; use -r/--rev to specify a different revision.
318 directory; use -r/--rev to specify a different revision.
318
319
319 The archive type is automatically detected based on file
320 The archive type is automatically detected based on file
320 extension (or override using -t/--type).
321 extension (or override using -t/--type).
321
322
322 .. container:: verbose
323 .. container:: verbose
323
324
324 Examples:
325 Examples:
325
326
326 - create a zip file containing the 1.0 release::
327 - create a zip file containing the 1.0 release::
327
328
328 hg archive -r 1.0 project-1.0.zip
329 hg archive -r 1.0 project-1.0.zip
329
330
330 - create a tarball excluding .hg files::
331 - create a tarball excluding .hg files::
331
332
332 hg archive project.tar.gz -X ".hg*"
333 hg archive project.tar.gz -X ".hg*"
333
334
334 Valid types are:
335 Valid types are:
335
336
336 :``files``: a directory full of files (default)
337 :``files``: a directory full of files (default)
337 :``tar``: tar archive, uncompressed
338 :``tar``: tar archive, uncompressed
338 :``tbz2``: tar archive, compressed using bzip2
339 :``tbz2``: tar archive, compressed using bzip2
339 :``tgz``: tar archive, compressed using gzip
340 :``tgz``: tar archive, compressed using gzip
340 :``uzip``: zip archive, uncompressed
341 :``uzip``: zip archive, uncompressed
341 :``zip``: zip archive, compressed using deflate
342 :``zip``: zip archive, compressed using deflate
342
343
343 The exact name of the destination archive or directory is given
344 The exact name of the destination archive or directory is given
344 using a format string; see :hg:`help export` for details.
345 using a format string; see :hg:`help export` for details.
345
346
346 Each member added to an archive file has a directory prefix
347 Each member added to an archive file has a directory prefix
347 prepended. Use -p/--prefix to specify a format string for the
348 prepended. Use -p/--prefix to specify a format string for the
348 prefix. The default is the basename of the archive, with suffixes
349 prefix. The default is the basename of the archive, with suffixes
349 removed.
350 removed.
350
351
351 Returns 0 on success.
352 Returns 0 on success.
352 '''
353 '''
353
354
354 ctx = scmutil.revsingle(repo, opts.get('rev'))
355 ctx = scmutil.revsingle(repo, opts.get('rev'))
355 if not ctx:
356 if not ctx:
356 raise util.Abort(_('no working directory: please specify a revision'))
357 raise util.Abort(_('no working directory: please specify a revision'))
357 node = ctx.node()
358 node = ctx.node()
358 dest = cmdutil.makefilename(repo, dest, node)
359 dest = cmdutil.makefilename(repo, dest, node)
359 if os.path.realpath(dest) == repo.root:
360 if os.path.realpath(dest) == repo.root:
360 raise util.Abort(_('repository root cannot be destination'))
361 raise util.Abort(_('repository root cannot be destination'))
361
362
362 kind = opts.get('type') or archival.guesskind(dest) or 'files'
363 kind = opts.get('type') or archival.guesskind(dest) or 'files'
363 prefix = opts.get('prefix')
364 prefix = opts.get('prefix')
364
365
365 if dest == '-':
366 if dest == '-':
366 if kind == 'files':
367 if kind == 'files':
367 raise util.Abort(_('cannot archive plain files to stdout'))
368 raise util.Abort(_('cannot archive plain files to stdout'))
368 dest = cmdutil.makefileobj(repo, dest)
369 dest = cmdutil.makefileobj(repo, dest)
369 if not prefix:
370 if not prefix:
370 prefix = os.path.basename(repo.root) + '-%h'
371 prefix = os.path.basename(repo.root) + '-%h'
371
372
372 prefix = cmdutil.makefilename(repo, prefix, node)
373 prefix = cmdutil.makefilename(repo, prefix, node)
373 matchfn = scmutil.match(ctx, [], opts)
374 matchfn = scmutil.match(ctx, [], opts)
374 archival.archive(repo, dest, node, kind, not opts.get('no_decode'),
375 archival.archive(repo, dest, node, kind, not opts.get('no_decode'),
375 matchfn, prefix, subrepos=opts.get('subrepos'))
376 matchfn, prefix, subrepos=opts.get('subrepos'))
376
377
377 @command('backout',
378 @command('backout',
378 [('', 'merge', None, _('merge with old dirstate parent after backout')),
379 [('', 'merge', None, _('merge with old dirstate parent after backout')),
379 ('', 'parent', '',
380 ('', 'parent', '',
380 _('parent to choose when backing out merge (DEPRECATED)'), _('REV')),
381 _('parent to choose when backing out merge (DEPRECATED)'), _('REV')),
381 ('r', 'rev', '', _('revision to backout'), _('REV')),
382 ('r', 'rev', '', _('revision to backout'), _('REV')),
382 ] + mergetoolopts + walkopts + commitopts + commitopts2,
383 ] + mergetoolopts + walkopts + commitopts + commitopts2,
383 _('[OPTION]... [-r] REV'))
384 _('[OPTION]... [-r] REV'))
384 def backout(ui, repo, node=None, rev=None, **opts):
385 def backout(ui, repo, node=None, rev=None, **opts):
385 '''reverse effect of earlier changeset
386 '''reverse effect of earlier changeset
386
387
387 Prepare a new changeset with the effect of REV undone in the
388 Prepare a new changeset with the effect of REV undone in the
388 current working directory.
389 current working directory.
389
390
390 If REV is the parent of the working directory, then this new changeset
391 If REV is the parent of the working directory, then this new changeset
391 is committed automatically. Otherwise, hg needs to merge the
392 is committed automatically. Otherwise, hg needs to merge the
392 changes and the merged result is left uncommitted.
393 changes and the merged result is left uncommitted.
393
394
394 .. note::
395 .. note::
395 backout cannot be used to fix either an unwanted or
396 backout cannot be used to fix either an unwanted or
396 incorrect merge.
397 incorrect merge.
397
398
398 .. container:: verbose
399 .. container:: verbose
399
400
400 By default, the pending changeset will have one parent,
401 By default, the pending changeset will have one parent,
401 maintaining a linear history. With --merge, the pending
402 maintaining a linear history. With --merge, the pending
402 changeset will instead have two parents: the old parent of the
403 changeset will instead have two parents: the old parent of the
403 working directory and a new child of REV that simply undoes REV.
404 working directory and a new child of REV that simply undoes REV.
404
405
405 Before version 1.7, the behavior without --merge was equivalent
406 Before version 1.7, the behavior without --merge was equivalent
406 to specifying --merge followed by :hg:`update --clean .` to
407 to specifying --merge followed by :hg:`update --clean .` to
407 cancel the merge and leave the child of REV as a head to be
408 cancel the merge and leave the child of REV as a head to be
408 merged separately.
409 merged separately.
409
410
410 See :hg:`help dates` for a list of formats valid for -d/--date.
411 See :hg:`help dates` for a list of formats valid for -d/--date.
411
412
412 Returns 0 on success.
413 Returns 0 on success.
413 '''
414 '''
414 if rev and node:
415 if rev and node:
415 raise util.Abort(_("please specify just one revision"))
416 raise util.Abort(_("please specify just one revision"))
416
417
417 if not rev:
418 if not rev:
418 rev = node
419 rev = node
419
420
420 if not rev:
421 if not rev:
421 raise util.Abort(_("please specify a revision to backout"))
422 raise util.Abort(_("please specify a revision to backout"))
422
423
423 date = opts.get('date')
424 date = opts.get('date')
424 if date:
425 if date:
425 opts['date'] = util.parsedate(date)
426 opts['date'] = util.parsedate(date)
426
427
427 cmdutil.bailifchanged(repo)
428 cmdutil.bailifchanged(repo)
428 node = scmutil.revsingle(repo, rev).node()
429 node = scmutil.revsingle(repo, rev).node()
429
430
430 op1, op2 = repo.dirstate.parents()
431 op1, op2 = repo.dirstate.parents()
431 a = repo.changelog.ancestor(op1, node)
432 a = repo.changelog.ancestor(op1, node)
432 if a != node:
433 if a != node:
433 raise util.Abort(_('cannot backout change on a different branch'))
434 raise util.Abort(_('cannot backout change on a different branch'))
434
435
435 p1, p2 = repo.changelog.parents(node)
436 p1, p2 = repo.changelog.parents(node)
436 if p1 == nullid:
437 if p1 == nullid:
437 raise util.Abort(_('cannot backout a change with no parents'))
438 raise util.Abort(_('cannot backout a change with no parents'))
438 if p2 != nullid:
439 if p2 != nullid:
439 if not opts.get('parent'):
440 if not opts.get('parent'):
440 raise util.Abort(_('cannot backout a merge changeset'))
441 raise util.Abort(_('cannot backout a merge changeset'))
441 p = repo.lookup(opts['parent'])
442 p = repo.lookup(opts['parent'])
442 if p not in (p1, p2):
443 if p not in (p1, p2):
443 raise util.Abort(_('%s is not a parent of %s') %
444 raise util.Abort(_('%s is not a parent of %s') %
444 (short(p), short(node)))
445 (short(p), short(node)))
445 parent = p
446 parent = p
446 else:
447 else:
447 if opts.get('parent'):
448 if opts.get('parent'):
448 raise util.Abort(_('cannot use --parent on non-merge changeset'))
449 raise util.Abort(_('cannot use --parent on non-merge changeset'))
449 parent = p1
450 parent = p1
450
451
451 # the backout should appear on the same branch
452 # the backout should appear on the same branch
452 branch = repo.dirstate.branch()
453 branch = repo.dirstate.branch()
453 hg.clean(repo, node, show_stats=False)
454 hg.clean(repo, node, show_stats=False)
454 repo.dirstate.setbranch(branch)
455 repo.dirstate.setbranch(branch)
455 revert_opts = opts.copy()
456 revert_opts = opts.copy()
456 revert_opts['date'] = None
457 revert_opts['date'] = None
457 revert_opts['all'] = True
458 revert_opts['all'] = True
458 revert_opts['rev'] = hex(parent)
459 revert_opts['rev'] = hex(parent)
459 revert_opts['no_backup'] = None
460 revert_opts['no_backup'] = None
460 revert(ui, repo, **revert_opts)
461 revert(ui, repo, **revert_opts)
461 if not opts.get('merge') and op1 != node:
462 if not opts.get('merge') and op1 != node:
462 try:
463 try:
463 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
464 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
464 return hg.update(repo, op1)
465 return hg.update(repo, op1)
465 finally:
466 finally:
466 ui.setconfig('ui', 'forcemerge', '')
467 ui.setconfig('ui', 'forcemerge', '')
467
468
468 commit_opts = opts.copy()
469 commit_opts = opts.copy()
469 commit_opts['addremove'] = False
470 commit_opts['addremove'] = False
470 if not commit_opts['message'] and not commit_opts['logfile']:
471 if not commit_opts['message'] and not commit_opts['logfile']:
471 # we don't translate commit messages
472 # we don't translate commit messages
472 commit_opts['message'] = "Backed out changeset %s" % short(node)
473 commit_opts['message'] = "Backed out changeset %s" % short(node)
473 commit_opts['force_editor'] = True
474 commit_opts['force_editor'] = True
474 commit(ui, repo, **commit_opts)
475 commit(ui, repo, **commit_opts)
475 def nice(node):
476 def nice(node):
476 return '%d:%s' % (repo.changelog.rev(node), short(node))
477 return '%d:%s' % (repo.changelog.rev(node), short(node))
477 ui.status(_('changeset %s backs out changeset %s\n') %
478 ui.status(_('changeset %s backs out changeset %s\n') %
478 (nice(repo.changelog.tip()), nice(node)))
479 (nice(repo.changelog.tip()), nice(node)))
479 if opts.get('merge') and op1 != node:
480 if opts.get('merge') and op1 != node:
480 hg.clean(repo, op1, show_stats=False)
481 hg.clean(repo, op1, show_stats=False)
481 ui.status(_('merging with changeset %s\n')
482 ui.status(_('merging with changeset %s\n')
482 % nice(repo.changelog.tip()))
483 % nice(repo.changelog.tip()))
483 try:
484 try:
484 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
485 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
485 return hg.merge(repo, hex(repo.changelog.tip()))
486 return hg.merge(repo, hex(repo.changelog.tip()))
486 finally:
487 finally:
487 ui.setconfig('ui', 'forcemerge', '')
488 ui.setconfig('ui', 'forcemerge', '')
488 return 0
489 return 0
489
490
490 @command('bisect',
491 @command('bisect',
491 [('r', 'reset', False, _('reset bisect state')),
492 [('r', 'reset', False, _('reset bisect state')),
492 ('g', 'good', False, _('mark changeset good')),
493 ('g', 'good', False, _('mark changeset good')),
493 ('b', 'bad', False, _('mark changeset bad')),
494 ('b', 'bad', False, _('mark changeset bad')),
494 ('s', 'skip', False, _('skip testing changeset')),
495 ('s', 'skip', False, _('skip testing changeset')),
495 ('e', 'extend', False, _('extend the bisect range')),
496 ('e', 'extend', False, _('extend the bisect range')),
496 ('c', 'command', '', _('use command to check changeset state'), _('CMD')),
497 ('c', 'command', '', _('use command to check changeset state'), _('CMD')),
497 ('U', 'noupdate', False, _('do not update to target'))],
498 ('U', 'noupdate', False, _('do not update to target'))],
498 _("[-gbsr] [-U] [-c CMD] [REV]"))
499 _("[-gbsr] [-U] [-c CMD] [REV]"))
499 def bisect(ui, repo, rev=None, extra=None, command=None,
500 def bisect(ui, repo, rev=None, extra=None, command=None,
500 reset=None, good=None, bad=None, skip=None, extend=None,
501 reset=None, good=None, bad=None, skip=None, extend=None,
501 noupdate=None):
502 noupdate=None):
502 """subdivision search of changesets
503 """subdivision search of changesets
503
504
504 This command helps to find changesets which introduce problems. To
505 This command helps to find changesets which introduce problems. To
505 use, mark the earliest changeset you know exhibits the problem as
506 use, mark the earliest changeset you know exhibits the problem as
506 bad, then mark the latest changeset which is free from the problem
507 bad, then mark the latest changeset which is free from the problem
507 as good. Bisect will update your working directory to a revision
508 as good. Bisect will update your working directory to a revision
508 for testing (unless the -U/--noupdate option is specified). Once
509 for testing (unless the -U/--noupdate option is specified). Once
509 you have performed tests, mark the working directory as good or
510 you have performed tests, mark the working directory as good or
510 bad, and bisect will either update to another candidate changeset
511 bad, and bisect will either update to another candidate changeset
511 or announce that it has found the bad revision.
512 or announce that it has found the bad revision.
512
513
513 As a shortcut, you can also use the revision argument to mark a
514 As a shortcut, you can also use the revision argument to mark a
514 revision as good or bad without checking it out first.
515 revision as good or bad without checking it out first.
515
516
516 If you supply a command, it will be used for automatic bisection.
517 If you supply a command, it will be used for automatic bisection.
517 Its exit status will be used to mark revisions as good or bad:
518 Its exit status will be used to mark revisions as good or bad:
518 status 0 means good, 125 means to skip the revision, 127
519 status 0 means good, 125 means to skip the revision, 127
519 (command not found) will abort the bisection, and any other
520 (command not found) will abort the bisection, and any other
520 non-zero exit status means the revision is bad.
521 non-zero exit status means the revision is bad.
521
522
522 .. container:: verbose
523 .. container:: verbose
523
524
524 Some examples:
525 Some examples:
525
526
526 - start a bisection with known bad revision 12, and good revision 34::
527 - start a bisection with known bad revision 12, and good revision 34::
527
528
528 hg bisect --bad 34
529 hg bisect --bad 34
529 hg bisect --good 12
530 hg bisect --good 12
530
531
531 - advance the current bisection by marking current revision as good or
532 - advance the current bisection by marking current revision as good or
532 bad::
533 bad::
533
534
534 hg bisect --good
535 hg bisect --good
535 hg bisect --bad
536 hg bisect --bad
536
537
537 - mark the current revision, or a known revision, to be skipped (eg. if
538 - mark the current revision, or a known revision, to be skipped (eg. if
538 that revision is not usable because of another issue)::
539 that revision is not usable because of another issue)::
539
540
540 hg bisect --skip
541 hg bisect --skip
541 hg bisect --skip 23
542 hg bisect --skip 23
542
543
543 - forget the current bisection::
544 - forget the current bisection::
544
545
545 hg bisect --reset
546 hg bisect --reset
546
547
547 - use 'make && make tests' to automatically find the first broken
548 - use 'make && make tests' to automatically find the first broken
548 revision::
549 revision::
549
550
550 hg bisect --reset
551 hg bisect --reset
551 hg bisect --bad 34
552 hg bisect --bad 34
552 hg bisect --good 12
553 hg bisect --good 12
553 hg bisect --command 'make && make tests'
554 hg bisect --command 'make && make tests'
554
555
555 - see all changesets whose states are already known in the current
556 - see all changesets whose states are already known in the current
556 bisection::
557 bisection::
557
558
558 hg log -r "bisect(pruned)"
559 hg log -r "bisect(pruned)"
559
560
560 - see all changesets that took part in the current bisection::
561 - see all changesets that took part in the current bisection::
561
562
562 hg log -r "bisect(range)"
563 hg log -r "bisect(range)"
563
564
564 - with the graphlog extension, you can even get a nice graph::
565 - with the graphlog extension, you can even get a nice graph::
565
566
566 hg log --graph -r "bisect(range)"
567 hg log --graph -r "bisect(range)"
567
568
568 See :hg:`help revsets` for more about the `bisect()` keyword.
569 See :hg:`help revsets` for more about the `bisect()` keyword.
569
570
570 Returns 0 on success.
571 Returns 0 on success.
571 """
572 """
572 def extendbisectrange(nodes, good):
573 def extendbisectrange(nodes, good):
573 # bisect is incomplete when it ends on a merge node and
574 # bisect is incomplete when it ends on a merge node and
574 # one of the parent was not checked.
575 # one of the parent was not checked.
575 parents = repo[nodes[0]].parents()
576 parents = repo[nodes[0]].parents()
576 if len(parents) > 1:
577 if len(parents) > 1:
577 side = good and state['bad'] or state['good']
578 side = good and state['bad'] or state['good']
578 num = len(set(i.node() for i in parents) & set(side))
579 num = len(set(i.node() for i in parents) & set(side))
579 if num == 1:
580 if num == 1:
580 return parents[0].ancestor(parents[1])
581 return parents[0].ancestor(parents[1])
581 return None
582 return None
582
583
583 def print_result(nodes, good):
584 def print_result(nodes, good):
584 displayer = cmdutil.show_changeset(ui, repo, {})
585 displayer = cmdutil.show_changeset(ui, repo, {})
585 if len(nodes) == 1:
586 if len(nodes) == 1:
586 # narrowed it down to a single revision
587 # narrowed it down to a single revision
587 if good:
588 if good:
588 ui.write(_("The first good revision is:\n"))
589 ui.write(_("The first good revision is:\n"))
589 else:
590 else:
590 ui.write(_("The first bad revision is:\n"))
591 ui.write(_("The first bad revision is:\n"))
591 displayer.show(repo[nodes[0]])
592 displayer.show(repo[nodes[0]])
592 extendnode = extendbisectrange(nodes, good)
593 extendnode = extendbisectrange(nodes, good)
593 if extendnode is not None:
594 if extendnode is not None:
594 ui.write(_('Not all ancestors of this changeset have been'
595 ui.write(_('Not all ancestors of this changeset have been'
595 ' checked.\nUse bisect --extend to continue the '
596 ' checked.\nUse bisect --extend to continue the '
596 'bisection from\nthe common ancestor, %s.\n')
597 'bisection from\nthe common ancestor, %s.\n')
597 % extendnode)
598 % extendnode)
598 else:
599 else:
599 # multiple possible revisions
600 # multiple possible revisions
600 if good:
601 if good:
601 ui.write(_("Due to skipped revisions, the first "
602 ui.write(_("Due to skipped revisions, the first "
602 "good revision could be any of:\n"))
603 "good revision could be any of:\n"))
603 else:
604 else:
604 ui.write(_("Due to skipped revisions, the first "
605 ui.write(_("Due to skipped revisions, the first "
605 "bad revision could be any of:\n"))
606 "bad revision could be any of:\n"))
606 for n in nodes:
607 for n in nodes:
607 displayer.show(repo[n])
608 displayer.show(repo[n])
608 displayer.close()
609 displayer.close()
609
610
610 def check_state(state, interactive=True):
611 def check_state(state, interactive=True):
611 if not state['good'] or not state['bad']:
612 if not state['good'] or not state['bad']:
612 if (good or bad or skip or reset) and interactive:
613 if (good or bad or skip or reset) and interactive:
613 return
614 return
614 if not state['good']:
615 if not state['good']:
615 raise util.Abort(_('cannot bisect (no known good revisions)'))
616 raise util.Abort(_('cannot bisect (no known good revisions)'))
616 else:
617 else:
617 raise util.Abort(_('cannot bisect (no known bad revisions)'))
618 raise util.Abort(_('cannot bisect (no known bad revisions)'))
618 return True
619 return True
619
620
620 # backward compatibility
621 # backward compatibility
621 if rev in "good bad reset init".split():
622 if rev in "good bad reset init".split():
622 ui.warn(_("(use of 'hg bisect <cmd>' is deprecated)\n"))
623 ui.warn(_("(use of 'hg bisect <cmd>' is deprecated)\n"))
623 cmd, rev, extra = rev, extra, None
624 cmd, rev, extra = rev, extra, None
624 if cmd == "good":
625 if cmd == "good":
625 good = True
626 good = True
626 elif cmd == "bad":
627 elif cmd == "bad":
627 bad = True
628 bad = True
628 else:
629 else:
629 reset = True
630 reset = True
630 elif extra or good + bad + skip + reset + extend + bool(command) > 1:
631 elif extra or good + bad + skip + reset + extend + bool(command) > 1:
631 raise util.Abort(_('incompatible arguments'))
632 raise util.Abort(_('incompatible arguments'))
632
633
633 if reset:
634 if reset:
634 p = repo.join("bisect.state")
635 p = repo.join("bisect.state")
635 if os.path.exists(p):
636 if os.path.exists(p):
636 os.unlink(p)
637 os.unlink(p)
637 return
638 return
638
639
639 state = hbisect.load_state(repo)
640 state = hbisect.load_state(repo)
640
641
641 if command:
642 if command:
642 changesets = 1
643 changesets = 1
643 try:
644 try:
644 while changesets:
645 while changesets:
645 # update state
646 # update state
646 status = util.system(command, out=ui.fout)
647 status = util.system(command, out=ui.fout)
647 if status == 125:
648 if status == 125:
648 transition = "skip"
649 transition = "skip"
649 elif status == 0:
650 elif status == 0:
650 transition = "good"
651 transition = "good"
651 # status < 0 means process was killed
652 # status < 0 means process was killed
652 elif status == 127:
653 elif status == 127:
653 raise util.Abort(_("failed to execute %s") % command)
654 raise util.Abort(_("failed to execute %s") % command)
654 elif status < 0:
655 elif status < 0:
655 raise util.Abort(_("%s killed") % command)
656 raise util.Abort(_("%s killed") % command)
656 else:
657 else:
657 transition = "bad"
658 transition = "bad"
658 ctx = scmutil.revsingle(repo, rev)
659 ctx = scmutil.revsingle(repo, rev)
659 rev = None # clear for future iterations
660 rev = None # clear for future iterations
660 state[transition].append(ctx.node())
661 state[transition].append(ctx.node())
661 ui.status(_('Changeset %d:%s: %s\n') % (ctx, ctx, transition))
662 ui.status(_('Changeset %d:%s: %s\n') % (ctx, ctx, transition))
662 check_state(state, interactive=False)
663 check_state(state, interactive=False)
663 # bisect
664 # bisect
664 nodes, changesets, good = hbisect.bisect(repo.changelog, state)
665 nodes, changesets, good = hbisect.bisect(repo.changelog, state)
665 # update to next check
666 # update to next check
666 cmdutil.bailifchanged(repo)
667 cmdutil.bailifchanged(repo)
667 hg.clean(repo, nodes[0], show_stats=False)
668 hg.clean(repo, nodes[0], show_stats=False)
668 finally:
669 finally:
669 hbisect.save_state(repo, state)
670 hbisect.save_state(repo, state)
670 print_result(nodes, good)
671 print_result(nodes, good)
671 return
672 return
672
673
673 # update state
674 # update state
674
675
675 if rev:
676 if rev:
676 nodes = [repo.lookup(i) for i in scmutil.revrange(repo, [rev])]
677 nodes = [repo.lookup(i) for i in scmutil.revrange(repo, [rev])]
677 else:
678 else:
678 nodes = [repo.lookup('.')]
679 nodes = [repo.lookup('.')]
679
680
680 if good or bad or skip:
681 if good or bad or skip:
681 if good:
682 if good:
682 state['good'] += nodes
683 state['good'] += nodes
683 elif bad:
684 elif bad:
684 state['bad'] += nodes
685 state['bad'] += nodes
685 elif skip:
686 elif skip:
686 state['skip'] += nodes
687 state['skip'] += nodes
687 hbisect.save_state(repo, state)
688 hbisect.save_state(repo, state)
688
689
689 if not check_state(state):
690 if not check_state(state):
690 return
691 return
691
692
692 # actually bisect
693 # actually bisect
693 nodes, changesets, good = hbisect.bisect(repo.changelog, state)
694 nodes, changesets, good = hbisect.bisect(repo.changelog, state)
694 if extend:
695 if extend:
695 if not changesets:
696 if not changesets:
696 extendnode = extendbisectrange(nodes, good)
697 extendnode = extendbisectrange(nodes, good)
697 if extendnode is not None:
698 if extendnode is not None:
698 ui.write(_("Extending search to changeset %d:%s\n"
699 ui.write(_("Extending search to changeset %d:%s\n"
699 % (extendnode.rev(), extendnode)))
700 % (extendnode.rev(), extendnode)))
700 if noupdate:
701 if noupdate:
701 return
702 return
702 cmdutil.bailifchanged(repo)
703 cmdutil.bailifchanged(repo)
703 return hg.clean(repo, extendnode.node())
704 return hg.clean(repo, extendnode.node())
704 raise util.Abort(_("nothing to extend"))
705 raise util.Abort(_("nothing to extend"))
705
706
706 if changesets == 0:
707 if changesets == 0:
707 print_result(nodes, good)
708 print_result(nodes, good)
708 else:
709 else:
709 assert len(nodes) == 1 # only a single node can be tested next
710 assert len(nodes) == 1 # only a single node can be tested next
710 node = nodes[0]
711 node = nodes[0]
711 # compute the approximate number of remaining tests
712 # compute the approximate number of remaining tests
712 tests, size = 0, 2
713 tests, size = 0, 2
713 while size <= changesets:
714 while size <= changesets:
714 tests, size = tests + 1, size * 2
715 tests, size = tests + 1, size * 2
715 rev = repo.changelog.rev(node)
716 rev = repo.changelog.rev(node)
716 ui.write(_("Testing changeset %d:%s "
717 ui.write(_("Testing changeset %d:%s "
717 "(%d changesets remaining, ~%d tests)\n")
718 "(%d changesets remaining, ~%d tests)\n")
718 % (rev, short(node), changesets, tests))
719 % (rev, short(node), changesets, tests))
719 if not noupdate:
720 if not noupdate:
720 cmdutil.bailifchanged(repo)
721 cmdutil.bailifchanged(repo)
721 return hg.clean(repo, node)
722 return hg.clean(repo, node)
722
723
723 @command('bookmarks',
724 @command('bookmarks',
724 [('f', 'force', False, _('force')),
725 [('f', 'force', False, _('force')),
725 ('r', 'rev', '', _('revision'), _('REV')),
726 ('r', 'rev', '', _('revision'), _('REV')),
726 ('d', 'delete', False, _('delete a given bookmark')),
727 ('d', 'delete', False, _('delete a given bookmark')),
727 ('m', 'rename', '', _('rename a given bookmark'), _('NAME')),
728 ('m', 'rename', '', _('rename a given bookmark'), _('NAME')),
728 ('i', 'inactive', False, _('do not mark a new bookmark active'))],
729 ('i', 'inactive', False, _('do not mark a new bookmark active'))],
729 _('hg bookmarks [-f] [-d] [-i] [-m NAME] [-r REV] [NAME]'))
730 _('hg bookmarks [-f] [-d] [-i] [-m NAME] [-r REV] [NAME]'))
730 def bookmark(ui, repo, mark=None, rev=None, force=False, delete=False,
731 def bookmark(ui, repo, mark=None, rev=None, force=False, delete=False,
731 rename=None, inactive=False):
732 rename=None, inactive=False):
732 '''track a line of development with movable markers
733 '''track a line of development with movable markers
733
734
734 Bookmarks are pointers to certain commits that move when committing.
735 Bookmarks are pointers to certain commits that move when committing.
735 Bookmarks are local. They can be renamed, copied and deleted. It is
736 Bookmarks are local. They can be renamed, copied and deleted. It is
736 possible to use :hg:`merge NAME` to merge from a given bookmark, and
737 possible to use :hg:`merge NAME` to merge from a given bookmark, and
737 :hg:`update NAME` to update to a given bookmark.
738 :hg:`update NAME` to update to a given bookmark.
738
739
739 You can use :hg:`bookmark NAME` to set a bookmark on the working
740 You can use :hg:`bookmark NAME` to set a bookmark on the working
740 directory's parent revision with the given name. If you specify
741 directory's parent revision with the given name. If you specify
741 a revision using -r REV (where REV may be an existing bookmark),
742 a revision using -r REV (where REV may be an existing bookmark),
742 the bookmark is assigned to that revision.
743 the bookmark is assigned to that revision.
743
744
744 Bookmarks can be pushed and pulled between repositories (see :hg:`help
745 Bookmarks can be pushed and pulled between repositories (see :hg:`help
745 push` and :hg:`help pull`). This requires both the local and remote
746 push` and :hg:`help pull`). This requires both the local and remote
746 repositories to support bookmarks. For versions prior to 1.8, this means
747 repositories to support bookmarks. For versions prior to 1.8, this means
747 the bookmarks extension must be enabled.
748 the bookmarks extension must be enabled.
748 '''
749 '''
749 hexfn = ui.debugflag and hex or short
750 hexfn = ui.debugflag and hex or short
750 marks = repo._bookmarks
751 marks = repo._bookmarks
751 cur = repo.changectx('.').node()
752 cur = repo.changectx('.').node()
752
753
753 if delete:
754 if delete:
754 if mark is None:
755 if mark is None:
755 raise util.Abort(_("bookmark name required"))
756 raise util.Abort(_("bookmark name required"))
756 if mark not in marks:
757 if mark not in marks:
757 raise util.Abort(_("bookmark '%s' does not exist") % mark)
758 raise util.Abort(_("bookmark '%s' does not exist") % mark)
758 if mark == repo._bookmarkcurrent:
759 if mark == repo._bookmarkcurrent:
759 bookmarks.setcurrent(repo, None)
760 bookmarks.setcurrent(repo, None)
760 del marks[mark]
761 del marks[mark]
761 bookmarks.write(repo)
762 bookmarks.write(repo)
762 return
763 return
763
764
764 if rename:
765 if rename:
765 if rename not in marks:
766 if rename not in marks:
766 raise util.Abort(_("bookmark '%s' does not exist") % rename)
767 raise util.Abort(_("bookmark '%s' does not exist") % rename)
767 if mark in marks and not force:
768 if mark in marks and not force:
768 raise util.Abort(_("bookmark '%s' already exists "
769 raise util.Abort(_("bookmark '%s' already exists "
769 "(use -f to force)") % mark)
770 "(use -f to force)") % mark)
770 if mark is None:
771 if mark is None:
771 raise util.Abort(_("new bookmark name required"))
772 raise util.Abort(_("new bookmark name required"))
772 marks[mark] = marks[rename]
773 marks[mark] = marks[rename]
773 if repo._bookmarkcurrent == rename and not inactive:
774 if repo._bookmarkcurrent == rename and not inactive:
774 bookmarks.setcurrent(repo, mark)
775 bookmarks.setcurrent(repo, mark)
775 del marks[rename]
776 del marks[rename]
776 bookmarks.write(repo)
777 bookmarks.write(repo)
777 return
778 return
778
779
779 if mark is not None:
780 if mark is not None:
780 if "\n" in mark:
781 if "\n" in mark:
781 raise util.Abort(_("bookmark name cannot contain newlines"))
782 raise util.Abort(_("bookmark name cannot contain newlines"))
782 mark = mark.strip()
783 mark = mark.strip()
783 if not mark:
784 if not mark:
784 raise util.Abort(_("bookmark names cannot consist entirely of "
785 raise util.Abort(_("bookmark names cannot consist entirely of "
785 "whitespace"))
786 "whitespace"))
786 if inactive and mark == repo._bookmarkcurrent:
787 if inactive and mark == repo._bookmarkcurrent:
787 bookmarks.setcurrent(repo, None)
788 bookmarks.setcurrent(repo, None)
788 return
789 return
789 if mark in marks and not force:
790 if mark in marks and not force:
790 raise util.Abort(_("bookmark '%s' already exists "
791 raise util.Abort(_("bookmark '%s' already exists "
791 "(use -f to force)") % mark)
792 "(use -f to force)") % mark)
792 if ((mark in repo.branchtags() or mark == repo.dirstate.branch())
793 if ((mark in repo.branchtags() or mark == repo.dirstate.branch())
793 and not force):
794 and not force):
794 raise util.Abort(
795 raise util.Abort(
795 _("a bookmark cannot have the name of an existing branch"))
796 _("a bookmark cannot have the name of an existing branch"))
796 if rev:
797 if rev:
797 marks[mark] = repo.lookup(rev)
798 marks[mark] = repo.lookup(rev)
798 else:
799 else:
799 marks[mark] = cur
800 marks[mark] = cur
800 if not inactive and cur == marks[mark]:
801 if not inactive and cur == marks[mark]:
801 bookmarks.setcurrent(repo, mark)
802 bookmarks.setcurrent(repo, mark)
802 bookmarks.write(repo)
803 bookmarks.write(repo)
803 return
804 return
804
805
805 if mark is None:
806 if mark is None:
806 if rev:
807 if rev:
807 raise util.Abort(_("bookmark name required"))
808 raise util.Abort(_("bookmark name required"))
808 if len(marks) == 0:
809 if len(marks) == 0:
809 ui.status(_("no bookmarks set\n"))
810 ui.status(_("no bookmarks set\n"))
810 else:
811 else:
811 for bmark, n in sorted(marks.iteritems()):
812 for bmark, n in sorted(marks.iteritems()):
812 current = repo._bookmarkcurrent
813 current = repo._bookmarkcurrent
813 if bmark == current and n == cur:
814 if bmark == current and n == cur:
814 prefix, label = '*', 'bookmarks.current'
815 prefix, label = '*', 'bookmarks.current'
815 else:
816 else:
816 prefix, label = ' ', ''
817 prefix, label = ' ', ''
817
818
818 if ui.quiet:
819 if ui.quiet:
819 ui.write("%s\n" % bmark, label=label)
820 ui.write("%s\n" % bmark, label=label)
820 else:
821 else:
821 ui.write(" %s %-25s %d:%s\n" % (
822 ui.write(" %s %-25s %d:%s\n" % (
822 prefix, bmark, repo.changelog.rev(n), hexfn(n)),
823 prefix, bmark, repo.changelog.rev(n), hexfn(n)),
823 label=label)
824 label=label)
824 return
825 return
825
826
826 @command('branch',
827 @command('branch',
827 [('f', 'force', None,
828 [('f', 'force', None,
828 _('set branch name even if it shadows an existing branch')),
829 _('set branch name even if it shadows an existing branch')),
829 ('C', 'clean', None, _('reset branch name to parent branch name'))],
830 ('C', 'clean', None, _('reset branch name to parent branch name'))],
830 _('[-fC] [NAME]'))
831 _('[-fC] [NAME]'))
831 def branch(ui, repo, label=None, **opts):
832 def branch(ui, repo, label=None, **opts):
832 """set or show the current branch name
833 """set or show the current branch name
833
834
834 .. note::
835 .. note::
835 Branch names are permanent and global. Use :hg:`bookmark` to create a
836 Branch names are permanent and global. Use :hg:`bookmark` to create a
836 light-weight bookmark instead. See :hg:`help glossary` for more
837 light-weight bookmark instead. See :hg:`help glossary` for more
837 information about named branches and bookmarks.
838 information about named branches and bookmarks.
838
839
839 With no argument, show the current branch name. With one argument,
840 With no argument, show the current branch name. With one argument,
840 set the working directory branch name (the branch will not exist
841 set the working directory branch name (the branch will not exist
841 in the repository until the next commit). Standard practice
842 in the repository until the next commit). Standard practice
842 recommends that primary development take place on the 'default'
843 recommends that primary development take place on the 'default'
843 branch.
844 branch.
844
845
845 Unless -f/--force is specified, branch will not let you set a
846 Unless -f/--force is specified, branch will not let you set a
846 branch name that already exists, even if it's inactive.
847 branch name that already exists, even if it's inactive.
847
848
848 Use -C/--clean to reset the working directory branch to that of
849 Use -C/--clean to reset the working directory branch to that of
849 the parent of the working directory, negating a previous branch
850 the parent of the working directory, negating a previous branch
850 change.
851 change.
851
852
852 Use the command :hg:`update` to switch to an existing branch. Use
853 Use the command :hg:`update` to switch to an existing branch. Use
853 :hg:`commit --close-branch` to mark this branch as closed.
854 :hg:`commit --close-branch` to mark this branch as closed.
854
855
855 Returns 0 on success.
856 Returns 0 on success.
856 """
857 """
857
858
858 if opts.get('clean'):
859 if opts.get('clean'):
859 label = repo[None].p1().branch()
860 label = repo[None].p1().branch()
860 repo.dirstate.setbranch(label)
861 repo.dirstate.setbranch(label)
861 ui.status(_('reset working directory to branch %s\n') % label)
862 ui.status(_('reset working directory to branch %s\n') % label)
862 elif label:
863 elif label:
863 if not opts.get('force') and label in repo.branchtags():
864 if not opts.get('force') and label in repo.branchtags():
864 if label not in [p.branch() for p in repo.parents()]:
865 if label not in [p.branch() for p in repo.parents()]:
865 raise util.Abort(_('a branch of the same name already exists'),
866 raise util.Abort(_('a branch of the same name already exists'),
866 # i18n: "it" refers to an existing branch
867 # i18n: "it" refers to an existing branch
867 hint=_("use 'hg update' to switch to it"))
868 hint=_("use 'hg update' to switch to it"))
868 repo.dirstate.setbranch(label)
869 repo.dirstate.setbranch(label)
869 ui.status(_('marked working directory as branch %s\n') % label)
870 ui.status(_('marked working directory as branch %s\n') % label)
870 ui.status(_('(branches are permanent and global, '
871 ui.status(_('(branches are permanent and global, '
871 'did you want a bookmark?)\n'))
872 'did you want a bookmark?)\n'))
872 else:
873 else:
873 ui.write("%s\n" % repo.dirstate.branch())
874 ui.write("%s\n" % repo.dirstate.branch())
874
875
875 @command('branches',
876 @command('branches',
876 [('a', 'active', False, _('show only branches that have unmerged heads')),
877 [('a', 'active', False, _('show only branches that have unmerged heads')),
877 ('c', 'closed', False, _('show normal and closed branches'))],
878 ('c', 'closed', False, _('show normal and closed branches'))],
878 _('[-ac]'))
879 _('[-ac]'))
879 def branches(ui, repo, active=False, closed=False):
880 def branches(ui, repo, active=False, closed=False):
880 """list repository named branches
881 """list repository named branches
881
882
882 List the repository's named branches, indicating which ones are
883 List the repository's named branches, indicating which ones are
883 inactive. If -c/--closed is specified, also list branches which have
884 inactive. If -c/--closed is specified, also list branches which have
884 been marked closed (see :hg:`commit --close-branch`).
885 been marked closed (see :hg:`commit --close-branch`).
885
886
886 If -a/--active is specified, only show active branches. A branch
887 If -a/--active is specified, only show active branches. A branch
887 is considered active if it contains repository heads.
888 is considered active if it contains repository heads.
888
889
889 Use the command :hg:`update` to switch to an existing branch.
890 Use the command :hg:`update` to switch to an existing branch.
890
891
891 Returns 0.
892 Returns 0.
892 """
893 """
893
894
894 hexfunc = ui.debugflag and hex or short
895 hexfunc = ui.debugflag and hex or short
895 activebranches = [repo[n].branch() for n in repo.heads()]
896 activebranches = [repo[n].branch() for n in repo.heads()]
896 def testactive(tag, node):
897 def testactive(tag, node):
897 realhead = tag in activebranches
898 realhead = tag in activebranches
898 open = node in repo.branchheads(tag, closed=False)
899 open = node in repo.branchheads(tag, closed=False)
899 return realhead and open
900 return realhead and open
900 branches = sorted([(testactive(tag, node), repo.changelog.rev(node), tag)
901 branches = sorted([(testactive(tag, node), repo.changelog.rev(node), tag)
901 for tag, node in repo.branchtags().items()],
902 for tag, node in repo.branchtags().items()],
902 reverse=True)
903 reverse=True)
903
904
904 for isactive, node, tag in branches:
905 for isactive, node, tag in branches:
905 if (not active) or isactive:
906 if (not active) or isactive:
906 if ui.quiet:
907 if ui.quiet:
907 ui.write("%s\n" % tag)
908 ui.write("%s\n" % tag)
908 else:
909 else:
909 hn = repo.lookup(node)
910 hn = repo.lookup(node)
910 if isactive:
911 if isactive:
911 label = 'branches.active'
912 label = 'branches.active'
912 notice = ''
913 notice = ''
913 elif hn not in repo.branchheads(tag, closed=False):
914 elif hn not in repo.branchheads(tag, closed=False):
914 if not closed:
915 if not closed:
915 continue
916 continue
916 label = 'branches.closed'
917 label = 'branches.closed'
917 notice = _(' (closed)')
918 notice = _(' (closed)')
918 else:
919 else:
919 label = 'branches.inactive'
920 label = 'branches.inactive'
920 notice = _(' (inactive)')
921 notice = _(' (inactive)')
921 if tag == repo.dirstate.branch():
922 if tag == repo.dirstate.branch():
922 label = 'branches.current'
923 label = 'branches.current'
923 rev = str(node).rjust(31 - encoding.colwidth(tag))
924 rev = str(node).rjust(31 - encoding.colwidth(tag))
924 rev = ui.label('%s:%s' % (rev, hexfunc(hn)), 'log.changeset')
925 rev = ui.label('%s:%s' % (rev, hexfunc(hn)), 'log.changeset')
925 tag = ui.label(tag, label)
926 tag = ui.label(tag, label)
926 ui.write("%s %s%s\n" % (tag, rev, notice))
927 ui.write("%s %s%s\n" % (tag, rev, notice))
927
928
928 @command('bundle',
929 @command('bundle',
929 [('f', 'force', None, _('run even when the destination is unrelated')),
930 [('f', 'force', None, _('run even when the destination is unrelated')),
930 ('r', 'rev', [], _('a changeset intended to be added to the destination'),
931 ('r', 'rev', [], _('a changeset intended to be added to the destination'),
931 _('REV')),
932 _('REV')),
932 ('b', 'branch', [], _('a specific branch you would like to bundle'),
933 ('b', 'branch', [], _('a specific branch you would like to bundle'),
933 _('BRANCH')),
934 _('BRANCH')),
934 ('', 'base', [],
935 ('', 'base', [],
935 _('a base changeset assumed to be available at the destination'),
936 _('a base changeset assumed to be available at the destination'),
936 _('REV')),
937 _('REV')),
937 ('a', 'all', None, _('bundle all changesets in the repository')),
938 ('a', 'all', None, _('bundle all changesets in the repository')),
938 ('t', 'type', 'bzip2', _('bundle compression type to use'), _('TYPE')),
939 ('t', 'type', 'bzip2', _('bundle compression type to use'), _('TYPE')),
939 ] + remoteopts,
940 ] + remoteopts,
940 _('[-f] [-t TYPE] [-a] [-r REV]... [--base REV]... FILE [DEST]'))
941 _('[-f] [-t TYPE] [-a] [-r REV]... [--base REV]... FILE [DEST]'))
941 def bundle(ui, repo, fname, dest=None, **opts):
942 def bundle(ui, repo, fname, dest=None, **opts):
942 """create a changegroup file
943 """create a changegroup file
943
944
944 Generate a compressed changegroup file collecting changesets not
945 Generate a compressed changegroup file collecting changesets not
945 known to be in another repository.
946 known to be in another repository.
946
947
947 If you omit the destination repository, then hg assumes the
948 If you omit the destination repository, then hg assumes the
948 destination will have all the nodes you specify with --base
949 destination will have all the nodes you specify with --base
949 parameters. To create a bundle containing all changesets, use
950 parameters. To create a bundle containing all changesets, use
950 -a/--all (or --base null).
951 -a/--all (or --base null).
951
952
952 You can change compression method with the -t/--type option.
953 You can change compression method with the -t/--type option.
953 The available compression methods are: none, bzip2, and
954 The available compression methods are: none, bzip2, and
954 gzip (by default, bundles are compressed using bzip2).
955 gzip (by default, bundles are compressed using bzip2).
955
956
956 The bundle file can then be transferred using conventional means
957 The bundle file can then be transferred using conventional means
957 and applied to another repository with the unbundle or pull
958 and applied to another repository with the unbundle or pull
958 command. This is useful when direct push and pull are not
959 command. This is useful when direct push and pull are not
959 available or when exporting an entire repository is undesirable.
960 available or when exporting an entire repository is undesirable.
960
961
961 Applying bundles preserves all changeset contents including
962 Applying bundles preserves all changeset contents including
962 permissions, copy/rename information, and revision history.
963 permissions, copy/rename information, and revision history.
963
964
964 Returns 0 on success, 1 if no changes found.
965 Returns 0 on success, 1 if no changes found.
965 """
966 """
966 revs = None
967 revs = None
967 if 'rev' in opts:
968 if 'rev' in opts:
968 revs = scmutil.revrange(repo, opts['rev'])
969 revs = scmutil.revrange(repo, opts['rev'])
969
970
970 if opts.get('all'):
971 if opts.get('all'):
971 base = ['null']
972 base = ['null']
972 else:
973 else:
973 base = scmutil.revrange(repo, opts.get('base'))
974 base = scmutil.revrange(repo, opts.get('base'))
974 if base:
975 if base:
975 if dest:
976 if dest:
976 raise util.Abort(_("--base is incompatible with specifying "
977 raise util.Abort(_("--base is incompatible with specifying "
977 "a destination"))
978 "a destination"))
978 common = [repo.lookup(rev) for rev in base]
979 common = [repo.lookup(rev) for rev in base]
979 heads = revs and map(repo.lookup, revs) or revs
980 heads = revs and map(repo.lookup, revs) or revs
980 else:
981 else:
981 dest = ui.expandpath(dest or 'default-push', dest or 'default')
982 dest = ui.expandpath(dest or 'default-push', dest or 'default')
982 dest, branches = hg.parseurl(dest, opts.get('branch'))
983 dest, branches = hg.parseurl(dest, opts.get('branch'))
983 other = hg.peer(repo, opts, dest)
984 other = hg.peer(repo, opts, dest)
984 revs, checkout = hg.addbranchrevs(repo, other, branches, revs)
985 revs, checkout = hg.addbranchrevs(repo, other, branches, revs)
985 heads = revs and map(repo.lookup, revs) or revs
986 heads = revs and map(repo.lookup, revs) or revs
986 common, outheads = discovery.findcommonoutgoing(repo, other,
987 common, outheads = discovery.findcommonoutgoing(repo, other,
987 onlyheads=heads,
988 onlyheads=heads,
988 force=opts.get('force'))
989 force=opts.get('force'))
989
990
990 cg = repo.getbundle('bundle', common=common, heads=heads)
991 cg = repo.getbundle('bundle', common=common, heads=heads)
991 if not cg:
992 if not cg:
992 ui.status(_("no changes found\n"))
993 ui.status(_("no changes found\n"))
993 return 1
994 return 1
994
995
995 bundletype = opts.get('type', 'bzip2').lower()
996 bundletype = opts.get('type', 'bzip2').lower()
996 btypes = {'none': 'HG10UN', 'bzip2': 'HG10BZ', 'gzip': 'HG10GZ'}
997 btypes = {'none': 'HG10UN', 'bzip2': 'HG10BZ', 'gzip': 'HG10GZ'}
997 bundletype = btypes.get(bundletype)
998 bundletype = btypes.get(bundletype)
998 if bundletype not in changegroup.bundletypes:
999 if bundletype not in changegroup.bundletypes:
999 raise util.Abort(_('unknown bundle type specified with --type'))
1000 raise util.Abort(_('unknown bundle type specified with --type'))
1000
1001
1001 changegroup.writebundle(cg, fname, bundletype)
1002 changegroup.writebundle(cg, fname, bundletype)
1002
1003
1003 @command('cat',
1004 @command('cat',
1004 [('o', 'output', '',
1005 [('o', 'output', '',
1005 _('print output to file with formatted name'), _('FORMAT')),
1006 _('print output to file with formatted name'), _('FORMAT')),
1006 ('r', 'rev', '', _('print the given revision'), _('REV')),
1007 ('r', 'rev', '', _('print the given revision'), _('REV')),
1007 ('', 'decode', None, _('apply any matching decode filter')),
1008 ('', 'decode', None, _('apply any matching decode filter')),
1008 ] + walkopts,
1009 ] + walkopts,
1009 _('[OPTION]... FILE...'))
1010 _('[OPTION]... FILE...'))
1010 def cat(ui, repo, file1, *pats, **opts):
1011 def cat(ui, repo, file1, *pats, **opts):
1011 """output the current or given revision of files
1012 """output the current or given revision of files
1012
1013
1013 Print the specified files as they were at the given revision. If
1014 Print the specified files as they were at the given revision. If
1014 no revision is given, the parent of the working directory is used,
1015 no revision is given, the parent of the working directory is used,
1015 or tip if no revision is checked out.
1016 or tip if no revision is checked out.
1016
1017
1017 Output may be to a file, in which case the name of the file is
1018 Output may be to a file, in which case the name of the file is
1018 given using a format string. The formatting rules are the same as
1019 given using a format string. The formatting rules are the same as
1019 for the export command, with the following additions:
1020 for the export command, with the following additions:
1020
1021
1021 :``%s``: basename of file being printed
1022 :``%s``: basename of file being printed
1022 :``%d``: dirname of file being printed, or '.' if in repository root
1023 :``%d``: dirname of file being printed, or '.' if in repository root
1023 :``%p``: root-relative path name of file being printed
1024 :``%p``: root-relative path name of file being printed
1024
1025
1025 Returns 0 on success.
1026 Returns 0 on success.
1026 """
1027 """
1027 ctx = scmutil.revsingle(repo, opts.get('rev'))
1028 ctx = scmutil.revsingle(repo, opts.get('rev'))
1028 err = 1
1029 err = 1
1029 m = scmutil.match(ctx, (file1,) + pats, opts)
1030 m = scmutil.match(ctx, (file1,) + pats, opts)
1030 for abs in ctx.walk(m):
1031 for abs in ctx.walk(m):
1031 fp = cmdutil.makefileobj(repo, opts.get('output'), ctx.node(),
1032 fp = cmdutil.makefileobj(repo, opts.get('output'), ctx.node(),
1032 pathname=abs)
1033 pathname=abs)
1033 data = ctx[abs].data()
1034 data = ctx[abs].data()
1034 if opts.get('decode'):
1035 if opts.get('decode'):
1035 data = repo.wwritedata(abs, data)
1036 data = repo.wwritedata(abs, data)
1036 fp.write(data)
1037 fp.write(data)
1037 fp.close()
1038 fp.close()
1038 err = 0
1039 err = 0
1039 return err
1040 return err
1040
1041
1041 @command('^clone',
1042 @command('^clone',
1042 [('U', 'noupdate', None,
1043 [('U', 'noupdate', None,
1043 _('the clone will include an empty working copy (only a repository)')),
1044 _('the clone will include an empty working copy (only a repository)')),
1044 ('u', 'updaterev', '', _('revision, tag or branch to check out'), _('REV')),
1045 ('u', 'updaterev', '', _('revision, tag or branch to check out'), _('REV')),
1045 ('r', 'rev', [], _('include the specified changeset'), _('REV')),
1046 ('r', 'rev', [], _('include the specified changeset'), _('REV')),
1046 ('b', 'branch', [], _('clone only the specified branch'), _('BRANCH')),
1047 ('b', 'branch', [], _('clone only the specified branch'), _('BRANCH')),
1047 ('', 'pull', None, _('use pull protocol to copy metadata')),
1048 ('', 'pull', None, _('use pull protocol to copy metadata')),
1048 ('', 'uncompressed', None, _('use uncompressed transfer (fast over LAN)')),
1049 ('', 'uncompressed', None, _('use uncompressed transfer (fast over LAN)')),
1049 ] + remoteopts,
1050 ] + remoteopts,
1050 _('[OPTION]... SOURCE [DEST]'))
1051 _('[OPTION]... SOURCE [DEST]'))
1051 def clone(ui, source, dest=None, **opts):
1052 def clone(ui, source, dest=None, **opts):
1052 """make a copy of an existing repository
1053 """make a copy of an existing repository
1053
1054
1054 Create a copy of an existing repository in a new directory.
1055 Create a copy of an existing repository in a new directory.
1055
1056
1056 If no destination directory name is specified, it defaults to the
1057 If no destination directory name is specified, it defaults to the
1057 basename of the source.
1058 basename of the source.
1058
1059
1059 The location of the source is added to the new repository's
1060 The location of the source is added to the new repository's
1060 ``.hg/hgrc`` file, as the default to be used for future pulls.
1061 ``.hg/hgrc`` file, as the default to be used for future pulls.
1061
1062
1062 Only local paths and ``ssh://`` URLs are supported as
1063 Only local paths and ``ssh://`` URLs are supported as
1063 destinations. For ``ssh://`` destinations, no working directory or
1064 destinations. For ``ssh://`` destinations, no working directory or
1064 ``.hg/hgrc`` will be created on the remote side.
1065 ``.hg/hgrc`` will be created on the remote side.
1065
1066
1066 To pull only a subset of changesets, specify one or more revisions
1067 To pull only a subset of changesets, specify one or more revisions
1067 identifiers with -r/--rev or branches with -b/--branch. The
1068 identifiers with -r/--rev or branches with -b/--branch. The
1068 resulting clone will contain only the specified changesets and
1069 resulting clone will contain only the specified changesets and
1069 their ancestors. These options (or 'clone src#rev dest') imply
1070 their ancestors. These options (or 'clone src#rev dest') imply
1070 --pull, even for local source repositories. Note that specifying a
1071 --pull, even for local source repositories. Note that specifying a
1071 tag will include the tagged changeset but not the changeset
1072 tag will include the tagged changeset but not the changeset
1072 containing the tag.
1073 containing the tag.
1073
1074
1074 To check out a particular version, use -u/--update, or
1075 To check out a particular version, use -u/--update, or
1075 -U/--noupdate to create a clone with no working directory.
1076 -U/--noupdate to create a clone with no working directory.
1076
1077
1077 .. container:: verbose
1078 .. container:: verbose
1078
1079
1079 For efficiency, hardlinks are used for cloning whenever the
1080 For efficiency, hardlinks are used for cloning whenever the
1080 source and destination are on the same filesystem (note this
1081 source and destination are on the same filesystem (note this
1081 applies only to the repository data, not to the working
1082 applies only to the repository data, not to the working
1082 directory). Some filesystems, such as AFS, implement hardlinking
1083 directory). Some filesystems, such as AFS, implement hardlinking
1083 incorrectly, but do not report errors. In these cases, use the
1084 incorrectly, but do not report errors. In these cases, use the
1084 --pull option to avoid hardlinking.
1085 --pull option to avoid hardlinking.
1085
1086
1086 In some cases, you can clone repositories and the working
1087 In some cases, you can clone repositories and the working
1087 directory using full hardlinks with ::
1088 directory using full hardlinks with ::
1088
1089
1089 $ cp -al REPO REPOCLONE
1090 $ cp -al REPO REPOCLONE
1090
1091
1091 This is the fastest way to clone, but it is not always safe. The
1092 This is the fastest way to clone, but it is not always safe. The
1092 operation is not atomic (making sure REPO is not modified during
1093 operation is not atomic (making sure REPO is not modified during
1093 the operation is up to you) and you have to make sure your
1094 the operation is up to you) and you have to make sure your
1094 editor breaks hardlinks (Emacs and most Linux Kernel tools do
1095 editor breaks hardlinks (Emacs and most Linux Kernel tools do
1095 so). Also, this is not compatible with certain extensions that
1096 so). Also, this is not compatible with certain extensions that
1096 place their metadata under the .hg directory, such as mq.
1097 place their metadata under the .hg directory, such as mq.
1097
1098
1098 Mercurial will update the working directory to the first applicable
1099 Mercurial will update the working directory to the first applicable
1099 revision from this list:
1100 revision from this list:
1100
1101
1101 a) null if -U or the source repository has no changesets
1102 a) null if -U or the source repository has no changesets
1102 b) if -u . and the source repository is local, the first parent of
1103 b) if -u . and the source repository is local, the first parent of
1103 the source repository's working directory
1104 the source repository's working directory
1104 c) the changeset specified with -u (if a branch name, this means the
1105 c) the changeset specified with -u (if a branch name, this means the
1105 latest head of that branch)
1106 latest head of that branch)
1106 d) the changeset specified with -r
1107 d) the changeset specified with -r
1107 e) the tipmost head specified with -b
1108 e) the tipmost head specified with -b
1108 f) the tipmost head specified with the url#branch source syntax
1109 f) the tipmost head specified with the url#branch source syntax
1109 g) the tipmost head of the default branch
1110 g) the tipmost head of the default branch
1110 h) tip
1111 h) tip
1111
1112
1112 Examples:
1113 Examples:
1113
1114
1114 - clone a remote repository to a new directory named hg/::
1115 - clone a remote repository to a new directory named hg/::
1115
1116
1116 hg clone http://selenic.com/hg
1117 hg clone http://selenic.com/hg
1117
1118
1118 - create a lightweight local clone::
1119 - create a lightweight local clone::
1119
1120
1120 hg clone project/ project-feature/
1121 hg clone project/ project-feature/
1121
1122
1122 - clone from an absolute path on an ssh server (note double-slash)::
1123 - clone from an absolute path on an ssh server (note double-slash)::
1123
1124
1124 hg clone ssh://user@server//home/projects/alpha/
1125 hg clone ssh://user@server//home/projects/alpha/
1125
1126
1126 - do a high-speed clone over a LAN while checking out a
1127 - do a high-speed clone over a LAN while checking out a
1127 specified version::
1128 specified version::
1128
1129
1129 hg clone --uncompressed http://server/repo -u 1.5
1130 hg clone --uncompressed http://server/repo -u 1.5
1130
1131
1131 - create a repository without changesets after a particular revision::
1132 - create a repository without changesets after a particular revision::
1132
1133
1133 hg clone -r 04e544 experimental/ good/
1134 hg clone -r 04e544 experimental/ good/
1134
1135
1135 - clone (and track) a particular named branch::
1136 - clone (and track) a particular named branch::
1136
1137
1137 hg clone http://selenic.com/hg#stable
1138 hg clone http://selenic.com/hg#stable
1138
1139
1139 See :hg:`help urls` for details on specifying URLs.
1140 See :hg:`help urls` for details on specifying URLs.
1140
1141
1141 Returns 0 on success.
1142 Returns 0 on success.
1142 """
1143 """
1143 if opts.get('noupdate') and opts.get('updaterev'):
1144 if opts.get('noupdate') and opts.get('updaterev'):
1144 raise util.Abort(_("cannot specify both --noupdate and --updaterev"))
1145 raise util.Abort(_("cannot specify both --noupdate and --updaterev"))
1145
1146
1146 r = hg.clone(ui, opts, source, dest,
1147 r = hg.clone(ui, opts, source, dest,
1147 pull=opts.get('pull'),
1148 pull=opts.get('pull'),
1148 stream=opts.get('uncompressed'),
1149 stream=opts.get('uncompressed'),
1149 rev=opts.get('rev'),
1150 rev=opts.get('rev'),
1150 update=opts.get('updaterev') or not opts.get('noupdate'),
1151 update=opts.get('updaterev') or not opts.get('noupdate'),
1151 branch=opts.get('branch'))
1152 branch=opts.get('branch'))
1152
1153
1153 return r is None
1154 return r is None
1154
1155
1155 @command('^commit|ci',
1156 @command('^commit|ci',
1156 [('A', 'addremove', None,
1157 [('A', 'addremove', None,
1157 _('mark new/missing files as added/removed before committing')),
1158 _('mark new/missing files as added/removed before committing')),
1158 ('', 'close-branch', None,
1159 ('', 'close-branch', None,
1159 _('mark a branch as closed, hiding it from the branch list')),
1160 _('mark a branch as closed, hiding it from the branch list')),
1160 ] + walkopts + commitopts + commitopts2 + subrepoopts,
1161 ] + walkopts + commitopts + commitopts2 + subrepoopts,
1161 _('[OPTION]... [FILE]...'))
1162 _('[OPTION]... [FILE]...'))
1162 def commit(ui, repo, *pats, **opts):
1163 def commit(ui, repo, *pats, **opts):
1163 """commit the specified files or all outstanding changes
1164 """commit the specified files or all outstanding changes
1164
1165
1165 Commit changes to the given files into the repository. Unlike a
1166 Commit changes to the given files into the repository. Unlike a
1166 centralized SCM, this operation is a local operation. See
1167 centralized SCM, this operation is a local operation. See
1167 :hg:`push` for a way to actively distribute your changes.
1168 :hg:`push` for a way to actively distribute your changes.
1168
1169
1169 If a list of files is omitted, all changes reported by :hg:`status`
1170 If a list of files is omitted, all changes reported by :hg:`status`
1170 will be committed.
1171 will be committed.
1171
1172
1172 If you are committing the result of a merge, do not provide any
1173 If you are committing the result of a merge, do not provide any
1173 filenames or -I/-X filters.
1174 filenames or -I/-X filters.
1174
1175
1175 If no commit message is specified, Mercurial starts your
1176 If no commit message is specified, Mercurial starts your
1176 configured editor where you can enter a message. In case your
1177 configured editor where you can enter a message. In case your
1177 commit fails, you will find a backup of your message in
1178 commit fails, you will find a backup of your message in
1178 ``.hg/last-message.txt``.
1179 ``.hg/last-message.txt``.
1179
1180
1180 See :hg:`help dates` for a list of formats valid for -d/--date.
1181 See :hg:`help dates` for a list of formats valid for -d/--date.
1181
1182
1182 Returns 0 on success, 1 if nothing changed.
1183 Returns 0 on success, 1 if nothing changed.
1183 """
1184 """
1184 if opts.get('subrepos'):
1185 if opts.get('subrepos'):
1185 # Let --subrepos on the command line overide config setting.
1186 # Let --subrepos on the command line overide config setting.
1186 ui.setconfig('ui', 'commitsubrepos', True)
1187 ui.setconfig('ui', 'commitsubrepos', True)
1187
1188
1188 extra = {}
1189 extra = {}
1189 if opts.get('close_branch'):
1190 if opts.get('close_branch'):
1190 if repo['.'].node() not in repo.branchheads():
1191 if repo['.'].node() not in repo.branchheads():
1191 # The topo heads set is included in the branch heads set of the
1192 # The topo heads set is included in the branch heads set of the
1192 # current branch, so it's sufficient to test branchheads
1193 # current branch, so it's sufficient to test branchheads
1193 raise util.Abort(_('can only close branch heads'))
1194 raise util.Abort(_('can only close branch heads'))
1194 extra['close'] = 1
1195 extra['close'] = 1
1195 e = cmdutil.commiteditor
1196 e = cmdutil.commiteditor
1196 if opts.get('force_editor'):
1197 if opts.get('force_editor'):
1197 e = cmdutil.commitforceeditor
1198 e = cmdutil.commitforceeditor
1198
1199
1199 def commitfunc(ui, repo, message, match, opts):
1200 def commitfunc(ui, repo, message, match, opts):
1200 return repo.commit(message, opts.get('user'), opts.get('date'), match,
1201 return repo.commit(message, opts.get('user'), opts.get('date'), match,
1201 editor=e, extra=extra)
1202 editor=e, extra=extra)
1202
1203
1203 branch = repo[None].branch()
1204 branch = repo[None].branch()
1204 bheads = repo.branchheads(branch)
1205 bheads = repo.branchheads(branch)
1205
1206
1206 node = cmdutil.commit(ui, repo, commitfunc, pats, opts)
1207 node = cmdutil.commit(ui, repo, commitfunc, pats, opts)
1207 if not node:
1208 if not node:
1208 stat = repo.status(match=scmutil.match(repo[None], pats, opts))
1209 stat = repo.status(match=scmutil.match(repo[None], pats, opts))
1209 if stat[3]:
1210 if stat[3]:
1210 ui.status(_("nothing changed (%d missing files, see 'hg status')\n")
1211 ui.status(_("nothing changed (%d missing files, see 'hg status')\n")
1211 % len(stat[3]))
1212 % len(stat[3]))
1212 else:
1213 else:
1213 ui.status(_("nothing changed\n"))
1214 ui.status(_("nothing changed\n"))
1214 return 1
1215 return 1
1215
1216
1216 ctx = repo[node]
1217 ctx = repo[node]
1217 parents = ctx.parents()
1218 parents = ctx.parents()
1218
1219
1219 if (bheads and node not in bheads and not
1220 if (bheads and node not in bheads and not
1220 [x for x in parents if x.node() in bheads and x.branch() == branch]):
1221 [x for x in parents if x.node() in bheads and x.branch() == branch]):
1221 ui.status(_('created new head\n'))
1222 ui.status(_('created new head\n'))
1222 # The message is not printed for initial roots. For the other
1223 # The message is not printed for initial roots. For the other
1223 # changesets, it is printed in the following situations:
1224 # changesets, it is printed in the following situations:
1224 #
1225 #
1225 # Par column: for the 2 parents with ...
1226 # Par column: for the 2 parents with ...
1226 # N: null or no parent
1227 # N: null or no parent
1227 # B: parent is on another named branch
1228 # B: parent is on another named branch
1228 # C: parent is a regular non head changeset
1229 # C: parent is a regular non head changeset
1229 # H: parent was a branch head of the current branch
1230 # H: parent was a branch head of the current branch
1230 # Msg column: whether we print "created new head" message
1231 # Msg column: whether we print "created new head" message
1231 # In the following, it is assumed that there already exists some
1232 # In the following, it is assumed that there already exists some
1232 # initial branch heads of the current branch, otherwise nothing is
1233 # initial branch heads of the current branch, otherwise nothing is
1233 # printed anyway.
1234 # printed anyway.
1234 #
1235 #
1235 # Par Msg Comment
1236 # Par Msg Comment
1236 # NN y additional topo root
1237 # NN y additional topo root
1237 #
1238 #
1238 # BN y additional branch root
1239 # BN y additional branch root
1239 # CN y additional topo head
1240 # CN y additional topo head
1240 # HN n usual case
1241 # HN n usual case
1241 #
1242 #
1242 # BB y weird additional branch root
1243 # BB y weird additional branch root
1243 # CB y branch merge
1244 # CB y branch merge
1244 # HB n merge with named branch
1245 # HB n merge with named branch
1245 #
1246 #
1246 # CC y additional head from merge
1247 # CC y additional head from merge
1247 # CH n merge with a head
1248 # CH n merge with a head
1248 #
1249 #
1249 # HH n head merge: head count decreases
1250 # HH n head merge: head count decreases
1250
1251
1251 if not opts.get('close_branch'):
1252 if not opts.get('close_branch'):
1252 for r in parents:
1253 for r in parents:
1253 if r.extra().get('close') and r.branch() == branch:
1254 if r.extra().get('close') and r.branch() == branch:
1254 ui.status(_('reopening closed branch head %d\n') % r)
1255 ui.status(_('reopening closed branch head %d\n') % r)
1255
1256
1256 if ui.debugflag:
1257 if ui.debugflag:
1257 ui.write(_('committed changeset %d:%s\n') % (int(ctx), ctx.hex()))
1258 ui.write(_('committed changeset %d:%s\n') % (int(ctx), ctx.hex()))
1258 elif ui.verbose:
1259 elif ui.verbose:
1259 ui.write(_('committed changeset %d:%s\n') % (int(ctx), ctx))
1260 ui.write(_('committed changeset %d:%s\n') % (int(ctx), ctx))
1260
1261
1261 @command('copy|cp',
1262 @command('copy|cp',
1262 [('A', 'after', None, _('record a copy that has already occurred')),
1263 [('A', 'after', None, _('record a copy that has already occurred')),
1263 ('f', 'force', None, _('forcibly copy over an existing managed file')),
1264 ('f', 'force', None, _('forcibly copy over an existing managed file')),
1264 ] + walkopts + dryrunopts,
1265 ] + walkopts + dryrunopts,
1265 _('[OPTION]... [SOURCE]... DEST'))
1266 _('[OPTION]... [SOURCE]... DEST'))
1266 def copy(ui, repo, *pats, **opts):
1267 def copy(ui, repo, *pats, **opts):
1267 """mark files as copied for the next commit
1268 """mark files as copied for the next commit
1268
1269
1269 Mark dest as having copies of source files. If dest is a
1270 Mark dest as having copies of source files. If dest is a
1270 directory, copies are put in that directory. If dest is a file,
1271 directory, copies are put in that directory. If dest is a file,
1271 the source must be a single file.
1272 the source must be a single file.
1272
1273
1273 By default, this command copies the contents of files as they
1274 By default, this command copies the contents of files as they
1274 exist in the working directory. If invoked with -A/--after, the
1275 exist in the working directory. If invoked with -A/--after, the
1275 operation is recorded, but no copying is performed.
1276 operation is recorded, but no copying is performed.
1276
1277
1277 This command takes effect with the next commit. To undo a copy
1278 This command takes effect with the next commit. To undo a copy
1278 before that, see :hg:`revert`.
1279 before that, see :hg:`revert`.
1279
1280
1280 Returns 0 on success, 1 if errors are encountered.
1281 Returns 0 on success, 1 if errors are encountered.
1281 """
1282 """
1282 wlock = repo.wlock(False)
1283 wlock = repo.wlock(False)
1283 try:
1284 try:
1284 return cmdutil.copy(ui, repo, pats, opts)
1285 return cmdutil.copy(ui, repo, pats, opts)
1285 finally:
1286 finally:
1286 wlock.release()
1287 wlock.release()
1287
1288
1288 @command('debugancestor', [], _('[INDEX] REV1 REV2'))
1289 @command('debugancestor', [], _('[INDEX] REV1 REV2'))
1289 def debugancestor(ui, repo, *args):
1290 def debugancestor(ui, repo, *args):
1290 """find the ancestor revision of two revisions in a given index"""
1291 """find the ancestor revision of two revisions in a given index"""
1291 if len(args) == 3:
1292 if len(args) == 3:
1292 index, rev1, rev2 = args
1293 index, rev1, rev2 = args
1293 r = revlog.revlog(scmutil.opener(os.getcwd(), audit=False), index)
1294 r = revlog.revlog(scmutil.opener(os.getcwd(), audit=False), index)
1294 lookup = r.lookup
1295 lookup = r.lookup
1295 elif len(args) == 2:
1296 elif len(args) == 2:
1296 if not repo:
1297 if not repo:
1297 raise util.Abort(_("there is no Mercurial repository here "
1298 raise util.Abort(_("there is no Mercurial repository here "
1298 "(.hg not found)"))
1299 "(.hg not found)"))
1299 rev1, rev2 = args
1300 rev1, rev2 = args
1300 r = repo.changelog
1301 r = repo.changelog
1301 lookup = repo.lookup
1302 lookup = repo.lookup
1302 else:
1303 else:
1303 raise util.Abort(_('either two or three arguments required'))
1304 raise util.Abort(_('either two or three arguments required'))
1304 a = r.ancestor(lookup(rev1), lookup(rev2))
1305 a = r.ancestor(lookup(rev1), lookup(rev2))
1305 ui.write("%d:%s\n" % (r.rev(a), hex(a)))
1306 ui.write("%d:%s\n" % (r.rev(a), hex(a)))
1306
1307
1307 @command('debugbuilddag',
1308 @command('debugbuilddag',
1308 [('m', 'mergeable-file', None, _('add single file mergeable changes')),
1309 [('m', 'mergeable-file', None, _('add single file mergeable changes')),
1309 ('o', 'overwritten-file', None, _('add single file all revs overwrite')),
1310 ('o', 'overwritten-file', None, _('add single file all revs overwrite')),
1310 ('n', 'new-file', None, _('add new file at each rev'))],
1311 ('n', 'new-file', None, _('add new file at each rev'))],
1311 _('[OPTION]... [TEXT]'))
1312 _('[OPTION]... [TEXT]'))
1312 def debugbuilddag(ui, repo, text=None,
1313 def debugbuilddag(ui, repo, text=None,
1313 mergeable_file=False,
1314 mergeable_file=False,
1314 overwritten_file=False,
1315 overwritten_file=False,
1315 new_file=False):
1316 new_file=False):
1316 """builds a repo with a given DAG from scratch in the current empty repo
1317 """builds a repo with a given DAG from scratch in the current empty repo
1317
1318
1318 The description of the DAG is read from stdin if not given on the
1319 The description of the DAG is read from stdin if not given on the
1319 command line.
1320 command line.
1320
1321
1321 Elements:
1322 Elements:
1322
1323
1323 - "+n" is a linear run of n nodes based on the current default parent
1324 - "+n" is a linear run of n nodes based on the current default parent
1324 - "." is a single node based on the current default parent
1325 - "." is a single node based on the current default parent
1325 - "$" resets the default parent to null (implied at the start);
1326 - "$" resets the default parent to null (implied at the start);
1326 otherwise the default parent is always the last node created
1327 otherwise the default parent is always the last node created
1327 - "<p" sets the default parent to the backref p
1328 - "<p" sets the default parent to the backref p
1328 - "*p" is a fork at parent p, which is a backref
1329 - "*p" is a fork at parent p, which is a backref
1329 - "*p1/p2" is a merge of parents p1 and p2, which are backrefs
1330 - "*p1/p2" is a merge of parents p1 and p2, which are backrefs
1330 - "/p2" is a merge of the preceding node and p2
1331 - "/p2" is a merge of the preceding node and p2
1331 - ":tag" defines a local tag for the preceding node
1332 - ":tag" defines a local tag for the preceding node
1332 - "@branch" sets the named branch for subsequent nodes
1333 - "@branch" sets the named branch for subsequent nodes
1333 - "#...\\n" is a comment up to the end of the line
1334 - "#...\\n" is a comment up to the end of the line
1334
1335
1335 Whitespace between the above elements is ignored.
1336 Whitespace between the above elements is ignored.
1336
1337
1337 A backref is either
1338 A backref is either
1338
1339
1339 - a number n, which references the node curr-n, where curr is the current
1340 - a number n, which references the node curr-n, where curr is the current
1340 node, or
1341 node, or
1341 - the name of a local tag you placed earlier using ":tag", or
1342 - the name of a local tag you placed earlier using ":tag", or
1342 - empty to denote the default parent.
1343 - empty to denote the default parent.
1343
1344
1344 All string valued-elements are either strictly alphanumeric, or must
1345 All string valued-elements are either strictly alphanumeric, or must
1345 be enclosed in double quotes ("..."), with "\\" as escape character.
1346 be enclosed in double quotes ("..."), with "\\" as escape character.
1346 """
1347 """
1347
1348
1348 if text is None:
1349 if text is None:
1349 ui.status(_("reading DAG from stdin\n"))
1350 ui.status(_("reading DAG from stdin\n"))
1350 text = ui.fin.read()
1351 text = ui.fin.read()
1351
1352
1352 cl = repo.changelog
1353 cl = repo.changelog
1353 if len(cl) > 0:
1354 if len(cl) > 0:
1354 raise util.Abort(_('repository is not empty'))
1355 raise util.Abort(_('repository is not empty'))
1355
1356
1356 # determine number of revs in DAG
1357 # determine number of revs in DAG
1357 total = 0
1358 total = 0
1358 for type, data in dagparser.parsedag(text):
1359 for type, data in dagparser.parsedag(text):
1359 if type == 'n':
1360 if type == 'n':
1360 total += 1
1361 total += 1
1361
1362
1362 if mergeable_file:
1363 if mergeable_file:
1363 linesperrev = 2
1364 linesperrev = 2
1364 # make a file with k lines per rev
1365 # make a file with k lines per rev
1365 initialmergedlines = [str(i) for i in xrange(0, total * linesperrev)]
1366 initialmergedlines = [str(i) for i in xrange(0, total * linesperrev)]
1366 initialmergedlines.append("")
1367 initialmergedlines.append("")
1367
1368
1368 tags = []
1369 tags = []
1369
1370
1370 tr = repo.transaction("builddag")
1371 tr = repo.transaction("builddag")
1371 try:
1372 try:
1372
1373
1373 at = -1
1374 at = -1
1374 atbranch = 'default'
1375 atbranch = 'default'
1375 nodeids = []
1376 nodeids = []
1376 ui.progress(_('building'), 0, unit=_('revisions'), total=total)
1377 ui.progress(_('building'), 0, unit=_('revisions'), total=total)
1377 for type, data in dagparser.parsedag(text):
1378 for type, data in dagparser.parsedag(text):
1378 if type == 'n':
1379 if type == 'n':
1379 ui.note('node %s\n' % str(data))
1380 ui.note('node %s\n' % str(data))
1380 id, ps = data
1381 id, ps = data
1381
1382
1382 files = []
1383 files = []
1383 fctxs = {}
1384 fctxs = {}
1384
1385
1385 p2 = None
1386 p2 = None
1386 if mergeable_file:
1387 if mergeable_file:
1387 fn = "mf"
1388 fn = "mf"
1388 p1 = repo[ps[0]]
1389 p1 = repo[ps[0]]
1389 if len(ps) > 1:
1390 if len(ps) > 1:
1390 p2 = repo[ps[1]]
1391 p2 = repo[ps[1]]
1391 pa = p1.ancestor(p2)
1392 pa = p1.ancestor(p2)
1392 base, local, other = [x[fn].data() for x in pa, p1, p2]
1393 base, local, other = [x[fn].data() for x in pa, p1, p2]
1393 m3 = simplemerge.Merge3Text(base, local, other)
1394 m3 = simplemerge.Merge3Text(base, local, other)
1394 ml = [l.strip() for l in m3.merge_lines()]
1395 ml = [l.strip() for l in m3.merge_lines()]
1395 ml.append("")
1396 ml.append("")
1396 elif at > 0:
1397 elif at > 0:
1397 ml = p1[fn].data().split("\n")
1398 ml = p1[fn].data().split("\n")
1398 else:
1399 else:
1399 ml = initialmergedlines
1400 ml = initialmergedlines
1400 ml[id * linesperrev] += " r%i" % id
1401 ml[id * linesperrev] += " r%i" % id
1401 mergedtext = "\n".join(ml)
1402 mergedtext = "\n".join(ml)
1402 files.append(fn)
1403 files.append(fn)
1403 fctxs[fn] = context.memfilectx(fn, mergedtext)
1404 fctxs[fn] = context.memfilectx(fn, mergedtext)
1404
1405
1405 if overwritten_file:
1406 if overwritten_file:
1406 fn = "of"
1407 fn = "of"
1407 files.append(fn)
1408 files.append(fn)
1408 fctxs[fn] = context.memfilectx(fn, "r%i\n" % id)
1409 fctxs[fn] = context.memfilectx(fn, "r%i\n" % id)
1409
1410
1410 if new_file:
1411 if new_file:
1411 fn = "nf%i" % id
1412 fn = "nf%i" % id
1412 files.append(fn)
1413 files.append(fn)
1413 fctxs[fn] = context.memfilectx(fn, "r%i\n" % id)
1414 fctxs[fn] = context.memfilectx(fn, "r%i\n" % id)
1414 if len(ps) > 1:
1415 if len(ps) > 1:
1415 if not p2:
1416 if not p2:
1416 p2 = repo[ps[1]]
1417 p2 = repo[ps[1]]
1417 for fn in p2:
1418 for fn in p2:
1418 if fn.startswith("nf"):
1419 if fn.startswith("nf"):
1419 files.append(fn)
1420 files.append(fn)
1420 fctxs[fn] = p2[fn]
1421 fctxs[fn] = p2[fn]
1421
1422
1422 def fctxfn(repo, cx, path):
1423 def fctxfn(repo, cx, path):
1423 return fctxs.get(path)
1424 return fctxs.get(path)
1424
1425
1425 if len(ps) == 0 or ps[0] < 0:
1426 if len(ps) == 0 or ps[0] < 0:
1426 pars = [None, None]
1427 pars = [None, None]
1427 elif len(ps) == 1:
1428 elif len(ps) == 1:
1428 pars = [nodeids[ps[0]], None]
1429 pars = [nodeids[ps[0]], None]
1429 else:
1430 else:
1430 pars = [nodeids[p] for p in ps]
1431 pars = [nodeids[p] for p in ps]
1431 cx = context.memctx(repo, pars, "r%i" % id, files, fctxfn,
1432 cx = context.memctx(repo, pars, "r%i" % id, files, fctxfn,
1432 date=(id, 0),
1433 date=(id, 0),
1433 user="debugbuilddag",
1434 user="debugbuilddag",
1434 extra={'branch': atbranch})
1435 extra={'branch': atbranch})
1435 nodeid = repo.commitctx(cx)
1436 nodeid = repo.commitctx(cx)
1436 nodeids.append(nodeid)
1437 nodeids.append(nodeid)
1437 at = id
1438 at = id
1438 elif type == 'l':
1439 elif type == 'l':
1439 id, name = data
1440 id, name = data
1440 ui.note('tag %s\n' % name)
1441 ui.note('tag %s\n' % name)
1441 tags.append("%s %s\n" % (hex(repo.changelog.node(id)), name))
1442 tags.append("%s %s\n" % (hex(repo.changelog.node(id)), name))
1442 elif type == 'a':
1443 elif type == 'a':
1443 ui.note('branch %s\n' % data)
1444 ui.note('branch %s\n' % data)
1444 atbranch = data
1445 atbranch = data
1445 ui.progress(_('building'), id, unit=_('revisions'), total=total)
1446 ui.progress(_('building'), id, unit=_('revisions'), total=total)
1446 tr.close()
1447 tr.close()
1447 finally:
1448 finally:
1448 ui.progress(_('building'), None)
1449 ui.progress(_('building'), None)
1449 tr.release()
1450 tr.release()
1450
1451
1451 if tags:
1452 if tags:
1452 repo.opener.write("localtags", "".join(tags))
1453 repo.opener.write("localtags", "".join(tags))
1453
1454
1454 @command('debugbundle', [('a', 'all', None, _('show all details'))], _('FILE'))
1455 @command('debugbundle', [('a', 'all', None, _('show all details'))], _('FILE'))
1455 def debugbundle(ui, bundlepath, all=None, **opts):
1456 def debugbundle(ui, bundlepath, all=None, **opts):
1456 """lists the contents of a bundle"""
1457 """lists the contents of a bundle"""
1457 f = url.open(ui, bundlepath)
1458 f = url.open(ui, bundlepath)
1458 try:
1459 try:
1459 gen = changegroup.readbundle(f, bundlepath)
1460 gen = changegroup.readbundle(f, bundlepath)
1460 if all:
1461 if all:
1461 ui.write("format: id, p1, p2, cset, delta base, len(delta)\n")
1462 ui.write("format: id, p1, p2, cset, delta base, len(delta)\n")
1462
1463
1463 def showchunks(named):
1464 def showchunks(named):
1464 ui.write("\n%s\n" % named)
1465 ui.write("\n%s\n" % named)
1465 chain = None
1466 chain = None
1466 while True:
1467 while True:
1467 chunkdata = gen.deltachunk(chain)
1468 chunkdata = gen.deltachunk(chain)
1468 if not chunkdata:
1469 if not chunkdata:
1469 break
1470 break
1470 node = chunkdata['node']
1471 node = chunkdata['node']
1471 p1 = chunkdata['p1']
1472 p1 = chunkdata['p1']
1472 p2 = chunkdata['p2']
1473 p2 = chunkdata['p2']
1473 cs = chunkdata['cs']
1474 cs = chunkdata['cs']
1474 deltabase = chunkdata['deltabase']
1475 deltabase = chunkdata['deltabase']
1475 delta = chunkdata['delta']
1476 delta = chunkdata['delta']
1476 ui.write("%s %s %s %s %s %s\n" %
1477 ui.write("%s %s %s %s %s %s\n" %
1477 (hex(node), hex(p1), hex(p2),
1478 (hex(node), hex(p1), hex(p2),
1478 hex(cs), hex(deltabase), len(delta)))
1479 hex(cs), hex(deltabase), len(delta)))
1479 chain = node
1480 chain = node
1480
1481
1481 chunkdata = gen.changelogheader()
1482 chunkdata = gen.changelogheader()
1482 showchunks("changelog")
1483 showchunks("changelog")
1483 chunkdata = gen.manifestheader()
1484 chunkdata = gen.manifestheader()
1484 showchunks("manifest")
1485 showchunks("manifest")
1485 while True:
1486 while True:
1486 chunkdata = gen.filelogheader()
1487 chunkdata = gen.filelogheader()
1487 if not chunkdata:
1488 if not chunkdata:
1488 break
1489 break
1489 fname = chunkdata['filename']
1490 fname = chunkdata['filename']
1490 showchunks(fname)
1491 showchunks(fname)
1491 else:
1492 else:
1492 chunkdata = gen.changelogheader()
1493 chunkdata = gen.changelogheader()
1493 chain = None
1494 chain = None
1494 while True:
1495 while True:
1495 chunkdata = gen.deltachunk(chain)
1496 chunkdata = gen.deltachunk(chain)
1496 if not chunkdata:
1497 if not chunkdata:
1497 break
1498 break
1498 node = chunkdata['node']
1499 node = chunkdata['node']
1499 ui.write("%s\n" % hex(node))
1500 ui.write("%s\n" % hex(node))
1500 chain = node
1501 chain = node
1501 finally:
1502 finally:
1502 f.close()
1503 f.close()
1503
1504
1504 @command('debugcheckstate', [], '')
1505 @command('debugcheckstate', [], '')
1505 def debugcheckstate(ui, repo):
1506 def debugcheckstate(ui, repo):
1506 """validate the correctness of the current dirstate"""
1507 """validate the correctness of the current dirstate"""
1507 parent1, parent2 = repo.dirstate.parents()
1508 parent1, parent2 = repo.dirstate.parents()
1508 m1 = repo[parent1].manifest()
1509 m1 = repo[parent1].manifest()
1509 m2 = repo[parent2].manifest()
1510 m2 = repo[parent2].manifest()
1510 errors = 0
1511 errors = 0
1511 for f in repo.dirstate:
1512 for f in repo.dirstate:
1512 state = repo.dirstate[f]
1513 state = repo.dirstate[f]
1513 if state in "nr" and f not in m1:
1514 if state in "nr" and f not in m1:
1514 ui.warn(_("%s in state %s, but not in manifest1\n") % (f, state))
1515 ui.warn(_("%s in state %s, but not in manifest1\n") % (f, state))
1515 errors += 1
1516 errors += 1
1516 if state in "a" and f in m1:
1517 if state in "a" and f in m1:
1517 ui.warn(_("%s in state %s, but also in manifest1\n") % (f, state))
1518 ui.warn(_("%s in state %s, but also in manifest1\n") % (f, state))
1518 errors += 1
1519 errors += 1
1519 if state in "m" and f not in m1 and f not in m2:
1520 if state in "m" and f not in m1 and f not in m2:
1520 ui.warn(_("%s in state %s, but not in either manifest\n") %
1521 ui.warn(_("%s in state %s, but not in either manifest\n") %
1521 (f, state))
1522 (f, state))
1522 errors += 1
1523 errors += 1
1523 for f in m1:
1524 for f in m1:
1524 state = repo.dirstate[f]
1525 state = repo.dirstate[f]
1525 if state not in "nrm":
1526 if state not in "nrm":
1526 ui.warn(_("%s in manifest1, but listed as state %s") % (f, state))
1527 ui.warn(_("%s in manifest1, but listed as state %s") % (f, state))
1527 errors += 1
1528 errors += 1
1528 if errors:
1529 if errors:
1529 error = _(".hg/dirstate inconsistent with current parent's manifest")
1530 error = _(".hg/dirstate inconsistent with current parent's manifest")
1530 raise util.Abort(error)
1531 raise util.Abort(error)
1531
1532
1532 @command('debugcommands', [], _('[COMMAND]'))
1533 @command('debugcommands', [], _('[COMMAND]'))
1533 def debugcommands(ui, cmd='', *args):
1534 def debugcommands(ui, cmd='', *args):
1534 """list all available commands and options"""
1535 """list all available commands and options"""
1535 for cmd, vals in sorted(table.iteritems()):
1536 for cmd, vals in sorted(table.iteritems()):
1536 cmd = cmd.split('|')[0].strip('^')
1537 cmd = cmd.split('|')[0].strip('^')
1537 opts = ', '.join([i[1] for i in vals[1]])
1538 opts = ', '.join([i[1] for i in vals[1]])
1538 ui.write('%s: %s\n' % (cmd, opts))
1539 ui.write('%s: %s\n' % (cmd, opts))
1539
1540
1540 @command('debugcomplete',
1541 @command('debugcomplete',
1541 [('o', 'options', None, _('show the command options'))],
1542 [('o', 'options', None, _('show the command options'))],
1542 _('[-o] CMD'))
1543 _('[-o] CMD'))
1543 def debugcomplete(ui, cmd='', **opts):
1544 def debugcomplete(ui, cmd='', **opts):
1544 """returns the completion list associated with the given command"""
1545 """returns the completion list associated with the given command"""
1545
1546
1546 if opts.get('options'):
1547 if opts.get('options'):
1547 options = []
1548 options = []
1548 otables = [globalopts]
1549 otables = [globalopts]
1549 if cmd:
1550 if cmd:
1550 aliases, entry = cmdutil.findcmd(cmd, table, False)
1551 aliases, entry = cmdutil.findcmd(cmd, table, False)
1551 otables.append(entry[1])
1552 otables.append(entry[1])
1552 for t in otables:
1553 for t in otables:
1553 for o in t:
1554 for o in t:
1554 if "(DEPRECATED)" in o[3]:
1555 if "(DEPRECATED)" in o[3]:
1555 continue
1556 continue
1556 if o[0]:
1557 if o[0]:
1557 options.append('-%s' % o[0])
1558 options.append('-%s' % o[0])
1558 options.append('--%s' % o[1])
1559 options.append('--%s' % o[1])
1559 ui.write("%s\n" % "\n".join(options))
1560 ui.write("%s\n" % "\n".join(options))
1560 return
1561 return
1561
1562
1562 cmdlist = cmdutil.findpossible(cmd, table)
1563 cmdlist = cmdutil.findpossible(cmd, table)
1563 if ui.verbose:
1564 if ui.verbose:
1564 cmdlist = [' '.join(c[0]) for c in cmdlist.values()]
1565 cmdlist = [' '.join(c[0]) for c in cmdlist.values()]
1565 ui.write("%s\n" % "\n".join(sorted(cmdlist)))
1566 ui.write("%s\n" % "\n".join(sorted(cmdlist)))
1566
1567
1567 @command('debugdag',
1568 @command('debugdag',
1568 [('t', 'tags', None, _('use tags as labels')),
1569 [('t', 'tags', None, _('use tags as labels')),
1569 ('b', 'branches', None, _('annotate with branch names')),
1570 ('b', 'branches', None, _('annotate with branch names')),
1570 ('', 'dots', None, _('use dots for runs')),
1571 ('', 'dots', None, _('use dots for runs')),
1571 ('s', 'spaces', None, _('separate elements by spaces'))],
1572 ('s', 'spaces', None, _('separate elements by spaces'))],
1572 _('[OPTION]... [FILE [REV]...]'))
1573 _('[OPTION]... [FILE [REV]...]'))
1573 def debugdag(ui, repo, file_=None, *revs, **opts):
1574 def debugdag(ui, repo, file_=None, *revs, **opts):
1574 """format the changelog or an index DAG as a concise textual description
1575 """format the changelog or an index DAG as a concise textual description
1575
1576
1576 If you pass a revlog index, the revlog's DAG is emitted. If you list
1577 If you pass a revlog index, the revlog's DAG is emitted. If you list
1577 revision numbers, they get labelled in the output as rN.
1578 revision numbers, they get labelled in the output as rN.
1578
1579
1579 Otherwise, the changelog DAG of the current repo is emitted.
1580 Otherwise, the changelog DAG of the current repo is emitted.
1580 """
1581 """
1581 spaces = opts.get('spaces')
1582 spaces = opts.get('spaces')
1582 dots = opts.get('dots')
1583 dots = opts.get('dots')
1583 if file_:
1584 if file_:
1584 rlog = revlog.revlog(scmutil.opener(os.getcwd(), audit=False), file_)
1585 rlog = revlog.revlog(scmutil.opener(os.getcwd(), audit=False), file_)
1585 revs = set((int(r) for r in revs))
1586 revs = set((int(r) for r in revs))
1586 def events():
1587 def events():
1587 for r in rlog:
1588 for r in rlog:
1588 yield 'n', (r, list(set(p for p in rlog.parentrevs(r) if p != -1)))
1589 yield 'n', (r, list(set(p for p in rlog.parentrevs(r) if p != -1)))
1589 if r in revs:
1590 if r in revs:
1590 yield 'l', (r, "r%i" % r)
1591 yield 'l', (r, "r%i" % r)
1591 elif repo:
1592 elif repo:
1592 cl = repo.changelog
1593 cl = repo.changelog
1593 tags = opts.get('tags')
1594 tags = opts.get('tags')
1594 branches = opts.get('branches')
1595 branches = opts.get('branches')
1595 if tags:
1596 if tags:
1596 labels = {}
1597 labels = {}
1597 for l, n in repo.tags().items():
1598 for l, n in repo.tags().items():
1598 labels.setdefault(cl.rev(n), []).append(l)
1599 labels.setdefault(cl.rev(n), []).append(l)
1599 def events():
1600 def events():
1600 b = "default"
1601 b = "default"
1601 for r in cl:
1602 for r in cl:
1602 if branches:
1603 if branches:
1603 newb = cl.read(cl.node(r))[5]['branch']
1604 newb = cl.read(cl.node(r))[5]['branch']
1604 if newb != b:
1605 if newb != b:
1605 yield 'a', newb
1606 yield 'a', newb
1606 b = newb
1607 b = newb
1607 yield 'n', (r, list(set(p for p in cl.parentrevs(r) if p != -1)))
1608 yield 'n', (r, list(set(p for p in cl.parentrevs(r) if p != -1)))
1608 if tags:
1609 if tags:
1609 ls = labels.get(r)
1610 ls = labels.get(r)
1610 if ls:
1611 if ls:
1611 for l in ls:
1612 for l in ls:
1612 yield 'l', (r, l)
1613 yield 'l', (r, l)
1613 else:
1614 else:
1614 raise util.Abort(_('need repo for changelog dag'))
1615 raise util.Abort(_('need repo for changelog dag'))
1615
1616
1616 for line in dagparser.dagtextlines(events(),
1617 for line in dagparser.dagtextlines(events(),
1617 addspaces=spaces,
1618 addspaces=spaces,
1618 wraplabels=True,
1619 wraplabels=True,
1619 wrapannotations=True,
1620 wrapannotations=True,
1620 wrapnonlinear=dots,
1621 wrapnonlinear=dots,
1621 usedots=dots,
1622 usedots=dots,
1622 maxlinewidth=70):
1623 maxlinewidth=70):
1623 ui.write(line)
1624 ui.write(line)
1624 ui.write("\n")
1625 ui.write("\n")
1625
1626
1626 @command('debugdata',
1627 @command('debugdata',
1627 [('c', 'changelog', False, _('open changelog')),
1628 [('c', 'changelog', False, _('open changelog')),
1628 ('m', 'manifest', False, _('open manifest'))],
1629 ('m', 'manifest', False, _('open manifest'))],
1629 _('-c|-m|FILE REV'))
1630 _('-c|-m|FILE REV'))
1630 def debugdata(ui, repo, file_, rev = None, **opts):
1631 def debugdata(ui, repo, file_, rev = None, **opts):
1631 """dump the contents of a data file revision"""
1632 """dump the contents of a data file revision"""
1632 if opts.get('changelog') or opts.get('manifest'):
1633 if opts.get('changelog') or opts.get('manifest'):
1633 file_, rev = None, file_
1634 file_, rev = None, file_
1634 elif rev is None:
1635 elif rev is None:
1635 raise error.CommandError('debugdata', _('invalid arguments'))
1636 raise error.CommandError('debugdata', _('invalid arguments'))
1636 r = cmdutil.openrevlog(repo, 'debugdata', file_, opts)
1637 r = cmdutil.openrevlog(repo, 'debugdata', file_, opts)
1637 try:
1638 try:
1638 ui.write(r.revision(r.lookup(rev)))
1639 ui.write(r.revision(r.lookup(rev)))
1639 except KeyError:
1640 except KeyError:
1640 raise util.Abort(_('invalid revision identifier %s') % rev)
1641 raise util.Abort(_('invalid revision identifier %s') % rev)
1641
1642
1642 @command('debugdate',
1643 @command('debugdate',
1643 [('e', 'extended', None, _('try extended date formats'))],
1644 [('e', 'extended', None, _('try extended date formats'))],
1644 _('[-e] DATE [RANGE]'))
1645 _('[-e] DATE [RANGE]'))
1645 def debugdate(ui, date, range=None, **opts):
1646 def debugdate(ui, date, range=None, **opts):
1646 """parse and display a date"""
1647 """parse and display a date"""
1647 if opts["extended"]:
1648 if opts["extended"]:
1648 d = util.parsedate(date, util.extendeddateformats)
1649 d = util.parsedate(date, util.extendeddateformats)
1649 else:
1650 else:
1650 d = util.parsedate(date)
1651 d = util.parsedate(date)
1651 ui.write("internal: %s %s\n" % d)
1652 ui.write("internal: %s %s\n" % d)
1652 ui.write("standard: %s\n" % util.datestr(d))
1653 ui.write("standard: %s\n" % util.datestr(d))
1653 if range:
1654 if range:
1654 m = util.matchdate(range)
1655 m = util.matchdate(range)
1655 ui.write("match: %s\n" % m(d[0]))
1656 ui.write("match: %s\n" % m(d[0]))
1656
1657
1657 @command('debugdiscovery',
1658 @command('debugdiscovery',
1658 [('', 'old', None, _('use old-style discovery')),
1659 [('', 'old', None, _('use old-style discovery')),
1659 ('', 'nonheads', None,
1660 ('', 'nonheads', None,
1660 _('use old-style discovery with non-heads included')),
1661 _('use old-style discovery with non-heads included')),
1661 ] + remoteopts,
1662 ] + remoteopts,
1662 _('[-l REV] [-r REV] [-b BRANCH]... [OTHER]'))
1663 _('[-l REV] [-r REV] [-b BRANCH]... [OTHER]'))
1663 def debugdiscovery(ui, repo, remoteurl="default", **opts):
1664 def debugdiscovery(ui, repo, remoteurl="default", **opts):
1664 """runs the changeset discovery protocol in isolation"""
1665 """runs the changeset discovery protocol in isolation"""
1665 remoteurl, branches = hg.parseurl(ui.expandpath(remoteurl), opts.get('branch'))
1666 remoteurl, branches = hg.parseurl(ui.expandpath(remoteurl), opts.get('branch'))
1666 remote = hg.peer(repo, opts, remoteurl)
1667 remote = hg.peer(repo, opts, remoteurl)
1667 ui.status(_('comparing with %s\n') % util.hidepassword(remoteurl))
1668 ui.status(_('comparing with %s\n') % util.hidepassword(remoteurl))
1668
1669
1669 # make sure tests are repeatable
1670 # make sure tests are repeatable
1670 random.seed(12323)
1671 random.seed(12323)
1671
1672
1672 def doit(localheads, remoteheads):
1673 def doit(localheads, remoteheads):
1673 if opts.get('old'):
1674 if opts.get('old'):
1674 if localheads:
1675 if localheads:
1675 raise util.Abort('cannot use localheads with old style discovery')
1676 raise util.Abort('cannot use localheads with old style discovery')
1676 common, _in, hds = treediscovery.findcommonincoming(repo, remote,
1677 common, _in, hds = treediscovery.findcommonincoming(repo, remote,
1677 force=True)
1678 force=True)
1678 common = set(common)
1679 common = set(common)
1679 if not opts.get('nonheads'):
1680 if not opts.get('nonheads'):
1680 ui.write("unpruned common: %s\n" % " ".join([short(n)
1681 ui.write("unpruned common: %s\n" % " ".join([short(n)
1681 for n in common]))
1682 for n in common]))
1682 dag = dagutil.revlogdag(repo.changelog)
1683 dag = dagutil.revlogdag(repo.changelog)
1683 all = dag.ancestorset(dag.internalizeall(common))
1684 all = dag.ancestorset(dag.internalizeall(common))
1684 common = dag.externalizeall(dag.headsetofconnecteds(all))
1685 common = dag.externalizeall(dag.headsetofconnecteds(all))
1685 else:
1686 else:
1686 common, any, hds = setdiscovery.findcommonheads(ui, repo, remote)
1687 common, any, hds = setdiscovery.findcommonheads(ui, repo, remote)
1687 common = set(common)
1688 common = set(common)
1688 rheads = set(hds)
1689 rheads = set(hds)
1689 lheads = set(repo.heads())
1690 lheads = set(repo.heads())
1690 ui.write("common heads: %s\n" % " ".join([short(n) for n in common]))
1691 ui.write("common heads: %s\n" % " ".join([short(n) for n in common]))
1691 if lheads <= common:
1692 if lheads <= common:
1692 ui.write("local is subset\n")
1693 ui.write("local is subset\n")
1693 elif rheads <= common:
1694 elif rheads <= common:
1694 ui.write("remote is subset\n")
1695 ui.write("remote is subset\n")
1695
1696
1696 serverlogs = opts.get('serverlog')
1697 serverlogs = opts.get('serverlog')
1697 if serverlogs:
1698 if serverlogs:
1698 for filename in serverlogs:
1699 for filename in serverlogs:
1699 logfile = open(filename, 'r')
1700 logfile = open(filename, 'r')
1700 try:
1701 try:
1701 line = logfile.readline()
1702 line = logfile.readline()
1702 while line:
1703 while line:
1703 parts = line.strip().split(';')
1704 parts = line.strip().split(';')
1704 op = parts[1]
1705 op = parts[1]
1705 if op == 'cg':
1706 if op == 'cg':
1706 pass
1707 pass
1707 elif op == 'cgss':
1708 elif op == 'cgss':
1708 doit(parts[2].split(' '), parts[3].split(' '))
1709 doit(parts[2].split(' '), parts[3].split(' '))
1709 elif op == 'unb':
1710 elif op == 'unb':
1710 doit(parts[3].split(' '), parts[2].split(' '))
1711 doit(parts[3].split(' '), parts[2].split(' '))
1711 line = logfile.readline()
1712 line = logfile.readline()
1712 finally:
1713 finally:
1713 logfile.close()
1714 logfile.close()
1714
1715
1715 else:
1716 else:
1716 remoterevs, _checkout = hg.addbranchrevs(repo, remote, branches,
1717 remoterevs, _checkout = hg.addbranchrevs(repo, remote, branches,
1717 opts.get('remote_head'))
1718 opts.get('remote_head'))
1718 localrevs = opts.get('local_head')
1719 localrevs = opts.get('local_head')
1719 doit(localrevs, remoterevs)
1720 doit(localrevs, remoterevs)
1720
1721
1721 @command('debugfileset', [], ('REVSPEC'))
1722 @command('debugfileset', [], ('REVSPEC'))
1722 def debugfileset(ui, repo, expr):
1723 def debugfileset(ui, repo, expr):
1723 '''parse and apply a fileset specification'''
1724 '''parse and apply a fileset specification'''
1724 if ui.verbose:
1725 if ui.verbose:
1725 tree = fileset.parse(expr)[0]
1726 tree = fileset.parse(expr)[0]
1726 ui.note(tree, "\n")
1727 ui.note(tree, "\n")
1727
1728
1728 for f in fileset.getfileset(repo[None], expr):
1729 for f in fileset.getfileset(repo[None], expr):
1729 ui.write("%s\n" % f)
1730 ui.write("%s\n" % f)
1730
1731
1731 @command('debugfsinfo', [], _('[PATH]'))
1732 @command('debugfsinfo', [], _('[PATH]'))
1732 def debugfsinfo(ui, path = "."):
1733 def debugfsinfo(ui, path = "."):
1733 """show information detected about current filesystem"""
1734 """show information detected about current filesystem"""
1734 util.writefile('.debugfsinfo', '')
1735 util.writefile('.debugfsinfo', '')
1735 ui.write('exec: %s\n' % (util.checkexec(path) and 'yes' or 'no'))
1736 ui.write('exec: %s\n' % (util.checkexec(path) and 'yes' or 'no'))
1736 ui.write('symlink: %s\n' % (util.checklink(path) and 'yes' or 'no'))
1737 ui.write('symlink: %s\n' % (util.checklink(path) and 'yes' or 'no'))
1737 ui.write('case-sensitive: %s\n' % (util.checkcase('.debugfsinfo')
1738 ui.write('case-sensitive: %s\n' % (util.checkcase('.debugfsinfo')
1738 and 'yes' or 'no'))
1739 and 'yes' or 'no'))
1739 os.unlink('.debugfsinfo')
1740 os.unlink('.debugfsinfo')
1740
1741
1741 @command('debuggetbundle',
1742 @command('debuggetbundle',
1742 [('H', 'head', [], _('id of head node'), _('ID')),
1743 [('H', 'head', [], _('id of head node'), _('ID')),
1743 ('C', 'common', [], _('id of common node'), _('ID')),
1744 ('C', 'common', [], _('id of common node'), _('ID')),
1744 ('t', 'type', 'bzip2', _('bundle compression type to use'), _('TYPE'))],
1745 ('t', 'type', 'bzip2', _('bundle compression type to use'), _('TYPE'))],
1745 _('REPO FILE [-H|-C ID]...'))
1746 _('REPO FILE [-H|-C ID]...'))
1746 def debuggetbundle(ui, repopath, bundlepath, head=None, common=None, **opts):
1747 def debuggetbundle(ui, repopath, bundlepath, head=None, common=None, **opts):
1747 """retrieves a bundle from a repo
1748 """retrieves a bundle from a repo
1748
1749
1749 Every ID must be a full-length hex node id string. Saves the bundle to the
1750 Every ID must be a full-length hex node id string. Saves the bundle to the
1750 given file.
1751 given file.
1751 """
1752 """
1752 repo = hg.peer(ui, opts, repopath)
1753 repo = hg.peer(ui, opts, repopath)
1753 if not repo.capable('getbundle'):
1754 if not repo.capable('getbundle'):
1754 raise util.Abort("getbundle() not supported by target repository")
1755 raise util.Abort("getbundle() not supported by target repository")
1755 args = {}
1756 args = {}
1756 if common:
1757 if common:
1757 args['common'] = [bin(s) for s in common]
1758 args['common'] = [bin(s) for s in common]
1758 if head:
1759 if head:
1759 args['heads'] = [bin(s) for s in head]
1760 args['heads'] = [bin(s) for s in head]
1760 bundle = repo.getbundle('debug', **args)
1761 bundle = repo.getbundle('debug', **args)
1761
1762
1762 bundletype = opts.get('type', 'bzip2').lower()
1763 bundletype = opts.get('type', 'bzip2').lower()
1763 btypes = {'none': 'HG10UN', 'bzip2': 'HG10BZ', 'gzip': 'HG10GZ'}
1764 btypes = {'none': 'HG10UN', 'bzip2': 'HG10BZ', 'gzip': 'HG10GZ'}
1764 bundletype = btypes.get(bundletype)
1765 bundletype = btypes.get(bundletype)
1765 if bundletype not in changegroup.bundletypes:
1766 if bundletype not in changegroup.bundletypes:
1766 raise util.Abort(_('unknown bundle type specified with --type'))
1767 raise util.Abort(_('unknown bundle type specified with --type'))
1767 changegroup.writebundle(bundle, bundlepath, bundletype)
1768 changegroup.writebundle(bundle, bundlepath, bundletype)
1768
1769
1769 @command('debugignore', [], '')
1770 @command('debugignore', [], '')
1770 def debugignore(ui, repo, *values, **opts):
1771 def debugignore(ui, repo, *values, **opts):
1771 """display the combined ignore pattern"""
1772 """display the combined ignore pattern"""
1772 ignore = repo.dirstate._ignore
1773 ignore = repo.dirstate._ignore
1773 includepat = getattr(ignore, 'includepat', None)
1774 includepat = getattr(ignore, 'includepat', None)
1774 if includepat is not None:
1775 if includepat is not None:
1775 ui.write("%s\n" % includepat)
1776 ui.write("%s\n" % includepat)
1776 else:
1777 else:
1777 raise util.Abort(_("no ignore patterns found"))
1778 raise util.Abort(_("no ignore patterns found"))
1778
1779
1779 @command('debugindex',
1780 @command('debugindex',
1780 [('c', 'changelog', False, _('open changelog')),
1781 [('c', 'changelog', False, _('open changelog')),
1781 ('m', 'manifest', False, _('open manifest')),
1782 ('m', 'manifest', False, _('open manifest')),
1782 ('f', 'format', 0, _('revlog format'), _('FORMAT'))],
1783 ('f', 'format', 0, _('revlog format'), _('FORMAT'))],
1783 _('[-f FORMAT] -c|-m|FILE'))
1784 _('[-f FORMAT] -c|-m|FILE'))
1784 def debugindex(ui, repo, file_ = None, **opts):
1785 def debugindex(ui, repo, file_ = None, **opts):
1785 """dump the contents of an index file"""
1786 """dump the contents of an index file"""
1786 r = cmdutil.openrevlog(repo, 'debugindex', file_, opts)
1787 r = cmdutil.openrevlog(repo, 'debugindex', file_, opts)
1787 format = opts.get('format', 0)
1788 format = opts.get('format', 0)
1788 if format not in (0, 1):
1789 if format not in (0, 1):
1789 raise util.Abort(_("unknown format %d") % format)
1790 raise util.Abort(_("unknown format %d") % format)
1790
1791
1791 generaldelta = r.version & revlog.REVLOGGENERALDELTA
1792 generaldelta = r.version & revlog.REVLOGGENERALDELTA
1792 if generaldelta:
1793 if generaldelta:
1793 basehdr = ' delta'
1794 basehdr = ' delta'
1794 else:
1795 else:
1795 basehdr = ' base'
1796 basehdr = ' base'
1796
1797
1797 if format == 0:
1798 if format == 0:
1798 ui.write(" rev offset length " + basehdr + " linkrev"
1799 ui.write(" rev offset length " + basehdr + " linkrev"
1799 " nodeid p1 p2\n")
1800 " nodeid p1 p2\n")
1800 elif format == 1:
1801 elif format == 1:
1801 ui.write(" rev flag offset length"
1802 ui.write(" rev flag offset length"
1802 " size " + basehdr + " link p1 p2 nodeid\n")
1803 " size " + basehdr + " link p1 p2 nodeid\n")
1803
1804
1804 for i in r:
1805 for i in r:
1805 node = r.node(i)
1806 node = r.node(i)
1806 if generaldelta:
1807 if generaldelta:
1807 base = r.deltaparent(i)
1808 base = r.deltaparent(i)
1808 else:
1809 else:
1809 base = r.chainbase(i)
1810 base = r.chainbase(i)
1810 if format == 0:
1811 if format == 0:
1811 try:
1812 try:
1812 pp = r.parents(node)
1813 pp = r.parents(node)
1813 except:
1814 except:
1814 pp = [nullid, nullid]
1815 pp = [nullid, nullid]
1815 ui.write("% 6d % 9d % 7d % 6d % 7d %s %s %s\n" % (
1816 ui.write("% 6d % 9d % 7d % 6d % 7d %s %s %s\n" % (
1816 i, r.start(i), r.length(i), base, r.linkrev(i),
1817 i, r.start(i), r.length(i), base, r.linkrev(i),
1817 short(node), short(pp[0]), short(pp[1])))
1818 short(node), short(pp[0]), short(pp[1])))
1818 elif format == 1:
1819 elif format == 1:
1819 pr = r.parentrevs(i)
1820 pr = r.parentrevs(i)
1820 ui.write("% 6d %04x % 8d % 8d % 8d % 6d % 6d % 6d % 6d %s\n" % (
1821 ui.write("% 6d %04x % 8d % 8d % 8d % 6d % 6d % 6d % 6d %s\n" % (
1821 i, r.flags(i), r.start(i), r.length(i), r.rawsize(i),
1822 i, r.flags(i), r.start(i), r.length(i), r.rawsize(i),
1822 base, r.linkrev(i), pr[0], pr[1], short(node)))
1823 base, r.linkrev(i), pr[0], pr[1], short(node)))
1823
1824
1824 @command('debugindexdot', [], _('FILE'))
1825 @command('debugindexdot', [], _('FILE'))
1825 def debugindexdot(ui, repo, file_):
1826 def debugindexdot(ui, repo, file_):
1826 """dump an index DAG as a graphviz dot file"""
1827 """dump an index DAG as a graphviz dot file"""
1827 r = None
1828 r = None
1828 if repo:
1829 if repo:
1829 filelog = repo.file(file_)
1830 filelog = repo.file(file_)
1830 if len(filelog):
1831 if len(filelog):
1831 r = filelog
1832 r = filelog
1832 if not r:
1833 if not r:
1833 r = revlog.revlog(scmutil.opener(os.getcwd(), audit=False), file_)
1834 r = revlog.revlog(scmutil.opener(os.getcwd(), audit=False), file_)
1834 ui.write("digraph G {\n")
1835 ui.write("digraph G {\n")
1835 for i in r:
1836 for i in r:
1836 node = r.node(i)
1837 node = r.node(i)
1837 pp = r.parents(node)
1838 pp = r.parents(node)
1838 ui.write("\t%d -> %d\n" % (r.rev(pp[0]), i))
1839 ui.write("\t%d -> %d\n" % (r.rev(pp[0]), i))
1839 if pp[1] != nullid:
1840 if pp[1] != nullid:
1840 ui.write("\t%d -> %d\n" % (r.rev(pp[1]), i))
1841 ui.write("\t%d -> %d\n" % (r.rev(pp[1]), i))
1841 ui.write("}\n")
1842 ui.write("}\n")
1842
1843
1843 @command('debuginstall', [], '')
1844 @command('debuginstall', [], '')
1844 def debuginstall(ui):
1845 def debuginstall(ui):
1845 '''test Mercurial installation
1846 '''test Mercurial installation
1846
1847
1847 Returns 0 on success.
1848 Returns 0 on success.
1848 '''
1849 '''
1849
1850
1850 def writetemp(contents):
1851 def writetemp(contents):
1851 (fd, name) = tempfile.mkstemp(prefix="hg-debuginstall-")
1852 (fd, name) = tempfile.mkstemp(prefix="hg-debuginstall-")
1852 f = os.fdopen(fd, "wb")
1853 f = os.fdopen(fd, "wb")
1853 f.write(contents)
1854 f.write(contents)
1854 f.close()
1855 f.close()
1855 return name
1856 return name
1856
1857
1857 problems = 0
1858 problems = 0
1858
1859
1859 # encoding
1860 # encoding
1860 ui.status(_("Checking encoding (%s)...\n") % encoding.encoding)
1861 ui.status(_("Checking encoding (%s)...\n") % encoding.encoding)
1861 try:
1862 try:
1862 encoding.fromlocal("test")
1863 encoding.fromlocal("test")
1863 except util.Abort, inst:
1864 except util.Abort, inst:
1864 ui.write(" %s\n" % inst)
1865 ui.write(" %s\n" % inst)
1865 ui.write(_(" (check that your locale is properly set)\n"))
1866 ui.write(_(" (check that your locale is properly set)\n"))
1866 problems += 1
1867 problems += 1
1867
1868
1868 # compiled modules
1869 # compiled modules
1869 ui.status(_("Checking installed modules (%s)...\n")
1870 ui.status(_("Checking installed modules (%s)...\n")
1870 % os.path.dirname(__file__))
1871 % os.path.dirname(__file__))
1871 try:
1872 try:
1872 import bdiff, mpatch, base85, osutil
1873 import bdiff, mpatch, base85, osutil
1873 dir(bdiff), dir(mpatch), dir(base85), dir(osutil) # quiet pyflakes
1874 dir(bdiff), dir(mpatch), dir(base85), dir(osutil) # quiet pyflakes
1874 except Exception, inst:
1875 except Exception, inst:
1875 ui.write(" %s\n" % inst)
1876 ui.write(" %s\n" % inst)
1876 ui.write(_(" One or more extensions could not be found"))
1877 ui.write(_(" One or more extensions could not be found"))
1877 ui.write(_(" (check that you compiled the extensions)\n"))
1878 ui.write(_(" (check that you compiled the extensions)\n"))
1878 problems += 1
1879 problems += 1
1879
1880
1880 # templates
1881 # templates
1881 import templater
1882 import templater
1882 p = templater.templatepath()
1883 p = templater.templatepath()
1883 ui.status(_("Checking templates (%s)...\n") % ' '.join(p))
1884 ui.status(_("Checking templates (%s)...\n") % ' '.join(p))
1884 try:
1885 try:
1885 templater.templater(templater.templatepath("map-cmdline.default"))
1886 templater.templater(templater.templatepath("map-cmdline.default"))
1886 except Exception, inst:
1887 except Exception, inst:
1887 ui.write(" %s\n" % inst)
1888 ui.write(" %s\n" % inst)
1888 ui.write(_(" (templates seem to have been installed incorrectly)\n"))
1889 ui.write(_(" (templates seem to have been installed incorrectly)\n"))
1889 problems += 1
1890 problems += 1
1890
1891
1891 # editor
1892 # editor
1892 ui.status(_("Checking commit editor...\n"))
1893 ui.status(_("Checking commit editor...\n"))
1893 editor = ui.geteditor()
1894 editor = ui.geteditor()
1894 cmdpath = util.findexe(editor) or util.findexe(editor.split()[0])
1895 cmdpath = util.findexe(editor) or util.findexe(editor.split()[0])
1895 if not cmdpath:
1896 if not cmdpath:
1896 if editor == 'vi':
1897 if editor == 'vi':
1897 ui.write(_(" No commit editor set and can't find vi in PATH\n"))
1898 ui.write(_(" No commit editor set and can't find vi in PATH\n"))
1898 ui.write(_(" (specify a commit editor in your configuration"
1899 ui.write(_(" (specify a commit editor in your configuration"
1899 " file)\n"))
1900 " file)\n"))
1900 else:
1901 else:
1901 ui.write(_(" Can't find editor '%s' in PATH\n") % editor)
1902 ui.write(_(" Can't find editor '%s' in PATH\n") % editor)
1902 ui.write(_(" (specify a commit editor in your configuration"
1903 ui.write(_(" (specify a commit editor in your configuration"
1903 " file)\n"))
1904 " file)\n"))
1904 problems += 1
1905 problems += 1
1905
1906
1906 # check username
1907 # check username
1907 ui.status(_("Checking username...\n"))
1908 ui.status(_("Checking username...\n"))
1908 try:
1909 try:
1909 ui.username()
1910 ui.username()
1910 except util.Abort, e:
1911 except util.Abort, e:
1911 ui.write(" %s\n" % e)
1912 ui.write(" %s\n" % e)
1912 ui.write(_(" (specify a username in your configuration file)\n"))
1913 ui.write(_(" (specify a username in your configuration file)\n"))
1913 problems += 1
1914 problems += 1
1914
1915
1915 if not problems:
1916 if not problems:
1916 ui.status(_("No problems detected\n"))
1917 ui.status(_("No problems detected\n"))
1917 else:
1918 else:
1918 ui.write(_("%s problems detected,"
1919 ui.write(_("%s problems detected,"
1919 " please check your install!\n") % problems)
1920 " please check your install!\n") % problems)
1920
1921
1921 return problems
1922 return problems
1922
1923
1923 @command('debugknown', [], _('REPO ID...'))
1924 @command('debugknown', [], _('REPO ID...'))
1924 def debugknown(ui, repopath, *ids, **opts):
1925 def debugknown(ui, repopath, *ids, **opts):
1925 """test whether node ids are known to a repo
1926 """test whether node ids are known to a repo
1926
1927
1927 Every ID must be a full-length hex node id string. Returns a list of 0s and 1s
1928 Every ID must be a full-length hex node id string. Returns a list of 0s and 1s
1928 indicating unknown/known.
1929 indicating unknown/known.
1929 """
1930 """
1930 repo = hg.peer(ui, opts, repopath)
1931 repo = hg.peer(ui, opts, repopath)
1931 if not repo.capable('known'):
1932 if not repo.capable('known'):
1932 raise util.Abort("known() not supported by target repository")
1933 raise util.Abort("known() not supported by target repository")
1933 flags = repo.known([bin(s) for s in ids])
1934 flags = repo.known([bin(s) for s in ids])
1934 ui.write("%s\n" % ("".join([f and "1" or "0" for f in flags])))
1935 ui.write("%s\n" % ("".join([f and "1" or "0" for f in flags])))
1935
1936
1936 @command('debugpushkey', [], _('REPO NAMESPACE [KEY OLD NEW]'))
1937 @command('debugpushkey', [], _('REPO NAMESPACE [KEY OLD NEW]'))
1937 def debugpushkey(ui, repopath, namespace, *keyinfo, **opts):
1938 def debugpushkey(ui, repopath, namespace, *keyinfo, **opts):
1938 '''access the pushkey key/value protocol
1939 '''access the pushkey key/value protocol
1939
1940
1940 With two args, list the keys in the given namespace.
1941 With two args, list the keys in the given namespace.
1941
1942
1942 With five args, set a key to new if it currently is set to old.
1943 With five args, set a key to new if it currently is set to old.
1943 Reports success or failure.
1944 Reports success or failure.
1944 '''
1945 '''
1945
1946
1946 target = hg.peer(ui, {}, repopath)
1947 target = hg.peer(ui, {}, repopath)
1947 if keyinfo:
1948 if keyinfo:
1948 key, old, new = keyinfo
1949 key, old, new = keyinfo
1949 r = target.pushkey(namespace, key, old, new)
1950 r = target.pushkey(namespace, key, old, new)
1950 ui.status(str(r) + '\n')
1951 ui.status(str(r) + '\n')
1951 return not r
1952 return not r
1952 else:
1953 else:
1953 for k, v in target.listkeys(namespace).iteritems():
1954 for k, v in target.listkeys(namespace).iteritems():
1954 ui.write("%s\t%s\n" % (k.encode('string-escape'),
1955 ui.write("%s\t%s\n" % (k.encode('string-escape'),
1955 v.encode('string-escape')))
1956 v.encode('string-escape')))
1956
1957
1957 @command('debugrebuildstate',
1958 @command('debugrebuildstate',
1958 [('r', 'rev', '', _('revision to rebuild to'), _('REV'))],
1959 [('r', 'rev', '', _('revision to rebuild to'), _('REV'))],
1959 _('[-r REV] [REV]'))
1960 _('[-r REV] [REV]'))
1960 def debugrebuildstate(ui, repo, rev="tip"):
1961 def debugrebuildstate(ui, repo, rev="tip"):
1961 """rebuild the dirstate as it would look like for the given revision"""
1962 """rebuild the dirstate as it would look like for the given revision"""
1962 ctx = scmutil.revsingle(repo, rev)
1963 ctx = scmutil.revsingle(repo, rev)
1963 wlock = repo.wlock()
1964 wlock = repo.wlock()
1964 try:
1965 try:
1965 repo.dirstate.rebuild(ctx.node(), ctx.manifest())
1966 repo.dirstate.rebuild(ctx.node(), ctx.manifest())
1966 finally:
1967 finally:
1967 wlock.release()
1968 wlock.release()
1968
1969
1969 @command('debugrename',
1970 @command('debugrename',
1970 [('r', 'rev', '', _('revision to debug'), _('REV'))],
1971 [('r', 'rev', '', _('revision to debug'), _('REV'))],
1971 _('[-r REV] FILE'))
1972 _('[-r REV] FILE'))
1972 def debugrename(ui, repo, file1, *pats, **opts):
1973 def debugrename(ui, repo, file1, *pats, **opts):
1973 """dump rename information"""
1974 """dump rename information"""
1974
1975
1975 ctx = scmutil.revsingle(repo, opts.get('rev'))
1976 ctx = scmutil.revsingle(repo, opts.get('rev'))
1976 m = scmutil.match(ctx, (file1,) + pats, opts)
1977 m = scmutil.match(ctx, (file1,) + pats, opts)
1977 for abs in ctx.walk(m):
1978 for abs in ctx.walk(m):
1978 fctx = ctx[abs]
1979 fctx = ctx[abs]
1979 o = fctx.filelog().renamed(fctx.filenode())
1980 o = fctx.filelog().renamed(fctx.filenode())
1980 rel = m.rel(abs)
1981 rel = m.rel(abs)
1981 if o:
1982 if o:
1982 ui.write(_("%s renamed from %s:%s\n") % (rel, o[0], hex(o[1])))
1983 ui.write(_("%s renamed from %s:%s\n") % (rel, o[0], hex(o[1])))
1983 else:
1984 else:
1984 ui.write(_("%s not renamed\n") % rel)
1985 ui.write(_("%s not renamed\n") % rel)
1985
1986
1986 @command('debugrevlog',
1987 @command('debugrevlog',
1987 [('c', 'changelog', False, _('open changelog')),
1988 [('c', 'changelog', False, _('open changelog')),
1988 ('m', 'manifest', False, _('open manifest')),
1989 ('m', 'manifest', False, _('open manifest')),
1989 ('d', 'dump', False, _('dump index data'))],
1990 ('d', 'dump', False, _('dump index data'))],
1990 _('-c|-m|FILE'))
1991 _('-c|-m|FILE'))
1991 def debugrevlog(ui, repo, file_ = None, **opts):
1992 def debugrevlog(ui, repo, file_ = None, **opts):
1992 """show data and statistics about a revlog"""
1993 """show data and statistics about a revlog"""
1993 r = cmdutil.openrevlog(repo, 'debugrevlog', file_, opts)
1994 r = cmdutil.openrevlog(repo, 'debugrevlog', file_, opts)
1994
1995
1995 if opts.get("dump"):
1996 if opts.get("dump"):
1996 numrevs = len(r)
1997 numrevs = len(r)
1997 ui.write("# rev p1rev p2rev start end deltastart base p1 p2"
1998 ui.write("# rev p1rev p2rev start end deltastart base p1 p2"
1998 " rawsize totalsize compression heads\n")
1999 " rawsize totalsize compression heads\n")
1999 ts = 0
2000 ts = 0
2000 heads = set()
2001 heads = set()
2001 for rev in xrange(numrevs):
2002 for rev in xrange(numrevs):
2002 dbase = r.deltaparent(rev)
2003 dbase = r.deltaparent(rev)
2003 if dbase == -1:
2004 if dbase == -1:
2004 dbase = rev
2005 dbase = rev
2005 cbase = r.chainbase(rev)
2006 cbase = r.chainbase(rev)
2006 p1, p2 = r.parentrevs(rev)
2007 p1, p2 = r.parentrevs(rev)
2007 rs = r.rawsize(rev)
2008 rs = r.rawsize(rev)
2008 ts = ts + rs
2009 ts = ts + rs
2009 heads -= set(r.parentrevs(rev))
2010 heads -= set(r.parentrevs(rev))
2010 heads.add(rev)
2011 heads.add(rev)
2011 ui.write("%d %d %d %d %d %d %d %d %d %d %d %d %d\n" %
2012 ui.write("%d %d %d %d %d %d %d %d %d %d %d %d %d\n" %
2012 (rev, p1, p2, r.start(rev), r.end(rev),
2013 (rev, p1, p2, r.start(rev), r.end(rev),
2013 r.start(dbase), r.start(cbase),
2014 r.start(dbase), r.start(cbase),
2014 r.start(p1), r.start(p2),
2015 r.start(p1), r.start(p2),
2015 rs, ts, ts / r.end(rev), len(heads)))
2016 rs, ts, ts / r.end(rev), len(heads)))
2016 return 0
2017 return 0
2017
2018
2018 v = r.version
2019 v = r.version
2019 format = v & 0xFFFF
2020 format = v & 0xFFFF
2020 flags = []
2021 flags = []
2021 gdelta = False
2022 gdelta = False
2022 if v & revlog.REVLOGNGINLINEDATA:
2023 if v & revlog.REVLOGNGINLINEDATA:
2023 flags.append('inline')
2024 flags.append('inline')
2024 if v & revlog.REVLOGGENERALDELTA:
2025 if v & revlog.REVLOGGENERALDELTA:
2025 gdelta = True
2026 gdelta = True
2026 flags.append('generaldelta')
2027 flags.append('generaldelta')
2027 if not flags:
2028 if not flags:
2028 flags = ['(none)']
2029 flags = ['(none)']
2029
2030
2030 nummerges = 0
2031 nummerges = 0
2031 numfull = 0
2032 numfull = 0
2032 numprev = 0
2033 numprev = 0
2033 nump1 = 0
2034 nump1 = 0
2034 nump2 = 0
2035 nump2 = 0
2035 numother = 0
2036 numother = 0
2036 nump1prev = 0
2037 nump1prev = 0
2037 nump2prev = 0
2038 nump2prev = 0
2038 chainlengths = []
2039 chainlengths = []
2039
2040
2040 datasize = [None, 0, 0L]
2041 datasize = [None, 0, 0L]
2041 fullsize = [None, 0, 0L]
2042 fullsize = [None, 0, 0L]
2042 deltasize = [None, 0, 0L]
2043 deltasize = [None, 0, 0L]
2043
2044
2044 def addsize(size, l):
2045 def addsize(size, l):
2045 if l[0] is None or size < l[0]:
2046 if l[0] is None or size < l[0]:
2046 l[0] = size
2047 l[0] = size
2047 if size > l[1]:
2048 if size > l[1]:
2048 l[1] = size
2049 l[1] = size
2049 l[2] += size
2050 l[2] += size
2050
2051
2051 numrevs = len(r)
2052 numrevs = len(r)
2052 for rev in xrange(numrevs):
2053 for rev in xrange(numrevs):
2053 p1, p2 = r.parentrevs(rev)
2054 p1, p2 = r.parentrevs(rev)
2054 delta = r.deltaparent(rev)
2055 delta = r.deltaparent(rev)
2055 if format > 0:
2056 if format > 0:
2056 addsize(r.rawsize(rev), datasize)
2057 addsize(r.rawsize(rev), datasize)
2057 if p2 != nullrev:
2058 if p2 != nullrev:
2058 nummerges += 1
2059 nummerges += 1
2059 size = r.length(rev)
2060 size = r.length(rev)
2060 if delta == nullrev:
2061 if delta == nullrev:
2061 chainlengths.append(0)
2062 chainlengths.append(0)
2062 numfull += 1
2063 numfull += 1
2063 addsize(size, fullsize)
2064 addsize(size, fullsize)
2064 else:
2065 else:
2065 chainlengths.append(chainlengths[delta] + 1)
2066 chainlengths.append(chainlengths[delta] + 1)
2066 addsize(size, deltasize)
2067 addsize(size, deltasize)
2067 if delta == rev - 1:
2068 if delta == rev - 1:
2068 numprev += 1
2069 numprev += 1
2069 if delta == p1:
2070 if delta == p1:
2070 nump1prev += 1
2071 nump1prev += 1
2071 elif delta == p2:
2072 elif delta == p2:
2072 nump2prev += 1
2073 nump2prev += 1
2073 elif delta == p1:
2074 elif delta == p1:
2074 nump1 += 1
2075 nump1 += 1
2075 elif delta == p2:
2076 elif delta == p2:
2076 nump2 += 1
2077 nump2 += 1
2077 elif delta != nullrev:
2078 elif delta != nullrev:
2078 numother += 1
2079 numother += 1
2079
2080
2080 numdeltas = numrevs - numfull
2081 numdeltas = numrevs - numfull
2081 numoprev = numprev - nump1prev - nump2prev
2082 numoprev = numprev - nump1prev - nump2prev
2082 totalrawsize = datasize[2]
2083 totalrawsize = datasize[2]
2083 datasize[2] /= numrevs
2084 datasize[2] /= numrevs
2084 fulltotal = fullsize[2]
2085 fulltotal = fullsize[2]
2085 fullsize[2] /= numfull
2086 fullsize[2] /= numfull
2086 deltatotal = deltasize[2]
2087 deltatotal = deltasize[2]
2087 deltasize[2] /= numrevs - numfull
2088 deltasize[2] /= numrevs - numfull
2088 totalsize = fulltotal + deltatotal
2089 totalsize = fulltotal + deltatotal
2089 avgchainlen = sum(chainlengths) / numrevs
2090 avgchainlen = sum(chainlengths) / numrevs
2090 compratio = totalrawsize / totalsize
2091 compratio = totalrawsize / totalsize
2091
2092
2092 basedfmtstr = '%%%dd\n'
2093 basedfmtstr = '%%%dd\n'
2093 basepcfmtstr = '%%%dd %s(%%5.2f%%%%)\n'
2094 basepcfmtstr = '%%%dd %s(%%5.2f%%%%)\n'
2094
2095
2095 def dfmtstr(max):
2096 def dfmtstr(max):
2096 return basedfmtstr % len(str(max))
2097 return basedfmtstr % len(str(max))
2097 def pcfmtstr(max, padding=0):
2098 def pcfmtstr(max, padding=0):
2098 return basepcfmtstr % (len(str(max)), ' ' * padding)
2099 return basepcfmtstr % (len(str(max)), ' ' * padding)
2099
2100
2100 def pcfmt(value, total):
2101 def pcfmt(value, total):
2101 return (value, 100 * float(value) / total)
2102 return (value, 100 * float(value) / total)
2102
2103
2103 ui.write('format : %d\n' % format)
2104 ui.write('format : %d\n' % format)
2104 ui.write('flags : %s\n' % ', '.join(flags))
2105 ui.write('flags : %s\n' % ', '.join(flags))
2105
2106
2106 ui.write('\n')
2107 ui.write('\n')
2107 fmt = pcfmtstr(totalsize)
2108 fmt = pcfmtstr(totalsize)
2108 fmt2 = dfmtstr(totalsize)
2109 fmt2 = dfmtstr(totalsize)
2109 ui.write('revisions : ' + fmt2 % numrevs)
2110 ui.write('revisions : ' + fmt2 % numrevs)
2110 ui.write(' merges : ' + fmt % pcfmt(nummerges, numrevs))
2111 ui.write(' merges : ' + fmt % pcfmt(nummerges, numrevs))
2111 ui.write(' normal : ' + fmt % pcfmt(numrevs - nummerges, numrevs))
2112 ui.write(' normal : ' + fmt % pcfmt(numrevs - nummerges, numrevs))
2112 ui.write('revisions : ' + fmt2 % numrevs)
2113 ui.write('revisions : ' + fmt2 % numrevs)
2113 ui.write(' full : ' + fmt % pcfmt(numfull, numrevs))
2114 ui.write(' full : ' + fmt % pcfmt(numfull, numrevs))
2114 ui.write(' deltas : ' + fmt % pcfmt(numdeltas, numrevs))
2115 ui.write(' deltas : ' + fmt % pcfmt(numdeltas, numrevs))
2115 ui.write('revision size : ' + fmt2 % totalsize)
2116 ui.write('revision size : ' + fmt2 % totalsize)
2116 ui.write(' full : ' + fmt % pcfmt(fulltotal, totalsize))
2117 ui.write(' full : ' + fmt % pcfmt(fulltotal, totalsize))
2117 ui.write(' deltas : ' + fmt % pcfmt(deltatotal, totalsize))
2118 ui.write(' deltas : ' + fmt % pcfmt(deltatotal, totalsize))
2118
2119
2119 ui.write('\n')
2120 ui.write('\n')
2120 fmt = dfmtstr(max(avgchainlen, compratio))
2121 fmt = dfmtstr(max(avgchainlen, compratio))
2121 ui.write('avg chain length : ' + fmt % avgchainlen)
2122 ui.write('avg chain length : ' + fmt % avgchainlen)
2122 ui.write('compression ratio : ' + fmt % compratio)
2123 ui.write('compression ratio : ' + fmt % compratio)
2123
2124
2124 if format > 0:
2125 if format > 0:
2125 ui.write('\n')
2126 ui.write('\n')
2126 ui.write('uncompressed data size (min/max/avg) : %d / %d / %d\n'
2127 ui.write('uncompressed data size (min/max/avg) : %d / %d / %d\n'
2127 % tuple(datasize))
2128 % tuple(datasize))
2128 ui.write('full revision size (min/max/avg) : %d / %d / %d\n'
2129 ui.write('full revision size (min/max/avg) : %d / %d / %d\n'
2129 % tuple(fullsize))
2130 % tuple(fullsize))
2130 ui.write('delta size (min/max/avg) : %d / %d / %d\n'
2131 ui.write('delta size (min/max/avg) : %d / %d / %d\n'
2131 % tuple(deltasize))
2132 % tuple(deltasize))
2132
2133
2133 if numdeltas > 0:
2134 if numdeltas > 0:
2134 ui.write('\n')
2135 ui.write('\n')
2135 fmt = pcfmtstr(numdeltas)
2136 fmt = pcfmtstr(numdeltas)
2136 fmt2 = pcfmtstr(numdeltas, 4)
2137 fmt2 = pcfmtstr(numdeltas, 4)
2137 ui.write('deltas against prev : ' + fmt % pcfmt(numprev, numdeltas))
2138 ui.write('deltas against prev : ' + fmt % pcfmt(numprev, numdeltas))
2138 if numprev > 0:
2139 if numprev > 0:
2139 ui.write(' where prev = p1 : ' + fmt2 % pcfmt(nump1prev, numprev))
2140 ui.write(' where prev = p1 : ' + fmt2 % pcfmt(nump1prev, numprev))
2140 ui.write(' where prev = p2 : ' + fmt2 % pcfmt(nump2prev, numprev))
2141 ui.write(' where prev = p2 : ' + fmt2 % pcfmt(nump2prev, numprev))
2141 ui.write(' other : ' + fmt2 % pcfmt(numoprev, numprev))
2142 ui.write(' other : ' + fmt2 % pcfmt(numoprev, numprev))
2142 if gdelta:
2143 if gdelta:
2143 ui.write('deltas against p1 : ' + fmt % pcfmt(nump1, numdeltas))
2144 ui.write('deltas against p1 : ' + fmt % pcfmt(nump1, numdeltas))
2144 ui.write('deltas against p2 : ' + fmt % pcfmt(nump2, numdeltas))
2145 ui.write('deltas against p2 : ' + fmt % pcfmt(nump2, numdeltas))
2145 ui.write('deltas against other : ' + fmt % pcfmt(numother, numdeltas))
2146 ui.write('deltas against other : ' + fmt % pcfmt(numother, numdeltas))
2146
2147
2147 @command('debugrevspec', [], ('REVSPEC'))
2148 @command('debugrevspec', [], ('REVSPEC'))
2148 def debugrevspec(ui, repo, expr):
2149 def debugrevspec(ui, repo, expr):
2149 '''parse and apply a revision specification'''
2150 '''parse and apply a revision specification'''
2150 if ui.verbose:
2151 if ui.verbose:
2151 tree = revset.parse(expr)[0]
2152 tree = revset.parse(expr)[0]
2152 ui.note(tree, "\n")
2153 ui.note(tree, "\n")
2153 newtree = revset.findaliases(ui, tree)
2154 newtree = revset.findaliases(ui, tree)
2154 if newtree != tree:
2155 if newtree != tree:
2155 ui.note(newtree, "\n")
2156 ui.note(newtree, "\n")
2156 func = revset.match(ui, expr)
2157 func = revset.match(ui, expr)
2157 for c in func(repo, range(len(repo))):
2158 for c in func(repo, range(len(repo))):
2158 ui.write("%s\n" % c)
2159 ui.write("%s\n" % c)
2159
2160
2160 @command('debugsetparents', [], _('REV1 [REV2]'))
2161 @command('debugsetparents', [], _('REV1 [REV2]'))
2161 def debugsetparents(ui, repo, rev1, rev2=None):
2162 def debugsetparents(ui, repo, rev1, rev2=None):
2162 """manually set the parents of the current working directory
2163 """manually set the parents of the current working directory
2163
2164
2164 This is useful for writing repository conversion tools, but should
2165 This is useful for writing repository conversion tools, but should
2165 be used with care.
2166 be used with care.
2166
2167
2167 Returns 0 on success.
2168 Returns 0 on success.
2168 """
2169 """
2169
2170
2170 r1 = scmutil.revsingle(repo, rev1).node()
2171 r1 = scmutil.revsingle(repo, rev1).node()
2171 r2 = scmutil.revsingle(repo, rev2, 'null').node()
2172 r2 = scmutil.revsingle(repo, rev2, 'null').node()
2172
2173
2173 wlock = repo.wlock()
2174 wlock = repo.wlock()
2174 try:
2175 try:
2175 repo.dirstate.setparents(r1, r2)
2176 repo.dirstate.setparents(r1, r2)
2176 finally:
2177 finally:
2177 wlock.release()
2178 wlock.release()
2178
2179
2179 @command('debugstate',
2180 @command('debugstate',
2180 [('', 'nodates', None, _('do not display the saved mtime')),
2181 [('', 'nodates', None, _('do not display the saved mtime')),
2181 ('', 'datesort', None, _('sort by saved mtime'))],
2182 ('', 'datesort', None, _('sort by saved mtime'))],
2182 _('[OPTION]...'))
2183 _('[OPTION]...'))
2183 def debugstate(ui, repo, nodates=None, datesort=None):
2184 def debugstate(ui, repo, nodates=None, datesort=None):
2184 """show the contents of the current dirstate"""
2185 """show the contents of the current dirstate"""
2185 timestr = ""
2186 timestr = ""
2186 showdate = not nodates
2187 showdate = not nodates
2187 if datesort:
2188 if datesort:
2188 keyfunc = lambda x: (x[1][3], x[0]) # sort by mtime, then by filename
2189 keyfunc = lambda x: (x[1][3], x[0]) # sort by mtime, then by filename
2189 else:
2190 else:
2190 keyfunc = None # sort by filename
2191 keyfunc = None # sort by filename
2191 for file_, ent in sorted(repo.dirstate._map.iteritems(), key=keyfunc):
2192 for file_, ent in sorted(repo.dirstate._map.iteritems(), key=keyfunc):
2192 if showdate:
2193 if showdate:
2193 if ent[3] == -1:
2194 if ent[3] == -1:
2194 # Pad or slice to locale representation
2195 # Pad or slice to locale representation
2195 locale_len = len(time.strftime("%Y-%m-%d %H:%M:%S ",
2196 locale_len = len(time.strftime("%Y-%m-%d %H:%M:%S ",
2196 time.localtime(0)))
2197 time.localtime(0)))
2197 timestr = 'unset'
2198 timestr = 'unset'
2198 timestr = (timestr[:locale_len] +
2199 timestr = (timestr[:locale_len] +
2199 ' ' * (locale_len - len(timestr)))
2200 ' ' * (locale_len - len(timestr)))
2200 else:
2201 else:
2201 timestr = time.strftime("%Y-%m-%d %H:%M:%S ",
2202 timestr = time.strftime("%Y-%m-%d %H:%M:%S ",
2202 time.localtime(ent[3]))
2203 time.localtime(ent[3]))
2203 if ent[1] & 020000:
2204 if ent[1] & 020000:
2204 mode = 'lnk'
2205 mode = 'lnk'
2205 else:
2206 else:
2206 mode = '%3o' % (ent[1] & 0777 & ~util.umask)
2207 mode = '%3o' % (ent[1] & 0777 & ~util.umask)
2207 ui.write("%c %s %10d %s%s\n" % (ent[0], mode, ent[2], timestr, file_))
2208 ui.write("%c %s %10d %s%s\n" % (ent[0], mode, ent[2], timestr, file_))
2208 for f in repo.dirstate.copies():
2209 for f in repo.dirstate.copies():
2209 ui.write(_("copy: %s -> %s\n") % (repo.dirstate.copied(f), f))
2210 ui.write(_("copy: %s -> %s\n") % (repo.dirstate.copied(f), f))
2210
2211
2211 @command('debugsub',
2212 @command('debugsub',
2212 [('r', 'rev', '',
2213 [('r', 'rev', '',
2213 _('revision to check'), _('REV'))],
2214 _('revision to check'), _('REV'))],
2214 _('[-r REV] [REV]'))
2215 _('[-r REV] [REV]'))
2215 def debugsub(ui, repo, rev=None):
2216 def debugsub(ui, repo, rev=None):
2216 ctx = scmutil.revsingle(repo, rev, None)
2217 ctx = scmutil.revsingle(repo, rev, None)
2217 for k, v in sorted(ctx.substate.items()):
2218 for k, v in sorted(ctx.substate.items()):
2218 ui.write('path %s\n' % k)
2219 ui.write('path %s\n' % k)
2219 ui.write(' source %s\n' % v[0])
2220 ui.write(' source %s\n' % v[0])
2220 ui.write(' revision %s\n' % v[1])
2221 ui.write(' revision %s\n' % v[1])
2221
2222
2222 @command('debugwalk', walkopts, _('[OPTION]... [FILE]...'))
2223 @command('debugwalk', walkopts, _('[OPTION]... [FILE]...'))
2223 def debugwalk(ui, repo, *pats, **opts):
2224 def debugwalk(ui, repo, *pats, **opts):
2224 """show how files match on given patterns"""
2225 """show how files match on given patterns"""
2225 m = scmutil.match(repo[None], pats, opts)
2226 m = scmutil.match(repo[None], pats, opts)
2226 items = list(repo.walk(m))
2227 items = list(repo.walk(m))
2227 if not items:
2228 if not items:
2228 return
2229 return
2229 fmt = 'f %%-%ds %%-%ds %%s' % (
2230 fmt = 'f %%-%ds %%-%ds %%s' % (
2230 max([len(abs) for abs in items]),
2231 max([len(abs) for abs in items]),
2231 max([len(m.rel(abs)) for abs in items]))
2232 max([len(m.rel(abs)) for abs in items]))
2232 for abs in items:
2233 for abs in items:
2233 line = fmt % (abs, m.rel(abs), m.exact(abs) and 'exact' or '')
2234 line = fmt % (abs, m.rel(abs), m.exact(abs) and 'exact' or '')
2234 ui.write("%s\n" % line.rstrip())
2235 ui.write("%s\n" % line.rstrip())
2235
2236
2236 @command('debugwireargs',
2237 @command('debugwireargs',
2237 [('', 'three', '', 'three'),
2238 [('', 'three', '', 'three'),
2238 ('', 'four', '', 'four'),
2239 ('', 'four', '', 'four'),
2239 ('', 'five', '', 'five'),
2240 ('', 'five', '', 'five'),
2240 ] + remoteopts,
2241 ] + remoteopts,
2241 _('REPO [OPTIONS]... [ONE [TWO]]'))
2242 _('REPO [OPTIONS]... [ONE [TWO]]'))
2242 def debugwireargs(ui, repopath, *vals, **opts):
2243 def debugwireargs(ui, repopath, *vals, **opts):
2243 repo = hg.peer(ui, opts, repopath)
2244 repo = hg.peer(ui, opts, repopath)
2244 for opt in remoteopts:
2245 for opt in remoteopts:
2245 del opts[opt[1]]
2246 del opts[opt[1]]
2246 args = {}
2247 args = {}
2247 for k, v in opts.iteritems():
2248 for k, v in opts.iteritems():
2248 if v:
2249 if v:
2249 args[k] = v
2250 args[k] = v
2250 # run twice to check that we don't mess up the stream for the next command
2251 # run twice to check that we don't mess up the stream for the next command
2251 res1 = repo.debugwireargs(*vals, **args)
2252 res1 = repo.debugwireargs(*vals, **args)
2252 res2 = repo.debugwireargs(*vals, **args)
2253 res2 = repo.debugwireargs(*vals, **args)
2253 ui.write("%s\n" % res1)
2254 ui.write("%s\n" % res1)
2254 if res1 != res2:
2255 if res1 != res2:
2255 ui.warn("%s\n" % res2)
2256 ui.warn("%s\n" % res2)
2256
2257
2257 @command('^diff',
2258 @command('^diff',
2258 [('r', 'rev', [], _('revision'), _('REV')),
2259 [('r', 'rev', [], _('revision'), _('REV')),
2259 ('c', 'change', '', _('change made by revision'), _('REV'))
2260 ('c', 'change', '', _('change made by revision'), _('REV'))
2260 ] + diffopts + diffopts2 + walkopts + subrepoopts,
2261 ] + diffopts + diffopts2 + walkopts + subrepoopts,
2261 _('[OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...'))
2262 _('[OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...'))
2262 def diff(ui, repo, *pats, **opts):
2263 def diff(ui, repo, *pats, **opts):
2263 """diff repository (or selected files)
2264 """diff repository (or selected files)
2264
2265
2265 Show differences between revisions for the specified files.
2266 Show differences between revisions for the specified files.
2266
2267
2267 Differences between files are shown using the unified diff format.
2268 Differences between files are shown using the unified diff format.
2268
2269
2269 .. note::
2270 .. note::
2270 diff may generate unexpected results for merges, as it will
2271 diff may generate unexpected results for merges, as it will
2271 default to comparing against the working directory's first
2272 default to comparing against the working directory's first
2272 parent changeset if no revisions are specified.
2273 parent changeset if no revisions are specified.
2273
2274
2274 When two revision arguments are given, then changes are shown
2275 When two revision arguments are given, then changes are shown
2275 between those revisions. If only one revision is specified then
2276 between those revisions. If only one revision is specified then
2276 that revision is compared to the working directory, and, when no
2277 that revision is compared to the working directory, and, when no
2277 revisions are specified, the working directory files are compared
2278 revisions are specified, the working directory files are compared
2278 to its parent.
2279 to its parent.
2279
2280
2280 Alternatively you can specify -c/--change with a revision to see
2281 Alternatively you can specify -c/--change with a revision to see
2281 the changes in that changeset relative to its first parent.
2282 the changes in that changeset relative to its first parent.
2282
2283
2283 Without the -a/--text option, diff will avoid generating diffs of
2284 Without the -a/--text option, diff will avoid generating diffs of
2284 files it detects as binary. With -a, diff will generate a diff
2285 files it detects as binary. With -a, diff will generate a diff
2285 anyway, probably with undesirable results.
2286 anyway, probably with undesirable results.
2286
2287
2287 Use the -g/--git option to generate diffs in the git extended diff
2288 Use the -g/--git option to generate diffs in the git extended diff
2288 format. For more information, read :hg:`help diffs`.
2289 format. For more information, read :hg:`help diffs`.
2289
2290
2290 .. container:: verbose
2291 .. container:: verbose
2291
2292
2292 Examples:
2293 Examples:
2293
2294
2294 - compare a file in the current working directory to its parent::
2295 - compare a file in the current working directory to its parent::
2295
2296
2296 hg diff foo.c
2297 hg diff foo.c
2297
2298
2298 - compare two historical versions of a directory, with rename info::
2299 - compare two historical versions of a directory, with rename info::
2299
2300
2300 hg diff --git -r 1.0:1.2 lib/
2301 hg diff --git -r 1.0:1.2 lib/
2301
2302
2302 - get change stats relative to the last change on some date::
2303 - get change stats relative to the last change on some date::
2303
2304
2304 hg diff --stat -r "date('may 2')"
2305 hg diff --stat -r "date('may 2')"
2305
2306
2306 - diff all newly-added files that contain a keyword::
2307 - diff all newly-added files that contain a keyword::
2307
2308
2308 hg diff "set:added() and grep(GNU)"
2309 hg diff "set:added() and grep(GNU)"
2309
2310
2310 - compare a revision and its parents::
2311 - compare a revision and its parents::
2311
2312
2312 hg diff -c 9353 # compare against first parent
2313 hg diff -c 9353 # compare against first parent
2313 hg diff -r 9353^:9353 # same using revset syntax
2314 hg diff -r 9353^:9353 # same using revset syntax
2314 hg diff -r 9353^2:9353 # compare against the second parent
2315 hg diff -r 9353^2:9353 # compare against the second parent
2315
2316
2316 Returns 0 on success.
2317 Returns 0 on success.
2317 """
2318 """
2318
2319
2319 revs = opts.get('rev')
2320 revs = opts.get('rev')
2320 change = opts.get('change')
2321 change = opts.get('change')
2321 stat = opts.get('stat')
2322 stat = opts.get('stat')
2322 reverse = opts.get('reverse')
2323 reverse = opts.get('reverse')
2323
2324
2324 if revs and change:
2325 if revs and change:
2325 msg = _('cannot specify --rev and --change at the same time')
2326 msg = _('cannot specify --rev and --change at the same time')
2326 raise util.Abort(msg)
2327 raise util.Abort(msg)
2327 elif change:
2328 elif change:
2328 node2 = scmutil.revsingle(repo, change, None).node()
2329 node2 = scmutil.revsingle(repo, change, None).node()
2329 node1 = repo[node2].p1().node()
2330 node1 = repo[node2].p1().node()
2330 else:
2331 else:
2331 node1, node2 = scmutil.revpair(repo, revs)
2332 node1, node2 = scmutil.revpair(repo, revs)
2332
2333
2333 if reverse:
2334 if reverse:
2334 node1, node2 = node2, node1
2335 node1, node2 = node2, node1
2335
2336
2336 diffopts = patch.diffopts(ui, opts)
2337 diffopts = patch.diffopts(ui, opts)
2337 m = scmutil.match(repo[node2], pats, opts)
2338 m = scmutil.match(repo[node2], pats, opts)
2338 cmdutil.diffordiffstat(ui, repo, diffopts, node1, node2, m, stat=stat,
2339 cmdutil.diffordiffstat(ui, repo, diffopts, node1, node2, m, stat=stat,
2339 listsubrepos=opts.get('subrepos'))
2340 listsubrepos=opts.get('subrepos'))
2340
2341
2341 @command('^export',
2342 @command('^export',
2342 [('o', 'output', '',
2343 [('o', 'output', '',
2343 _('print output to file with formatted name'), _('FORMAT')),
2344 _('print output to file with formatted name'), _('FORMAT')),
2344 ('', 'switch-parent', None, _('diff against the second parent')),
2345 ('', 'switch-parent', None, _('diff against the second parent')),
2345 ('r', 'rev', [], _('revisions to export'), _('REV')),
2346 ('r', 'rev', [], _('revisions to export'), _('REV')),
2346 ] + diffopts,
2347 ] + diffopts,
2347 _('[OPTION]... [-o OUTFILESPEC] REV...'))
2348 _('[OPTION]... [-o OUTFILESPEC] REV...'))
2348 def export(ui, repo, *changesets, **opts):
2349 def export(ui, repo, *changesets, **opts):
2349 """dump the header and diffs for one or more changesets
2350 """dump the header and diffs for one or more changesets
2350
2351
2351 Print the changeset header and diffs for one or more revisions.
2352 Print the changeset header and diffs for one or more revisions.
2352
2353
2353 The information shown in the changeset header is: author, date,
2354 The information shown in the changeset header is: author, date,
2354 branch name (if non-default), changeset hash, parent(s) and commit
2355 branch name (if non-default), changeset hash, parent(s) and commit
2355 comment.
2356 comment.
2356
2357
2357 .. note::
2358 .. note::
2358 export may generate unexpected diff output for merge
2359 export may generate unexpected diff output for merge
2359 changesets, as it will compare the merge changeset against its
2360 changesets, as it will compare the merge changeset against its
2360 first parent only.
2361 first parent only.
2361
2362
2362 Output may be to a file, in which case the name of the file is
2363 Output may be to a file, in which case the name of the file is
2363 given using a format string. The formatting rules are as follows:
2364 given using a format string. The formatting rules are as follows:
2364
2365
2365 :``%%``: literal "%" character
2366 :``%%``: literal "%" character
2366 :``%H``: changeset hash (40 hexadecimal digits)
2367 :``%H``: changeset hash (40 hexadecimal digits)
2367 :``%N``: number of patches being generated
2368 :``%N``: number of patches being generated
2368 :``%R``: changeset revision number
2369 :``%R``: changeset revision number
2369 :``%b``: basename of the exporting repository
2370 :``%b``: basename of the exporting repository
2370 :``%h``: short-form changeset hash (12 hexadecimal digits)
2371 :``%h``: short-form changeset hash (12 hexadecimal digits)
2371 :``%m``: first line of the commit message (only alphanumeric characters)
2372 :``%m``: first line of the commit message (only alphanumeric characters)
2372 :``%n``: zero-padded sequence number, starting at 1
2373 :``%n``: zero-padded sequence number, starting at 1
2373 :``%r``: zero-padded changeset revision number
2374 :``%r``: zero-padded changeset revision number
2374
2375
2375 Without the -a/--text option, export will avoid generating diffs
2376 Without the -a/--text option, export will avoid generating diffs
2376 of files it detects as binary. With -a, export will generate a
2377 of files it detects as binary. With -a, export will generate a
2377 diff anyway, probably with undesirable results.
2378 diff anyway, probably with undesirable results.
2378
2379
2379 Use the -g/--git option to generate diffs in the git extended diff
2380 Use the -g/--git option to generate diffs in the git extended diff
2380 format. See :hg:`help diffs` for more information.
2381 format. See :hg:`help diffs` for more information.
2381
2382
2382 With the --switch-parent option, the diff will be against the
2383 With the --switch-parent option, the diff will be against the
2383 second parent. It can be useful to review a merge.
2384 second parent. It can be useful to review a merge.
2384
2385
2385 .. container:: verbose
2386 .. container:: verbose
2386
2387
2387 Examples:
2388 Examples:
2388
2389
2389 - use export and import to transplant a bugfix to the current
2390 - use export and import to transplant a bugfix to the current
2390 branch::
2391 branch::
2391
2392
2392 hg export -r 9353 | hg import -
2393 hg export -r 9353 | hg import -
2393
2394
2394 - export all the changesets between two revisions to a file with
2395 - export all the changesets between two revisions to a file with
2395 rename information::
2396 rename information::
2396
2397
2397 hg export --git -r 123:150 > changes.txt
2398 hg export --git -r 123:150 > changes.txt
2398
2399
2399 - split outgoing changes into a series of patches with
2400 - split outgoing changes into a series of patches with
2400 descriptive names::
2401 descriptive names::
2401
2402
2402 hg export -r "outgoing()" -o "%n-%m.patch"
2403 hg export -r "outgoing()" -o "%n-%m.patch"
2403
2404
2404 Returns 0 on success.
2405 Returns 0 on success.
2405 """
2406 """
2406 changesets += tuple(opts.get('rev', []))
2407 changesets += tuple(opts.get('rev', []))
2407 if not changesets:
2408 if not changesets:
2408 raise util.Abort(_("export requires at least one changeset"))
2409 raise util.Abort(_("export requires at least one changeset"))
2409 revs = scmutil.revrange(repo, changesets)
2410 revs = scmutil.revrange(repo, changesets)
2410 if len(revs) > 1:
2411 if len(revs) > 1:
2411 ui.note(_('exporting patches:\n'))
2412 ui.note(_('exporting patches:\n'))
2412 else:
2413 else:
2413 ui.note(_('exporting patch:\n'))
2414 ui.note(_('exporting patch:\n'))
2414 cmdutil.export(repo, revs, template=opts.get('output'),
2415 cmdutil.export(repo, revs, template=opts.get('output'),
2415 switch_parent=opts.get('switch_parent'),
2416 switch_parent=opts.get('switch_parent'),
2416 opts=patch.diffopts(ui, opts))
2417 opts=patch.diffopts(ui, opts))
2417
2418
2418 @command('^forget', walkopts, _('[OPTION]... FILE...'))
2419 @command('^forget', walkopts, _('[OPTION]... FILE...'))
2419 def forget(ui, repo, *pats, **opts):
2420 def forget(ui, repo, *pats, **opts):
2420 """forget the specified files on the next commit
2421 """forget the specified files on the next commit
2421
2422
2422 Mark the specified files so they will no longer be tracked
2423 Mark the specified files so they will no longer be tracked
2423 after the next commit.
2424 after the next commit.
2424
2425
2425 This only removes files from the current branch, not from the
2426 This only removes files from the current branch, not from the
2426 entire project history, and it does not delete them from the
2427 entire project history, and it does not delete them from the
2427 working directory.
2428 working directory.
2428
2429
2429 To undo a forget before the next commit, see :hg:`add`.
2430 To undo a forget before the next commit, see :hg:`add`.
2430
2431
2431 .. container:: verbose
2432 .. container:: verbose
2432
2433
2433 Examples:
2434 Examples:
2434
2435
2435 - forget newly-added binary files::
2436 - forget newly-added binary files::
2436
2437
2437 hg forget "set:added() and binary()"
2438 hg forget "set:added() and binary()"
2438
2439
2439 - forget files that would be excluded by .hgignore::
2440 - forget files that would be excluded by .hgignore::
2440
2441
2441 hg forget "set:hgignore()"
2442 hg forget "set:hgignore()"
2442
2443
2443 Returns 0 on success.
2444 Returns 0 on success.
2444 """
2445 """
2445
2446
2446 if not pats:
2447 if not pats:
2447 raise util.Abort(_('no files specified'))
2448 raise util.Abort(_('no files specified'))
2448
2449
2449 wctx = repo[None]
2450 wctx = repo[None]
2450 m = scmutil.match(wctx, pats, opts)
2451 m = scmutil.match(wctx, pats, opts)
2451 s = repo.status(match=m, clean=True)
2452 s = repo.status(match=m, clean=True)
2452 forget = sorted(s[0] + s[1] + s[3] + s[6])
2453 forget = sorted(s[0] + s[1] + s[3] + s[6])
2453 subforget = {}
2454 subforget = {}
2454 errs = 0
2455 errs = 0
2455
2456
2456 for subpath in wctx.substate:
2457 for subpath in wctx.substate:
2457 sub = wctx.sub(subpath)
2458 sub = wctx.sub(subpath)
2458 try:
2459 try:
2459 submatch = matchmod.narrowmatcher(subpath, m)
2460 submatch = matchmod.narrowmatcher(subpath, m)
2460 for fsub in sub.walk(submatch):
2461 for fsub in sub.walk(submatch):
2461 if submatch.exact(fsub):
2462 if submatch.exact(fsub):
2462 subforget[subpath + '/' + fsub] = (fsub, sub)
2463 subforget[subpath + '/' + fsub] = (fsub, sub)
2463 except error.LookupError:
2464 except error.LookupError:
2464 ui.status(_("skipping missing subrepository: %s\n") % subpath)
2465 ui.status(_("skipping missing subrepository: %s\n") % subpath)
2465
2466
2466 for f in m.files():
2467 for f in m.files():
2467 if f not in repo.dirstate and not os.path.isdir(m.rel(f)):
2468 if f not in repo.dirstate and not os.path.isdir(m.rel(f)):
2468 if f not in subforget:
2469 if f not in subforget:
2469 if os.path.exists(m.rel(f)):
2470 if os.path.exists(m.rel(f)):
2470 ui.warn(_('not removing %s: file is already untracked\n')
2471 ui.warn(_('not removing %s: file is already untracked\n')
2471 % m.rel(f))
2472 % m.rel(f))
2472 errs = 1
2473 errs = 1
2473
2474
2474 for f in forget:
2475 for f in forget:
2475 if ui.verbose or not m.exact(f):
2476 if ui.verbose or not m.exact(f):
2476 ui.status(_('removing %s\n') % m.rel(f))
2477 ui.status(_('removing %s\n') % m.rel(f))
2477
2478
2478 if ui.verbose:
2479 if ui.verbose:
2479 for f in sorted(subforget.keys()):
2480 for f in sorted(subforget.keys()):
2480 ui.status(_('removing %s\n') % m.rel(f))
2481 ui.status(_('removing %s\n') % m.rel(f))
2481
2482
2482 wctx.forget(forget)
2483 wctx.forget(forget)
2483
2484
2484 for f in sorted(subforget.keys()):
2485 for f in sorted(subforget.keys()):
2485 fsub, sub = subforget[f]
2486 fsub, sub = subforget[f]
2486 sub.forget([fsub])
2487 sub.forget([fsub])
2487
2488
2488 return errs
2489 return errs
2489
2490
2490 @command(
2491 @command(
2491 'graft',
2492 'graft',
2492 [('c', 'continue', False, _('resume interrupted graft')),
2493 [('c', 'continue', False, _('resume interrupted graft')),
2493 ('e', 'edit', False, _('invoke editor on commit messages')),
2494 ('e', 'edit', False, _('invoke editor on commit messages')),
2494 ('D', 'currentdate', False,
2495 ('D', 'currentdate', False,
2495 _('record the current date as commit date')),
2496 _('record the current date as commit date')),
2496 ('U', 'currentuser', False,
2497 ('U', 'currentuser', False,
2497 _('record the current user as committer'), _('DATE'))]
2498 _('record the current user as committer'), _('DATE'))]
2498 + commitopts2 + mergetoolopts,
2499 + commitopts2 + mergetoolopts,
2499 _('[OPTION]... REVISION...'))
2500 _('[OPTION]... REVISION...'))
2500 def graft(ui, repo, *revs, **opts):
2501 def graft(ui, repo, *revs, **opts):
2501 '''copy changes from other branches onto the current branch
2502 '''copy changes from other branches onto the current branch
2502
2503
2503 This command uses Mercurial's merge logic to copy individual
2504 This command uses Mercurial's merge logic to copy individual
2504 changes from other branches without merging branches in the
2505 changes from other branches without merging branches in the
2505 history graph. This is sometimes known as 'backporting' or
2506 history graph. This is sometimes known as 'backporting' or
2506 'cherry-picking'. By default, graft will copy user, date, and
2507 'cherry-picking'. By default, graft will copy user, date, and
2507 description from the source changesets.
2508 description from the source changesets.
2508
2509
2509 Changesets that are ancestors of the current revision, that have
2510 Changesets that are ancestors of the current revision, that have
2510 already been grafted, or that are merges will be skipped.
2511 already been grafted, or that are merges will be skipped.
2511
2512
2512 If a graft merge results in conflicts, the graft process is
2513 If a graft merge results in conflicts, the graft process is
2513 interrupted so that the current merge can be manually resolved.
2514 interrupted so that the current merge can be manually resolved.
2514 Once all conflicts are addressed, the graft process can be
2515 Once all conflicts are addressed, the graft process can be
2515 continued with the -c/--continue option.
2516 continued with the -c/--continue option.
2516
2517
2517 .. note::
2518 .. note::
2518 The -c/--continue option does not reapply earlier options.
2519 The -c/--continue option does not reapply earlier options.
2519
2520
2520 .. container:: verbose
2521 .. container:: verbose
2521
2522
2522 Examples:
2523 Examples:
2523
2524
2524 - copy a single change to the stable branch and edit its description::
2525 - copy a single change to the stable branch and edit its description::
2525
2526
2526 hg update stable
2527 hg update stable
2527 hg graft --edit 9393
2528 hg graft --edit 9393
2528
2529
2529 - graft a range of changesets with one exception, updating dates::
2530 - graft a range of changesets with one exception, updating dates::
2530
2531
2531 hg graft -D "2085::2093 and not 2091"
2532 hg graft -D "2085::2093 and not 2091"
2532
2533
2533 - continue a graft after resolving conflicts::
2534 - continue a graft after resolving conflicts::
2534
2535
2535 hg graft -c
2536 hg graft -c
2536
2537
2537 - show the source of a grafted changeset::
2538 - show the source of a grafted changeset::
2538
2539
2539 hg log --debug -r tip
2540 hg log --debug -r tip
2540
2541
2541 Returns 0 on successful completion.
2542 Returns 0 on successful completion.
2542 '''
2543 '''
2543
2544
2544 if not opts.get('user') and opts.get('currentuser'):
2545 if not opts.get('user') and opts.get('currentuser'):
2545 opts['user'] = ui.username()
2546 opts['user'] = ui.username()
2546 if not opts.get('date') and opts.get('currentdate'):
2547 if not opts.get('date') and opts.get('currentdate'):
2547 opts['date'] = "%d %d" % util.makedate()
2548 opts['date'] = "%d %d" % util.makedate()
2548
2549
2549 editor = None
2550 editor = None
2550 if opts.get('edit'):
2551 if opts.get('edit'):
2551 editor = cmdutil.commitforceeditor
2552 editor = cmdutil.commitforceeditor
2552
2553
2553 cont = False
2554 cont = False
2554 if opts['continue']:
2555 if opts['continue']:
2555 cont = True
2556 cont = True
2556 if revs:
2557 if revs:
2557 raise util.Abort(_("can't specify --continue and revisions"))
2558 raise util.Abort(_("can't specify --continue and revisions"))
2558 # read in unfinished revisions
2559 # read in unfinished revisions
2559 try:
2560 try:
2560 nodes = repo.opener.read('graftstate').splitlines()
2561 nodes = repo.opener.read('graftstate').splitlines()
2561 revs = [repo[node].rev() for node in nodes]
2562 revs = [repo[node].rev() for node in nodes]
2562 except IOError, inst:
2563 except IOError, inst:
2563 if inst.errno != errno.ENOENT:
2564 if inst.errno != errno.ENOENT:
2564 raise
2565 raise
2565 raise util.Abort(_("no graft state found, can't continue"))
2566 raise util.Abort(_("no graft state found, can't continue"))
2566 else:
2567 else:
2567 cmdutil.bailifchanged(repo)
2568 cmdutil.bailifchanged(repo)
2568 if not revs:
2569 if not revs:
2569 raise util.Abort(_('no revisions specified'))
2570 raise util.Abort(_('no revisions specified'))
2570 revs = scmutil.revrange(repo, revs)
2571 revs = scmutil.revrange(repo, revs)
2571
2572
2572 # check for merges
2573 # check for merges
2573 for rev in repo.revs('%ld and merge()', revs):
2574 for rev in repo.revs('%ld and merge()', revs):
2574 ui.warn(_('skipping ungraftable merge revision %s\n') % rev)
2575 ui.warn(_('skipping ungraftable merge revision %s\n') % rev)
2575 revs.remove(rev)
2576 revs.remove(rev)
2576 if not revs:
2577 if not revs:
2577 return -1
2578 return -1
2578
2579
2579 # check for ancestors of dest branch
2580 # check for ancestors of dest branch
2580 for rev in repo.revs('::. and %ld', revs):
2581 for rev in repo.revs('::. and %ld', revs):
2581 ui.warn(_('skipping ancestor revision %s\n') % rev)
2582 ui.warn(_('skipping ancestor revision %s\n') % rev)
2582 revs.remove(rev)
2583 revs.remove(rev)
2583 if not revs:
2584 if not revs:
2584 return -1
2585 return -1
2585
2586
2586 # analyze revs for earlier grafts
2587 # analyze revs for earlier grafts
2587 ids = {}
2588 ids = {}
2588 for ctx in repo.set("%ld", revs):
2589 for ctx in repo.set("%ld", revs):
2589 ids[ctx.hex()] = ctx.rev()
2590 ids[ctx.hex()] = ctx.rev()
2590 n = ctx.extra().get('source')
2591 n = ctx.extra().get('source')
2591 if n:
2592 if n:
2592 ids[n] = ctx.rev()
2593 ids[n] = ctx.rev()
2593
2594
2594 # check ancestors for earlier grafts
2595 # check ancestors for earlier grafts
2595 ui.debug('scanning for duplicate grafts\n')
2596 ui.debug('scanning for duplicate grafts\n')
2596 for ctx in repo.set("::. - ::%ld", revs):
2597 for ctx in repo.set("::. - ::%ld", revs):
2597 n = ctx.extra().get('source')
2598 n = ctx.extra().get('source')
2598 if n in ids:
2599 if n in ids:
2599 r = repo[n].rev()
2600 r = repo[n].rev()
2600 if r in revs:
2601 if r in revs:
2601 ui.warn(_('skipping already grafted revision %s\n') % r)
2602 ui.warn(_('skipping already grafted revision %s\n') % r)
2602 revs.remove(r)
2603 revs.remove(r)
2603 elif ids[n] in revs:
2604 elif ids[n] in revs:
2604 ui.warn(_('skipping already grafted revision %s '
2605 ui.warn(_('skipping already grafted revision %s '
2605 '(same origin %d)\n') % (ids[n], r))
2606 '(same origin %d)\n') % (ids[n], r))
2606 revs.remove(ids[n])
2607 revs.remove(ids[n])
2607 elif ctx.hex() in ids:
2608 elif ctx.hex() in ids:
2608 r = ids[ctx.hex()]
2609 r = ids[ctx.hex()]
2609 ui.warn(_('skipping already grafted revision %s '
2610 ui.warn(_('skipping already grafted revision %s '
2610 '(was grafted from %d)\n') % (r, ctx.rev()))
2611 '(was grafted from %d)\n') % (r, ctx.rev()))
2611 revs.remove(r)
2612 revs.remove(r)
2612 if not revs:
2613 if not revs:
2613 return -1
2614 return -1
2614
2615
2615 for pos, ctx in enumerate(repo.set("%ld", revs)):
2616 for pos, ctx in enumerate(repo.set("%ld", revs)):
2616 current = repo['.']
2617 current = repo['.']
2617 ui.status(_('grafting revision %s\n') % ctx.rev())
2618 ui.status(_('grafting revision %s\n') % ctx.rev())
2618
2619
2619 # we don't merge the first commit when continuing
2620 # we don't merge the first commit when continuing
2620 if not cont:
2621 if not cont:
2621 # perform the graft merge with p1(rev) as 'ancestor'
2622 # perform the graft merge with p1(rev) as 'ancestor'
2622 try:
2623 try:
2623 # ui.forcemerge is an internal variable, do not document
2624 # ui.forcemerge is an internal variable, do not document
2624 repo.ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
2625 repo.ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
2625 stats = mergemod.update(repo, ctx.node(), True, True, False,
2626 stats = mergemod.update(repo, ctx.node(), True, True, False,
2626 ctx.p1().node())
2627 ctx.p1().node())
2627 finally:
2628 finally:
2628 ui.setconfig('ui', 'forcemerge', '')
2629 ui.setconfig('ui', 'forcemerge', '')
2629 # drop the second merge parent
2630 # drop the second merge parent
2630 repo.dirstate.setparents(current.node(), nullid)
2631 repo.dirstate.setparents(current.node(), nullid)
2631 repo.dirstate.write()
2632 repo.dirstate.write()
2632 # fix up dirstate for copies and renames
2633 # fix up dirstate for copies and renames
2633 cmdutil.duplicatecopies(repo, ctx.rev(), current.node())
2634 cmdutil.duplicatecopies(repo, ctx.rev(), current.node())
2634 # report any conflicts
2635 # report any conflicts
2635 if stats and stats[3] > 0:
2636 if stats and stats[3] > 0:
2636 # write out state for --continue
2637 # write out state for --continue
2637 nodelines = [repo[rev].hex() + "\n" for rev in revs[pos:]]
2638 nodelines = [repo[rev].hex() + "\n" for rev in revs[pos:]]
2638 repo.opener.write('graftstate', ''.join(nodelines))
2639 repo.opener.write('graftstate', ''.join(nodelines))
2639 raise util.Abort(
2640 raise util.Abort(
2640 _("unresolved conflicts, can't continue"),
2641 _("unresolved conflicts, can't continue"),
2641 hint=_('use hg resolve and hg graft --continue'))
2642 hint=_('use hg resolve and hg graft --continue'))
2642 else:
2643 else:
2643 cont = False
2644 cont = False
2644
2645
2645 # commit
2646 # commit
2646 source = ctx.extra().get('source')
2647 source = ctx.extra().get('source')
2647 if not source:
2648 if not source:
2648 source = ctx.hex()
2649 source = ctx.hex()
2649 extra = {'source': source}
2650 extra = {'source': source}
2650 user = ctx.user()
2651 user = ctx.user()
2651 if opts.get('user'):
2652 if opts.get('user'):
2652 user = opts['user']
2653 user = opts['user']
2653 date = ctx.date()
2654 date = ctx.date()
2654 if opts.get('date'):
2655 if opts.get('date'):
2655 date = opts['date']
2656 date = opts['date']
2656 repo.commit(text=ctx.description(), user=user,
2657 repo.commit(text=ctx.description(), user=user,
2657 date=date, extra=extra, editor=editor)
2658 date=date, extra=extra, editor=editor)
2658
2659
2659 # remove state when we complete successfully
2660 # remove state when we complete successfully
2660 if os.path.exists(repo.join('graftstate')):
2661 if os.path.exists(repo.join('graftstate')):
2661 util.unlinkpath(repo.join('graftstate'))
2662 util.unlinkpath(repo.join('graftstate'))
2662
2663
2663 return 0
2664 return 0
2664
2665
2665 @command('grep',
2666 @command('grep',
2666 [('0', 'print0', None, _('end fields with NUL')),
2667 [('0', 'print0', None, _('end fields with NUL')),
2667 ('', 'all', None, _('print all revisions that match')),
2668 ('', 'all', None, _('print all revisions that match')),
2668 ('a', 'text', None, _('treat all files as text')),
2669 ('a', 'text', None, _('treat all files as text')),
2669 ('f', 'follow', None,
2670 ('f', 'follow', None,
2670 _('follow changeset history,'
2671 _('follow changeset history,'
2671 ' or file history across copies and renames')),
2672 ' or file history across copies and renames')),
2672 ('i', 'ignore-case', None, _('ignore case when matching')),
2673 ('i', 'ignore-case', None, _('ignore case when matching')),
2673 ('l', 'files-with-matches', None,
2674 ('l', 'files-with-matches', None,
2674 _('print only filenames and revisions that match')),
2675 _('print only filenames and revisions that match')),
2675 ('n', 'line-number', None, _('print matching line numbers')),
2676 ('n', 'line-number', None, _('print matching line numbers')),
2676 ('r', 'rev', [],
2677 ('r', 'rev', [],
2677 _('only search files changed within revision range'), _('REV')),
2678 _('only search files changed within revision range'), _('REV')),
2678 ('u', 'user', None, _('list the author (long with -v)')),
2679 ('u', 'user', None, _('list the author (long with -v)')),
2679 ('d', 'date', None, _('list the date (short with -q)')),
2680 ('d', 'date', None, _('list the date (short with -q)')),
2680 ] + walkopts,
2681 ] + walkopts,
2681 _('[OPTION]... PATTERN [FILE]...'))
2682 _('[OPTION]... PATTERN [FILE]...'))
2682 def grep(ui, repo, pattern, *pats, **opts):
2683 def grep(ui, repo, pattern, *pats, **opts):
2683 """search for a pattern in specified files and revisions
2684 """search for a pattern in specified files and revisions
2684
2685
2685 Search revisions of files for a regular expression.
2686 Search revisions of files for a regular expression.
2686
2687
2687 This command behaves differently than Unix grep. It only accepts
2688 This command behaves differently than Unix grep. It only accepts
2688 Python/Perl regexps. It searches repository history, not the
2689 Python/Perl regexps. It searches repository history, not the
2689 working directory. It always prints the revision number in which a
2690 working directory. It always prints the revision number in which a
2690 match appears.
2691 match appears.
2691
2692
2692 By default, grep only prints output for the first revision of a
2693 By default, grep only prints output for the first revision of a
2693 file in which it finds a match. To get it to print every revision
2694 file in which it finds a match. To get it to print every revision
2694 that contains a change in match status ("-" for a match that
2695 that contains a change in match status ("-" for a match that
2695 becomes a non-match, or "+" for a non-match that becomes a match),
2696 becomes a non-match, or "+" for a non-match that becomes a match),
2696 use the --all flag.
2697 use the --all flag.
2697
2698
2698 Returns 0 if a match is found, 1 otherwise.
2699 Returns 0 if a match is found, 1 otherwise.
2699 """
2700 """
2700 reflags = re.M
2701 reflags = re.M
2701 if opts.get('ignore_case'):
2702 if opts.get('ignore_case'):
2702 reflags |= re.I
2703 reflags |= re.I
2703 try:
2704 try:
2704 regexp = re.compile(pattern, reflags)
2705 regexp = re.compile(pattern, reflags)
2705 except re.error, inst:
2706 except re.error, inst:
2706 ui.warn(_("grep: invalid match pattern: %s\n") % inst)
2707 ui.warn(_("grep: invalid match pattern: %s\n") % inst)
2707 return 1
2708 return 1
2708 sep, eol = ':', '\n'
2709 sep, eol = ':', '\n'
2709 if opts.get('print0'):
2710 if opts.get('print0'):
2710 sep = eol = '\0'
2711 sep = eol = '\0'
2711
2712
2712 getfile = util.lrucachefunc(repo.file)
2713 getfile = util.lrucachefunc(repo.file)
2713
2714
2714 def matchlines(body):
2715 def matchlines(body):
2715 begin = 0
2716 begin = 0
2716 linenum = 0
2717 linenum = 0
2717 while True:
2718 while True:
2718 match = regexp.search(body, begin)
2719 match = regexp.search(body, begin)
2719 if not match:
2720 if not match:
2720 break
2721 break
2721 mstart, mend = match.span()
2722 mstart, mend = match.span()
2722 linenum += body.count('\n', begin, mstart) + 1
2723 linenum += body.count('\n', begin, mstart) + 1
2723 lstart = body.rfind('\n', begin, mstart) + 1 or begin
2724 lstart = body.rfind('\n', begin, mstart) + 1 or begin
2724 begin = body.find('\n', mend) + 1 or len(body) + 1
2725 begin = body.find('\n', mend) + 1 or len(body) + 1
2725 lend = begin - 1
2726 lend = begin - 1
2726 yield linenum, mstart - lstart, mend - lstart, body[lstart:lend]
2727 yield linenum, mstart - lstart, mend - lstart, body[lstart:lend]
2727
2728
2728 class linestate(object):
2729 class linestate(object):
2729 def __init__(self, line, linenum, colstart, colend):
2730 def __init__(self, line, linenum, colstart, colend):
2730 self.line = line
2731 self.line = line
2731 self.linenum = linenum
2732 self.linenum = linenum
2732 self.colstart = colstart
2733 self.colstart = colstart
2733 self.colend = colend
2734 self.colend = colend
2734
2735
2735 def __hash__(self):
2736 def __hash__(self):
2736 return hash((self.linenum, self.line))
2737 return hash((self.linenum, self.line))
2737
2738
2738 def __eq__(self, other):
2739 def __eq__(self, other):
2739 return self.line == other.line
2740 return self.line == other.line
2740
2741
2741 matches = {}
2742 matches = {}
2742 copies = {}
2743 copies = {}
2743 def grepbody(fn, rev, body):
2744 def grepbody(fn, rev, body):
2744 matches[rev].setdefault(fn, [])
2745 matches[rev].setdefault(fn, [])
2745 m = matches[rev][fn]
2746 m = matches[rev][fn]
2746 for lnum, cstart, cend, line in matchlines(body):
2747 for lnum, cstart, cend, line in matchlines(body):
2747 s = linestate(line, lnum, cstart, cend)
2748 s = linestate(line, lnum, cstart, cend)
2748 m.append(s)
2749 m.append(s)
2749
2750
2750 def difflinestates(a, b):
2751 def difflinestates(a, b):
2751 sm = difflib.SequenceMatcher(None, a, b)
2752 sm = difflib.SequenceMatcher(None, a, b)
2752 for tag, alo, ahi, blo, bhi in sm.get_opcodes():
2753 for tag, alo, ahi, blo, bhi in sm.get_opcodes():
2753 if tag == 'insert':
2754 if tag == 'insert':
2754 for i in xrange(blo, bhi):
2755 for i in xrange(blo, bhi):
2755 yield ('+', b[i])
2756 yield ('+', b[i])
2756 elif tag == 'delete':
2757 elif tag == 'delete':
2757 for i in xrange(alo, ahi):
2758 for i in xrange(alo, ahi):
2758 yield ('-', a[i])
2759 yield ('-', a[i])
2759 elif tag == 'replace':
2760 elif tag == 'replace':
2760 for i in xrange(alo, ahi):
2761 for i in xrange(alo, ahi):
2761 yield ('-', a[i])
2762 yield ('-', a[i])
2762 for i in xrange(blo, bhi):
2763 for i in xrange(blo, bhi):
2763 yield ('+', b[i])
2764 yield ('+', b[i])
2764
2765
2765 def display(fn, ctx, pstates, states):
2766 def display(fn, ctx, pstates, states):
2766 rev = ctx.rev()
2767 rev = ctx.rev()
2767 datefunc = ui.quiet and util.shortdate or util.datestr
2768 datefunc = ui.quiet and util.shortdate or util.datestr
2768 found = False
2769 found = False
2769 filerevmatches = {}
2770 filerevmatches = {}
2770 def binary():
2771 def binary():
2771 flog = getfile(fn)
2772 flog = getfile(fn)
2772 return util.binary(flog.read(ctx.filenode(fn)))
2773 return util.binary(flog.read(ctx.filenode(fn)))
2773
2774
2774 if opts.get('all'):
2775 if opts.get('all'):
2775 iter = difflinestates(pstates, states)
2776 iter = difflinestates(pstates, states)
2776 else:
2777 else:
2777 iter = [('', l) for l in states]
2778 iter = [('', l) for l in states]
2778 for change, l in iter:
2779 for change, l in iter:
2779 cols = [fn, str(rev)]
2780 cols = [fn, str(rev)]
2780 before, match, after = None, None, None
2781 before, match, after = None, None, None
2781 if opts.get('line_number'):
2782 if opts.get('line_number'):
2782 cols.append(str(l.linenum))
2783 cols.append(str(l.linenum))
2783 if opts.get('all'):
2784 if opts.get('all'):
2784 cols.append(change)
2785 cols.append(change)
2785 if opts.get('user'):
2786 if opts.get('user'):
2786 cols.append(ui.shortuser(ctx.user()))
2787 cols.append(ui.shortuser(ctx.user()))
2787 if opts.get('date'):
2788 if opts.get('date'):
2788 cols.append(datefunc(ctx.date()))
2789 cols.append(datefunc(ctx.date()))
2789 if opts.get('files_with_matches'):
2790 if opts.get('files_with_matches'):
2790 c = (fn, rev)
2791 c = (fn, rev)
2791 if c in filerevmatches:
2792 if c in filerevmatches:
2792 continue
2793 continue
2793 filerevmatches[c] = 1
2794 filerevmatches[c] = 1
2794 else:
2795 else:
2795 before = l.line[:l.colstart]
2796 before = l.line[:l.colstart]
2796 match = l.line[l.colstart:l.colend]
2797 match = l.line[l.colstart:l.colend]
2797 after = l.line[l.colend:]
2798 after = l.line[l.colend:]
2798 ui.write(sep.join(cols))
2799 ui.write(sep.join(cols))
2799 if before is not None:
2800 if before is not None:
2800 if not opts.get('text') and binary():
2801 if not opts.get('text') and binary():
2801 ui.write(sep + " Binary file matches")
2802 ui.write(sep + " Binary file matches")
2802 else:
2803 else:
2803 ui.write(sep + before)
2804 ui.write(sep + before)
2804 ui.write(match, label='grep.match')
2805 ui.write(match, label='grep.match')
2805 ui.write(after)
2806 ui.write(after)
2806 ui.write(eol)
2807 ui.write(eol)
2807 found = True
2808 found = True
2808 return found
2809 return found
2809
2810
2810 skip = {}
2811 skip = {}
2811 revfiles = {}
2812 revfiles = {}
2812 matchfn = scmutil.match(repo[None], pats, opts)
2813 matchfn = scmutil.match(repo[None], pats, opts)
2813 found = False
2814 found = False
2814 follow = opts.get('follow')
2815 follow = opts.get('follow')
2815
2816
2816 def prep(ctx, fns):
2817 def prep(ctx, fns):
2817 rev = ctx.rev()
2818 rev = ctx.rev()
2818 pctx = ctx.p1()
2819 pctx = ctx.p1()
2819 parent = pctx.rev()
2820 parent = pctx.rev()
2820 matches.setdefault(rev, {})
2821 matches.setdefault(rev, {})
2821 matches.setdefault(parent, {})
2822 matches.setdefault(parent, {})
2822 files = revfiles.setdefault(rev, [])
2823 files = revfiles.setdefault(rev, [])
2823 for fn in fns:
2824 for fn in fns:
2824 flog = getfile(fn)
2825 flog = getfile(fn)
2825 try:
2826 try:
2826 fnode = ctx.filenode(fn)
2827 fnode = ctx.filenode(fn)
2827 except error.LookupError:
2828 except error.LookupError:
2828 continue
2829 continue
2829
2830
2830 copied = flog.renamed(fnode)
2831 copied = flog.renamed(fnode)
2831 copy = follow and copied and copied[0]
2832 copy = follow and copied and copied[0]
2832 if copy:
2833 if copy:
2833 copies.setdefault(rev, {})[fn] = copy
2834 copies.setdefault(rev, {})[fn] = copy
2834 if fn in skip:
2835 if fn in skip:
2835 if copy:
2836 if copy:
2836 skip[copy] = True
2837 skip[copy] = True
2837 continue
2838 continue
2838 files.append(fn)
2839 files.append(fn)
2839
2840
2840 if fn not in matches[rev]:
2841 if fn not in matches[rev]:
2841 grepbody(fn, rev, flog.read(fnode))
2842 grepbody(fn, rev, flog.read(fnode))
2842
2843
2843 pfn = copy or fn
2844 pfn = copy or fn
2844 if pfn not in matches[parent]:
2845 if pfn not in matches[parent]:
2845 try:
2846 try:
2846 fnode = pctx.filenode(pfn)
2847 fnode = pctx.filenode(pfn)
2847 grepbody(pfn, parent, flog.read(fnode))
2848 grepbody(pfn, parent, flog.read(fnode))
2848 except error.LookupError:
2849 except error.LookupError:
2849 pass
2850 pass
2850
2851
2851 for ctx in cmdutil.walkchangerevs(repo, matchfn, opts, prep):
2852 for ctx in cmdutil.walkchangerevs(repo, matchfn, opts, prep):
2852 rev = ctx.rev()
2853 rev = ctx.rev()
2853 parent = ctx.p1().rev()
2854 parent = ctx.p1().rev()
2854 for fn in sorted(revfiles.get(rev, [])):
2855 for fn in sorted(revfiles.get(rev, [])):
2855 states = matches[rev][fn]
2856 states = matches[rev][fn]
2856 copy = copies.get(rev, {}).get(fn)
2857 copy = copies.get(rev, {}).get(fn)
2857 if fn in skip:
2858 if fn in skip:
2858 if copy:
2859 if copy:
2859 skip[copy] = True
2860 skip[copy] = True
2860 continue
2861 continue
2861 pstates = matches.get(parent, {}).get(copy or fn, [])
2862 pstates = matches.get(parent, {}).get(copy or fn, [])
2862 if pstates or states:
2863 if pstates or states:
2863 r = display(fn, ctx, pstates, states)
2864 r = display(fn, ctx, pstates, states)
2864 found = found or r
2865 found = found or r
2865 if r and not opts.get('all'):
2866 if r and not opts.get('all'):
2866 skip[fn] = True
2867 skip[fn] = True
2867 if copy:
2868 if copy:
2868 skip[copy] = True
2869 skip[copy] = True
2869 del matches[rev]
2870 del matches[rev]
2870 del revfiles[rev]
2871 del revfiles[rev]
2871
2872
2872 return not found
2873 return not found
2873
2874
2874 @command('heads',
2875 @command('heads',
2875 [('r', 'rev', '',
2876 [('r', 'rev', '',
2876 _('show only heads which are descendants of STARTREV'), _('STARTREV')),
2877 _('show only heads which are descendants of STARTREV'), _('STARTREV')),
2877 ('t', 'topo', False, _('show topological heads only')),
2878 ('t', 'topo', False, _('show topological heads only')),
2878 ('a', 'active', False, _('show active branchheads only (DEPRECATED)')),
2879 ('a', 'active', False, _('show active branchheads only (DEPRECATED)')),
2879 ('c', 'closed', False, _('show normal and closed branch heads')),
2880 ('c', 'closed', False, _('show normal and closed branch heads')),
2880 ] + templateopts,
2881 ] + templateopts,
2881 _('[-ac] [-r STARTREV] [REV]...'))
2882 _('[-ac] [-r STARTREV] [REV]...'))
2882 def heads(ui, repo, *branchrevs, **opts):
2883 def heads(ui, repo, *branchrevs, **opts):
2883 """show current repository heads or show branch heads
2884 """show current repository heads or show branch heads
2884
2885
2885 With no arguments, show all repository branch heads.
2886 With no arguments, show all repository branch heads.
2886
2887
2887 Repository "heads" are changesets with no child changesets. They are
2888 Repository "heads" are changesets with no child changesets. They are
2888 where development generally takes place and are the usual targets
2889 where development generally takes place and are the usual targets
2889 for update and merge operations. Branch heads are changesets that have
2890 for update and merge operations. Branch heads are changesets that have
2890 no child changeset on the same branch.
2891 no child changeset on the same branch.
2891
2892
2892 If one or more REVs are given, only branch heads on the branches
2893 If one or more REVs are given, only branch heads on the branches
2893 associated with the specified changesets are shown. This means
2894 associated with the specified changesets are shown. This means
2894 that you can use :hg:`heads foo` to see the heads on a branch
2895 that you can use :hg:`heads foo` to see the heads on a branch
2895 named ``foo``.
2896 named ``foo``.
2896
2897
2897 If -c/--closed is specified, also show branch heads marked closed
2898 If -c/--closed is specified, also show branch heads marked closed
2898 (see :hg:`commit --close-branch`).
2899 (see :hg:`commit --close-branch`).
2899
2900
2900 If STARTREV is specified, only those heads that are descendants of
2901 If STARTREV is specified, only those heads that are descendants of
2901 STARTREV will be displayed.
2902 STARTREV will be displayed.
2902
2903
2903 If -t/--topo is specified, named branch mechanics will be ignored and only
2904 If -t/--topo is specified, named branch mechanics will be ignored and only
2904 changesets without children will be shown.
2905 changesets without children will be shown.
2905
2906
2906 Returns 0 if matching heads are found, 1 if not.
2907 Returns 0 if matching heads are found, 1 if not.
2907 """
2908 """
2908
2909
2909 start = None
2910 start = None
2910 if 'rev' in opts:
2911 if 'rev' in opts:
2911 start = scmutil.revsingle(repo, opts['rev'], None).node()
2912 start = scmutil.revsingle(repo, opts['rev'], None).node()
2912
2913
2913 if opts.get('topo'):
2914 if opts.get('topo'):
2914 heads = [repo[h] for h in repo.heads(start)]
2915 heads = [repo[h] for h in repo.heads(start)]
2915 else:
2916 else:
2916 heads = []
2917 heads = []
2917 for branch in repo.branchmap():
2918 for branch in repo.branchmap():
2918 heads += repo.branchheads(branch, start, opts.get('closed'))
2919 heads += repo.branchheads(branch, start, opts.get('closed'))
2919 heads = [repo[h] for h in heads]
2920 heads = [repo[h] for h in heads]
2920
2921
2921 if branchrevs:
2922 if branchrevs:
2922 branches = set(repo[br].branch() for br in branchrevs)
2923 branches = set(repo[br].branch() for br in branchrevs)
2923 heads = [h for h in heads if h.branch() in branches]
2924 heads = [h for h in heads if h.branch() in branches]
2924
2925
2925 if opts.get('active') and branchrevs:
2926 if opts.get('active') and branchrevs:
2926 dagheads = repo.heads(start)
2927 dagheads = repo.heads(start)
2927 heads = [h for h in heads if h.node() in dagheads]
2928 heads = [h for h in heads if h.node() in dagheads]
2928
2929
2929 if branchrevs:
2930 if branchrevs:
2930 haveheads = set(h.branch() for h in heads)
2931 haveheads = set(h.branch() for h in heads)
2931 if branches - haveheads:
2932 if branches - haveheads:
2932 headless = ', '.join(b for b in branches - haveheads)
2933 headless = ', '.join(b for b in branches - haveheads)
2933 msg = _('no open branch heads found on branches %s')
2934 msg = _('no open branch heads found on branches %s')
2934 if opts.get('rev'):
2935 if opts.get('rev'):
2935 msg += _(' (started at %s)' % opts['rev'])
2936 msg += _(' (started at %s)' % opts['rev'])
2936 ui.warn((msg + '\n') % headless)
2937 ui.warn((msg + '\n') % headless)
2937
2938
2938 if not heads:
2939 if not heads:
2939 return 1
2940 return 1
2940
2941
2941 heads = sorted(heads, key=lambda x: -x.rev())
2942 heads = sorted(heads, key=lambda x: -x.rev())
2942 displayer = cmdutil.show_changeset(ui, repo, opts)
2943 displayer = cmdutil.show_changeset(ui, repo, opts)
2943 for ctx in heads:
2944 for ctx in heads:
2944 displayer.show(ctx)
2945 displayer.show(ctx)
2945 displayer.close()
2946 displayer.close()
2946
2947
2947 @command('help',
2948 @command('help',
2948 [('e', 'extension', None, _('show only help for extensions')),
2949 [('e', 'extension', None, _('show only help for extensions')),
2949 ('c', 'command', None, _('show only help for commands'))],
2950 ('c', 'command', None, _('show only help for commands'))],
2950 _('[-ec] [TOPIC]'))
2951 _('[-ec] [TOPIC]'))
2951 def help_(ui, name=None, unknowncmd=False, full=True, **opts):
2952 def help_(ui, name=None, unknowncmd=False, full=True, **opts):
2952 """show help for a given topic or a help overview
2953 """show help for a given topic or a help overview
2953
2954
2954 With no arguments, print a list of commands with short help messages.
2955 With no arguments, print a list of commands with short help messages.
2955
2956
2956 Given a topic, extension, or command name, print help for that
2957 Given a topic, extension, or command name, print help for that
2957 topic.
2958 topic.
2958
2959
2959 Returns 0 if successful.
2960 Returns 0 if successful.
2960 """
2961 """
2961
2962
2962 textwidth = min(ui.termwidth(), 80) - 2
2963 textwidth = min(ui.termwidth(), 80) - 2
2963
2964
2964 def optrst(options):
2965 def optrst(options):
2965 data = []
2966 data = []
2966 multioccur = False
2967 multioccur = False
2967 for option in options:
2968 for option in options:
2968 if len(option) == 5:
2969 if len(option) == 5:
2969 shortopt, longopt, default, desc, optlabel = option
2970 shortopt, longopt, default, desc, optlabel = option
2970 else:
2971 else:
2971 shortopt, longopt, default, desc = option
2972 shortopt, longopt, default, desc = option
2972 optlabel = _("VALUE") # default label
2973 optlabel = _("VALUE") # default label
2973
2974
2974 if _("DEPRECATED") in desc and not ui.verbose:
2975 if _("DEPRECATED") in desc and not ui.verbose:
2975 continue
2976 continue
2976
2977
2977 so = ''
2978 so = ''
2978 if shortopt:
2979 if shortopt:
2979 so = '-' + shortopt
2980 so = '-' + shortopt
2980 lo = '--' + longopt
2981 lo = '--' + longopt
2981 if default:
2982 if default:
2982 desc += _(" (default: %s)") % default
2983 desc += _(" (default: %s)") % default
2983
2984
2984 if isinstance(default, list):
2985 if isinstance(default, list):
2985 lo += " %s [+]" % optlabel
2986 lo += " %s [+]" % optlabel
2986 multioccur = True
2987 multioccur = True
2987 elif (default is not None) and not isinstance(default, bool):
2988 elif (default is not None) and not isinstance(default, bool):
2988 lo += " %s" % optlabel
2989 lo += " %s" % optlabel
2989
2990
2990 data.append((so, lo, desc))
2991 data.append((so, lo, desc))
2991
2992
2992 rst = minirst.maketable(data, 1)
2993 rst = minirst.maketable(data, 1)
2993
2994
2994 if multioccur:
2995 if multioccur:
2995 rst += _("\n[+] marked option can be specified multiple times\n")
2996 rst += _("\n[+] marked option can be specified multiple times\n")
2996
2997
2997 return rst
2998 return rst
2998
2999
2999 # list all option lists
3000 # list all option lists
3000 def opttext(optlist, width):
3001 def opttext(optlist, width):
3001 rst = ''
3002 rst = ''
3002 if not optlist:
3003 if not optlist:
3003 return ''
3004 return ''
3004
3005
3005 for title, options in optlist:
3006 for title, options in optlist:
3006 rst += '\n%s\n' % title
3007 rst += '\n%s\n' % title
3007 if options:
3008 if options:
3008 rst += "\n"
3009 rst += "\n"
3009 rst += optrst(options)
3010 rst += optrst(options)
3010 rst += '\n'
3011 rst += '\n'
3011
3012
3012 return '\n' + minirst.format(rst, width)
3013 return '\n' + minirst.format(rst, width)
3013
3014
3014 def addglobalopts(optlist, aliases):
3015 def addglobalopts(optlist, aliases):
3015 if ui.quiet:
3016 if ui.quiet:
3016 return []
3017 return []
3017
3018
3018 if ui.verbose:
3019 if ui.verbose:
3019 optlist.append((_("global options:"), globalopts))
3020 optlist.append((_("global options:"), globalopts))
3020 if name == 'shortlist':
3021 if name == 'shortlist':
3021 optlist.append((_('use "hg help" for the full list '
3022 optlist.append((_('use "hg help" for the full list '
3022 'of commands'), ()))
3023 'of commands'), ()))
3023 else:
3024 else:
3024 if name == 'shortlist':
3025 if name == 'shortlist':
3025 msg = _('use "hg help" for the full list of commands '
3026 msg = _('use "hg help" for the full list of commands '
3026 'or "hg -v" for details')
3027 'or "hg -v" for details')
3027 elif name and not full:
3028 elif name and not full:
3028 msg = _('use "hg help %s" to show the full help text' % name)
3029 msg = _('use "hg help %s" to show the full help text' % name)
3029 elif aliases:
3030 elif aliases:
3030 msg = _('use "hg -v help%s" to show builtin aliases and '
3031 msg = _('use "hg -v help%s" to show builtin aliases and '
3031 'global options') % (name and " " + name or "")
3032 'global options') % (name and " " + name or "")
3032 else:
3033 else:
3033 msg = _('use "hg -v help %s" to show more info') % name
3034 msg = _('use "hg -v help %s" to show more info') % name
3034 optlist.append((msg, ()))
3035 optlist.append((msg, ()))
3035
3036
3036 def helpcmd(name):
3037 def helpcmd(name):
3037 try:
3038 try:
3038 aliases, entry = cmdutil.findcmd(name, table, strict=unknowncmd)
3039 aliases, entry = cmdutil.findcmd(name, table, strict=unknowncmd)
3039 except error.AmbiguousCommand, inst:
3040 except error.AmbiguousCommand, inst:
3040 # py3k fix: except vars can't be used outside the scope of the
3041 # py3k fix: except vars can't be used outside the scope of the
3041 # except block, nor can be used inside a lambda. python issue4617
3042 # except block, nor can be used inside a lambda. python issue4617
3042 prefix = inst.args[0]
3043 prefix = inst.args[0]
3043 select = lambda c: c.lstrip('^').startswith(prefix)
3044 select = lambda c: c.lstrip('^').startswith(prefix)
3044 helplist(select)
3045 helplist(select)
3045 return
3046 return
3046
3047
3047 # check if it's an invalid alias and display its error if it is
3048 # check if it's an invalid alias and display its error if it is
3048 if getattr(entry[0], 'badalias', False):
3049 if getattr(entry[0], 'badalias', False):
3049 if not unknowncmd:
3050 if not unknowncmd:
3050 entry[0](ui)
3051 entry[0](ui)
3051 return
3052 return
3052
3053
3053 rst = ""
3054 rst = ""
3054
3055
3055 # synopsis
3056 # synopsis
3056 if len(entry) > 2:
3057 if len(entry) > 2:
3057 if entry[2].startswith('hg'):
3058 if entry[2].startswith('hg'):
3058 rst += "%s\n" % entry[2]
3059 rst += "%s\n" % entry[2]
3059 else:
3060 else:
3060 rst += 'hg %s %s\n' % (aliases[0], entry[2])
3061 rst += 'hg %s %s\n' % (aliases[0], entry[2])
3061 else:
3062 else:
3062 rst += 'hg %s\n' % aliases[0]
3063 rst += 'hg %s\n' % aliases[0]
3063
3064
3064 # aliases
3065 # aliases
3065 if full and not ui.quiet and len(aliases) > 1:
3066 if full and not ui.quiet and len(aliases) > 1:
3066 rst += _("\naliases: %s\n") % ', '.join(aliases[1:])
3067 rst += _("\naliases: %s\n") % ', '.join(aliases[1:])
3067
3068
3068 # description
3069 # description
3069 doc = gettext(entry[0].__doc__)
3070 doc = gettext(entry[0].__doc__)
3070 if not doc:
3071 if not doc:
3071 doc = _("(no help text available)")
3072 doc = _("(no help text available)")
3072 if util.safehasattr(entry[0], 'definition'): # aliased command
3073 if util.safehasattr(entry[0], 'definition'): # aliased command
3073 if entry[0].definition.startswith('!'): # shell alias
3074 if entry[0].definition.startswith('!'): # shell alias
3074 doc = _('shell alias for::\n\n %s') % entry[0].definition[1:]
3075 doc = _('shell alias for::\n\n %s') % entry[0].definition[1:]
3075 else:
3076 else:
3076 doc = _('alias for: hg %s\n\n%s') % (entry[0].definition, doc)
3077 doc = _('alias for: hg %s\n\n%s') % (entry[0].definition, doc)
3077 if ui.quiet or not full:
3078 if ui.quiet or not full:
3078 doc = doc.splitlines()[0]
3079 doc = doc.splitlines()[0]
3079 rst += "\n" + doc + "\n"
3080 rst += "\n" + doc + "\n"
3080
3081
3081 # check if this command shadows a non-trivial (multi-line)
3082 # check if this command shadows a non-trivial (multi-line)
3082 # extension help text
3083 # extension help text
3083 try:
3084 try:
3084 mod = extensions.find(name)
3085 mod = extensions.find(name)
3085 doc = gettext(mod.__doc__) or ''
3086 doc = gettext(mod.__doc__) or ''
3086 if '\n' in doc.strip():
3087 if '\n' in doc.strip():
3087 msg = _('use "hg help -e %s" to show help for '
3088 msg = _('use "hg help -e %s" to show help for '
3088 'the %s extension') % (name, name)
3089 'the %s extension') % (name, name)
3089 rst += '\n%s\n' % msg
3090 rst += '\n%s\n' % msg
3090 except KeyError:
3091 except KeyError:
3091 pass
3092 pass
3092
3093
3093 # options
3094 # options
3094 if not ui.quiet and entry[1]:
3095 if not ui.quiet and entry[1]:
3095 rst += '\noptions:\n\n'
3096 rst += '\noptions:\n\n'
3096 rst += optrst(entry[1])
3097 rst += optrst(entry[1])
3097
3098
3098 if ui.verbose:
3099 if ui.verbose:
3099 rst += '\nglobal options:\n\n'
3100 rst += '\nglobal options:\n\n'
3100 rst += optrst(globalopts)
3101 rst += optrst(globalopts)
3101
3102
3102 keep = ui.verbose and ['verbose'] or []
3103 keep = ui.verbose and ['verbose'] or []
3103 formatted, pruned = minirst.format(rst, textwidth, keep=keep)
3104 formatted, pruned = minirst.format(rst, textwidth, keep=keep)
3104 ui.write(formatted)
3105 ui.write(formatted)
3105
3106
3106 if not ui.verbose:
3107 if not ui.verbose:
3107 if not full:
3108 if not full:
3108 ui.write(_('\nuse "hg help %s" to show the full help text\n')
3109 ui.write(_('\nuse "hg help %s" to show the full help text\n')
3109 % name)
3110 % name)
3110 elif not ui.quiet:
3111 elif not ui.quiet:
3111 ui.write(_('\nuse "hg -v help %s" to show more info\n') % name)
3112 ui.write(_('\nuse "hg -v help %s" to show more info\n') % name)
3112
3113
3113
3114
3114 def helplist(select=None):
3115 def helplist(select=None):
3115 # list of commands
3116 # list of commands
3116 if name == "shortlist":
3117 if name == "shortlist":
3117 header = _('basic commands:\n\n')
3118 header = _('basic commands:\n\n')
3118 else:
3119 else:
3119 header = _('list of commands:\n\n')
3120 header = _('list of commands:\n\n')
3120
3121
3121 h = {}
3122 h = {}
3122 cmds = {}
3123 cmds = {}
3123 for c, e in table.iteritems():
3124 for c, e in table.iteritems():
3124 f = c.split("|", 1)[0]
3125 f = c.split("|", 1)[0]
3125 if select and not select(f):
3126 if select and not select(f):
3126 continue
3127 continue
3127 if (not select and name != 'shortlist' and
3128 if (not select and name != 'shortlist' and
3128 e[0].__module__ != __name__):
3129 e[0].__module__ != __name__):
3129 continue
3130 continue
3130 if name == "shortlist" and not f.startswith("^"):
3131 if name == "shortlist" and not f.startswith("^"):
3131 continue
3132 continue
3132 f = f.lstrip("^")
3133 f = f.lstrip("^")
3133 if not ui.debugflag and f.startswith("debug"):
3134 if not ui.debugflag and f.startswith("debug"):
3134 continue
3135 continue
3135 doc = e[0].__doc__
3136 doc = e[0].__doc__
3136 if doc and 'DEPRECATED' in doc and not ui.verbose:
3137 if doc and 'DEPRECATED' in doc and not ui.verbose:
3137 continue
3138 continue
3138 doc = gettext(doc)
3139 doc = gettext(doc)
3139 if not doc:
3140 if not doc:
3140 doc = _("(no help text available)")
3141 doc = _("(no help text available)")
3141 h[f] = doc.splitlines()[0].rstrip()
3142 h[f] = doc.splitlines()[0].rstrip()
3142 cmds[f] = c.lstrip("^")
3143 cmds[f] = c.lstrip("^")
3143
3144
3144 if not h:
3145 if not h:
3145 ui.status(_('no commands defined\n'))
3146 ui.status(_('no commands defined\n'))
3146 return
3147 return
3147
3148
3148 ui.status(header)
3149 ui.status(header)
3149 fns = sorted(h)
3150 fns = sorted(h)
3150 m = max(map(len, fns))
3151 m = max(map(len, fns))
3151 for f in fns:
3152 for f in fns:
3152 if ui.verbose:
3153 if ui.verbose:
3153 commands = cmds[f].replace("|",", ")
3154 commands = cmds[f].replace("|",", ")
3154 ui.write(" %s:\n %s\n"%(commands, h[f]))
3155 ui.write(" %s:\n %s\n"%(commands, h[f]))
3155 else:
3156 else:
3156 ui.write('%s\n' % (util.wrap(h[f], textwidth,
3157 ui.write('%s\n' % (util.wrap(h[f], textwidth,
3157 initindent=' %-*s ' % (m, f),
3158 initindent=' %-*s ' % (m, f),
3158 hangindent=' ' * (m + 4))))
3159 hangindent=' ' * (m + 4))))
3159
3160
3160 if not name:
3161 if not name:
3161 text = help.listexts(_('enabled extensions:'), extensions.enabled())
3162 text = help.listexts(_('enabled extensions:'), extensions.enabled())
3162 if text:
3163 if text:
3163 ui.write("\n%s" % minirst.format(text, textwidth))
3164 ui.write("\n%s" % minirst.format(text, textwidth))
3164
3165
3165 ui.write(_("\nadditional help topics:\n\n"))
3166 ui.write(_("\nadditional help topics:\n\n"))
3166 topics = []
3167 topics = []
3167 for names, header, doc in help.helptable:
3168 for names, header, doc in help.helptable:
3168 topics.append((sorted(names, key=len, reverse=True)[0], header))
3169 topics.append((sorted(names, key=len, reverse=True)[0], header))
3169 topics_len = max([len(s[0]) for s in topics])
3170 topics_len = max([len(s[0]) for s in topics])
3170 for t, desc in topics:
3171 for t, desc in topics:
3171 ui.write(" %-*s %s\n" % (topics_len, t, desc))
3172 ui.write(" %-*s %s\n" % (topics_len, t, desc))
3172
3173
3173 optlist = []
3174 optlist = []
3174 addglobalopts(optlist, True)
3175 addglobalopts(optlist, True)
3175 ui.write(opttext(optlist, textwidth))
3176 ui.write(opttext(optlist, textwidth))
3176
3177
3177 def helptopic(name):
3178 def helptopic(name):
3178 for names, header, doc in help.helptable:
3179 for names, header, doc in help.helptable:
3179 if name in names:
3180 if name in names:
3180 break
3181 break
3181 else:
3182 else:
3182 raise error.UnknownCommand(name)
3183 raise error.UnknownCommand(name)
3183
3184
3184 # description
3185 # description
3185 if not doc:
3186 if not doc:
3186 doc = _("(no help text available)")
3187 doc = _("(no help text available)")
3187 if util.safehasattr(doc, '__call__'):
3188 if util.safehasattr(doc, '__call__'):
3188 doc = doc()
3189 doc = doc()
3189
3190
3190 ui.write("%s\n\n" % header)
3191 ui.write("%s\n\n" % header)
3191 ui.write("%s" % minirst.format(doc, textwidth, indent=4))
3192 ui.write("%s" % minirst.format(doc, textwidth, indent=4))
3192 try:
3193 try:
3193 cmdutil.findcmd(name, table)
3194 cmdutil.findcmd(name, table)
3194 ui.write(_('\nuse "hg help -c %s" to see help for '
3195 ui.write(_('\nuse "hg help -c %s" to see help for '
3195 'the %s command\n') % (name, name))
3196 'the %s command\n') % (name, name))
3196 except error.UnknownCommand:
3197 except error.UnknownCommand:
3197 pass
3198 pass
3198
3199
3199 def helpext(name):
3200 def helpext(name):
3200 try:
3201 try:
3201 mod = extensions.find(name)
3202 mod = extensions.find(name)
3202 doc = gettext(mod.__doc__) or _('no help text available')
3203 doc = gettext(mod.__doc__) or _('no help text available')
3203 except KeyError:
3204 except KeyError:
3204 mod = None
3205 mod = None
3205 doc = extensions.disabledext(name)
3206 doc = extensions.disabledext(name)
3206 if not doc:
3207 if not doc:
3207 raise error.UnknownCommand(name)
3208 raise error.UnknownCommand(name)
3208
3209
3209 if '\n' not in doc:
3210 if '\n' not in doc:
3210 head, tail = doc, ""
3211 head, tail = doc, ""
3211 else:
3212 else:
3212 head, tail = doc.split('\n', 1)
3213 head, tail = doc.split('\n', 1)
3213 ui.write(_('%s extension - %s\n\n') % (name.split('.')[-1], head))
3214 ui.write(_('%s extension - %s\n\n') % (name.split('.')[-1], head))
3214 if tail:
3215 if tail:
3215 ui.write(minirst.format(tail, textwidth))
3216 ui.write(minirst.format(tail, textwidth))
3216 ui.status('\n')
3217 ui.status('\n')
3217
3218
3218 if mod:
3219 if mod:
3219 try:
3220 try:
3220 ct = mod.cmdtable
3221 ct = mod.cmdtable
3221 except AttributeError:
3222 except AttributeError:
3222 ct = {}
3223 ct = {}
3223 modcmds = set([c.split('|', 1)[0] for c in ct])
3224 modcmds = set([c.split('|', 1)[0] for c in ct])
3224 helplist(modcmds.__contains__)
3225 helplist(modcmds.__contains__)
3225 else:
3226 else:
3226 ui.write(_('use "hg help extensions" for information on enabling '
3227 ui.write(_('use "hg help extensions" for information on enabling '
3227 'extensions\n'))
3228 'extensions\n'))
3228
3229
3229 def helpextcmd(name):
3230 def helpextcmd(name):
3230 cmd, ext, mod = extensions.disabledcmd(ui, name, ui.config('ui', 'strict'))
3231 cmd, ext, mod = extensions.disabledcmd(ui, name, ui.config('ui', 'strict'))
3231 doc = gettext(mod.__doc__).splitlines()[0]
3232 doc = gettext(mod.__doc__).splitlines()[0]
3232
3233
3233 msg = help.listexts(_("'%s' is provided by the following "
3234 msg = help.listexts(_("'%s' is provided by the following "
3234 "extension:") % cmd, {ext: doc}, indent=4)
3235 "extension:") % cmd, {ext: doc}, indent=4)
3235 ui.write(minirst.format(msg, textwidth))
3236 ui.write(minirst.format(msg, textwidth))
3236 ui.write('\n')
3237 ui.write('\n')
3237 ui.write(_('use "hg help extensions" for information on enabling '
3238 ui.write(_('use "hg help extensions" for information on enabling '
3238 'extensions\n'))
3239 'extensions\n'))
3239
3240
3240 if name and name != 'shortlist':
3241 if name and name != 'shortlist':
3241 i = None
3242 i = None
3242 if unknowncmd:
3243 if unknowncmd:
3243 queries = (helpextcmd,)
3244 queries = (helpextcmd,)
3244 elif opts.get('extension'):
3245 elif opts.get('extension'):
3245 queries = (helpext,)
3246 queries = (helpext,)
3246 elif opts.get('command'):
3247 elif opts.get('command'):
3247 queries = (helpcmd,)
3248 queries = (helpcmd,)
3248 else:
3249 else:
3249 queries = (helptopic, helpcmd, helpext, helpextcmd)
3250 queries = (helptopic, helpcmd, helpext, helpextcmd)
3250 for f in queries:
3251 for f in queries:
3251 try:
3252 try:
3252 f(name)
3253 f(name)
3253 i = None
3254 i = None
3254 break
3255 break
3255 except error.UnknownCommand, inst:
3256 except error.UnknownCommand, inst:
3256 i = inst
3257 i = inst
3257 if i:
3258 if i:
3258 raise i
3259 raise i
3259 else:
3260 else:
3260 # program name
3261 # program name
3261 ui.status(_("Mercurial Distributed SCM\n"))
3262 ui.status(_("Mercurial Distributed SCM\n"))
3262 ui.status('\n')
3263 ui.status('\n')
3263 helplist()
3264 helplist()
3264
3265
3265
3266
3266 @command('identify|id',
3267 @command('identify|id',
3267 [('r', 'rev', '',
3268 [('r', 'rev', '',
3268 _('identify the specified revision'), _('REV')),
3269 _('identify the specified revision'), _('REV')),
3269 ('n', 'num', None, _('show local revision number')),
3270 ('n', 'num', None, _('show local revision number')),
3270 ('i', 'id', None, _('show global revision id')),
3271 ('i', 'id', None, _('show global revision id')),
3271 ('b', 'branch', None, _('show branch')),
3272 ('b', 'branch', None, _('show branch')),
3272 ('t', 'tags', None, _('show tags')),
3273 ('t', 'tags', None, _('show tags')),
3273 ('B', 'bookmarks', None, _('show bookmarks')),
3274 ('B', 'bookmarks', None, _('show bookmarks')),
3274 ] + remoteopts,
3275 ] + remoteopts,
3275 _('[-nibtB] [-r REV] [SOURCE]'))
3276 _('[-nibtB] [-r REV] [SOURCE]'))
3276 def identify(ui, repo, source=None, rev=None,
3277 def identify(ui, repo, source=None, rev=None,
3277 num=None, id=None, branch=None, tags=None, bookmarks=None, **opts):
3278 num=None, id=None, branch=None, tags=None, bookmarks=None, **opts):
3278 """identify the working copy or specified revision
3279 """identify the working copy or specified revision
3279
3280
3280 Print a summary identifying the repository state at REV using one or
3281 Print a summary identifying the repository state at REV using one or
3281 two parent hash identifiers, followed by a "+" if the working
3282 two parent hash identifiers, followed by a "+" if the working
3282 directory has uncommitted changes, the branch name (if not default),
3283 directory has uncommitted changes, the branch name (if not default),
3283 a list of tags, and a list of bookmarks.
3284 a list of tags, and a list of bookmarks.
3284
3285
3285 When REV is not given, print a summary of the current state of the
3286 When REV is not given, print a summary of the current state of the
3286 repository.
3287 repository.
3287
3288
3288 Specifying a path to a repository root or Mercurial bundle will
3289 Specifying a path to a repository root or Mercurial bundle will
3289 cause lookup to operate on that repository/bundle.
3290 cause lookup to operate on that repository/bundle.
3290
3291
3291 .. container:: verbose
3292 .. container:: verbose
3292
3293
3293 Examples:
3294 Examples:
3294
3295
3295 - generate a build identifier for the working directory::
3296 - generate a build identifier for the working directory::
3296
3297
3297 hg id --id > build-id.dat
3298 hg id --id > build-id.dat
3298
3299
3299 - find the revision corresponding to a tag::
3300 - find the revision corresponding to a tag::
3300
3301
3301 hg id -n -r 1.3
3302 hg id -n -r 1.3
3302
3303
3303 - check the most recent revision of a remote repository::
3304 - check the most recent revision of a remote repository::
3304
3305
3305 hg id -r tip http://selenic.com/hg/
3306 hg id -r tip http://selenic.com/hg/
3306
3307
3307 Returns 0 if successful.
3308 Returns 0 if successful.
3308 """
3309 """
3309
3310
3310 if not repo and not source:
3311 if not repo and not source:
3311 raise util.Abort(_("there is no Mercurial repository here "
3312 raise util.Abort(_("there is no Mercurial repository here "
3312 "(.hg not found)"))
3313 "(.hg not found)"))
3313
3314
3314 hexfunc = ui.debugflag and hex or short
3315 hexfunc = ui.debugflag and hex or short
3315 default = not (num or id or branch or tags or bookmarks)
3316 default = not (num or id or branch or tags or bookmarks)
3316 output = []
3317 output = []
3317 revs = []
3318 revs = []
3318
3319
3319 if source:
3320 if source:
3320 source, branches = hg.parseurl(ui.expandpath(source))
3321 source, branches = hg.parseurl(ui.expandpath(source))
3321 repo = hg.peer(ui, opts, source)
3322 repo = hg.peer(ui, opts, source)
3322 revs, checkout = hg.addbranchrevs(repo, repo, branches, None)
3323 revs, checkout = hg.addbranchrevs(repo, repo, branches, None)
3323
3324
3324 if not repo.local():
3325 if not repo.local():
3325 if num or branch or tags:
3326 if num or branch or tags:
3326 raise util.Abort(
3327 raise util.Abort(
3327 _("can't query remote revision number, branch, or tags"))
3328 _("can't query remote revision number, branch, or tags"))
3328 if not rev and revs:
3329 if not rev and revs:
3329 rev = revs[0]
3330 rev = revs[0]
3330 if not rev:
3331 if not rev:
3331 rev = "tip"
3332 rev = "tip"
3332
3333
3333 remoterev = repo.lookup(rev)
3334 remoterev = repo.lookup(rev)
3334 if default or id:
3335 if default or id:
3335 output = [hexfunc(remoterev)]
3336 output = [hexfunc(remoterev)]
3336
3337
3337 def getbms():
3338 def getbms():
3338 bms = []
3339 bms = []
3339
3340
3340 if 'bookmarks' in repo.listkeys('namespaces'):
3341 if 'bookmarks' in repo.listkeys('namespaces'):
3341 hexremoterev = hex(remoterev)
3342 hexremoterev = hex(remoterev)
3342 bms = [bm for bm, bmr in repo.listkeys('bookmarks').iteritems()
3343 bms = [bm for bm, bmr in repo.listkeys('bookmarks').iteritems()
3343 if bmr == hexremoterev]
3344 if bmr == hexremoterev]
3344
3345
3345 return bms
3346 return bms
3346
3347
3347 if bookmarks:
3348 if bookmarks:
3348 output.extend(getbms())
3349 output.extend(getbms())
3349 elif default and not ui.quiet:
3350 elif default and not ui.quiet:
3350 # multiple bookmarks for a single parent separated by '/'
3351 # multiple bookmarks for a single parent separated by '/'
3351 bm = '/'.join(getbms())
3352 bm = '/'.join(getbms())
3352 if bm:
3353 if bm:
3353 output.append(bm)
3354 output.append(bm)
3354 else:
3355 else:
3355 if not rev:
3356 if not rev:
3356 ctx = repo[None]
3357 ctx = repo[None]
3357 parents = ctx.parents()
3358 parents = ctx.parents()
3358 changed = ""
3359 changed = ""
3359 if default or id or num:
3360 if default or id or num:
3360 changed = util.any(repo.status()) and "+" or ""
3361 changed = util.any(repo.status()) and "+" or ""
3361 if default or id:
3362 if default or id:
3362 output = ["%s%s" %
3363 output = ["%s%s" %
3363 ('+'.join([hexfunc(p.node()) for p in parents]), changed)]
3364 ('+'.join([hexfunc(p.node()) for p in parents]), changed)]
3364 if num:
3365 if num:
3365 output.append("%s%s" %
3366 output.append("%s%s" %
3366 ('+'.join([str(p.rev()) for p in parents]), changed))
3367 ('+'.join([str(p.rev()) for p in parents]), changed))
3367 else:
3368 else:
3368 ctx = scmutil.revsingle(repo, rev)
3369 ctx = scmutil.revsingle(repo, rev)
3369 if default or id:
3370 if default or id:
3370 output = [hexfunc(ctx.node())]
3371 output = [hexfunc(ctx.node())]
3371 if num:
3372 if num:
3372 output.append(str(ctx.rev()))
3373 output.append(str(ctx.rev()))
3373
3374
3374 if default and not ui.quiet:
3375 if default and not ui.quiet:
3375 b = ctx.branch()
3376 b = ctx.branch()
3376 if b != 'default':
3377 if b != 'default':
3377 output.append("(%s)" % b)
3378 output.append("(%s)" % b)
3378
3379
3379 # multiple tags for a single parent separated by '/'
3380 # multiple tags for a single parent separated by '/'
3380 t = '/'.join(ctx.tags())
3381 t = '/'.join(ctx.tags())
3381 if t:
3382 if t:
3382 output.append(t)
3383 output.append(t)
3383
3384
3384 # multiple bookmarks for a single parent separated by '/'
3385 # multiple bookmarks for a single parent separated by '/'
3385 bm = '/'.join(ctx.bookmarks())
3386 bm = '/'.join(ctx.bookmarks())
3386 if bm:
3387 if bm:
3387 output.append(bm)
3388 output.append(bm)
3388 else:
3389 else:
3389 if branch:
3390 if branch:
3390 output.append(ctx.branch())
3391 output.append(ctx.branch())
3391
3392
3392 if tags:
3393 if tags:
3393 output.extend(ctx.tags())
3394 output.extend(ctx.tags())
3394
3395
3395 if bookmarks:
3396 if bookmarks:
3396 output.extend(ctx.bookmarks())
3397 output.extend(ctx.bookmarks())
3397
3398
3398 ui.write("%s\n" % ' '.join(output))
3399 ui.write("%s\n" % ' '.join(output))
3399
3400
3400 @command('import|patch',
3401 @command('import|patch',
3401 [('p', 'strip', 1,
3402 [('p', 'strip', 1,
3402 _('directory strip option for patch. This has the same '
3403 _('directory strip option for patch. This has the same '
3403 'meaning as the corresponding patch option'), _('NUM')),
3404 'meaning as the corresponding patch option'), _('NUM')),
3404 ('b', 'base', '', _('base path (DEPRECATED)'), _('PATH')),
3405 ('b', 'base', '', _('base path (DEPRECATED)'), _('PATH')),
3405 ('e', 'edit', False, _('invoke editor on commit messages')),
3406 ('e', 'edit', False, _('invoke editor on commit messages')),
3406 ('f', 'force', None, _('skip check for outstanding uncommitted changes')),
3407 ('f', 'force', None, _('skip check for outstanding uncommitted changes')),
3407 ('', 'no-commit', None,
3408 ('', 'no-commit', None,
3408 _("don't commit, just update the working directory")),
3409 _("don't commit, just update the working directory")),
3409 ('', 'bypass', None,
3410 ('', 'bypass', None,
3410 _("apply patch without touching the working directory")),
3411 _("apply patch without touching the working directory")),
3411 ('', 'exact', None,
3412 ('', 'exact', None,
3412 _('apply patch to the nodes from which it was generated')),
3413 _('apply patch to the nodes from which it was generated')),
3413 ('', 'import-branch', None,
3414 ('', 'import-branch', None,
3414 _('use any branch information in patch (implied by --exact)'))] +
3415 _('use any branch information in patch (implied by --exact)'))] +
3415 commitopts + commitopts2 + similarityopts,
3416 commitopts + commitopts2 + similarityopts,
3416 _('[OPTION]... PATCH...'))
3417 _('[OPTION]... PATCH...'))
3417 def import_(ui, repo, patch1=None, *patches, **opts):
3418 def import_(ui, repo, patch1=None, *patches, **opts):
3418 """import an ordered set of patches
3419 """import an ordered set of patches
3419
3420
3420 Import a list of patches and commit them individually (unless
3421 Import a list of patches and commit them individually (unless
3421 --no-commit is specified).
3422 --no-commit is specified).
3422
3423
3423 If there are outstanding changes in the working directory, import
3424 If there are outstanding changes in the working directory, import
3424 will abort unless given the -f/--force flag.
3425 will abort unless given the -f/--force flag.
3425
3426
3426 You can import a patch straight from a mail message. Even patches
3427 You can import a patch straight from a mail message. Even patches
3427 as attachments work (to use the body part, it must have type
3428 as attachments work (to use the body part, it must have type
3428 text/plain or text/x-patch). From and Subject headers of email
3429 text/plain or text/x-patch). From and Subject headers of email
3429 message are used as default committer and commit message. All
3430 message are used as default committer and commit message. All
3430 text/plain body parts before first diff are added to commit
3431 text/plain body parts before first diff are added to commit
3431 message.
3432 message.
3432
3433
3433 If the imported patch was generated by :hg:`export`, user and
3434 If the imported patch was generated by :hg:`export`, user and
3434 description from patch override values from message headers and
3435 description from patch override values from message headers and
3435 body. Values given on command line with -m/--message and -u/--user
3436 body. Values given on command line with -m/--message and -u/--user
3436 override these.
3437 override these.
3437
3438
3438 If --exact is specified, import will set the working directory to
3439 If --exact is specified, import will set the working directory to
3439 the parent of each patch before applying it, and will abort if the
3440 the parent of each patch before applying it, and will abort if the
3440 resulting changeset has a different ID than the one recorded in
3441 resulting changeset has a different ID than the one recorded in
3441 the patch. This may happen due to character set problems or other
3442 the patch. This may happen due to character set problems or other
3442 deficiencies in the text patch format.
3443 deficiencies in the text patch format.
3443
3444
3444 Use --bypass to apply and commit patches directly to the
3445 Use --bypass to apply and commit patches directly to the
3445 repository, not touching the working directory. Without --exact,
3446 repository, not touching the working directory. Without --exact,
3446 patches will be applied on top of the working directory parent
3447 patches will be applied on top of the working directory parent
3447 revision.
3448 revision.
3448
3449
3449 With -s/--similarity, hg will attempt to discover renames and
3450 With -s/--similarity, hg will attempt to discover renames and
3450 copies in the patch in the same way as :hg:`addremove`.
3451 copies in the patch in the same way as :hg:`addremove`.
3451
3452
3452 To read a patch from standard input, use "-" as the patch name. If
3453 To read a patch from standard input, use "-" as the patch name. If
3453 a URL is specified, the patch will be downloaded from it.
3454 a URL is specified, the patch will be downloaded from it.
3454 See :hg:`help dates` for a list of formats valid for -d/--date.
3455 See :hg:`help dates` for a list of formats valid for -d/--date.
3455
3456
3456 .. container:: verbose
3457 .. container:: verbose
3457
3458
3458 Examples:
3459 Examples:
3459
3460
3460 - import a traditional patch from a website and detect renames::
3461 - import a traditional patch from a website and detect renames::
3461
3462
3462 hg import -s 80 http://example.com/bugfix.patch
3463 hg import -s 80 http://example.com/bugfix.patch
3463
3464
3464 - import a changeset from an hgweb server::
3465 - import a changeset from an hgweb server::
3465
3466
3466 hg import http://www.selenic.com/hg/rev/5ca8c111e9aa
3467 hg import http://www.selenic.com/hg/rev/5ca8c111e9aa
3467
3468
3468 - import all the patches in an Unix-style mbox::
3469 - import all the patches in an Unix-style mbox::
3469
3470
3470 hg import incoming-patches.mbox
3471 hg import incoming-patches.mbox
3471
3472
3472 - attempt to exactly restore an exported changeset (not always
3473 - attempt to exactly restore an exported changeset (not always
3473 possible)::
3474 possible)::
3474
3475
3475 hg import --exact proposed-fix.patch
3476 hg import --exact proposed-fix.patch
3476
3477
3477 Returns 0 on success.
3478 Returns 0 on success.
3478 """
3479 """
3479
3480
3480 if not patch1:
3481 if not patch1:
3481 raise util.Abort(_('need at least one patch to import'))
3482 raise util.Abort(_('need at least one patch to import'))
3482
3483
3483 patches = (patch1,) + patches
3484 patches = (patch1,) + patches
3484
3485
3485 date = opts.get('date')
3486 date = opts.get('date')
3486 if date:
3487 if date:
3487 opts['date'] = util.parsedate(date)
3488 opts['date'] = util.parsedate(date)
3488
3489
3489 editor = cmdutil.commiteditor
3490 editor = cmdutil.commiteditor
3490 if opts.get('edit'):
3491 if opts.get('edit'):
3491 editor = cmdutil.commitforceeditor
3492 editor = cmdutil.commitforceeditor
3492
3493
3493 update = not opts.get('bypass')
3494 update = not opts.get('bypass')
3494 if not update and opts.get('no_commit'):
3495 if not update and opts.get('no_commit'):
3495 raise util.Abort(_('cannot use --no-commit with --bypass'))
3496 raise util.Abort(_('cannot use --no-commit with --bypass'))
3496 try:
3497 try:
3497 sim = float(opts.get('similarity') or 0)
3498 sim = float(opts.get('similarity') or 0)
3498 except ValueError:
3499 except ValueError:
3499 raise util.Abort(_('similarity must be a number'))
3500 raise util.Abort(_('similarity must be a number'))
3500 if sim < 0 or sim > 100:
3501 if sim < 0 or sim > 100:
3501 raise util.Abort(_('similarity must be between 0 and 100'))
3502 raise util.Abort(_('similarity must be between 0 and 100'))
3502 if sim and not update:
3503 if sim and not update:
3503 raise util.Abort(_('cannot use --similarity with --bypass'))
3504 raise util.Abort(_('cannot use --similarity with --bypass'))
3504
3505
3505 if (opts.get('exact') or not opts.get('force')) and update:
3506 if (opts.get('exact') or not opts.get('force')) and update:
3506 cmdutil.bailifchanged(repo)
3507 cmdutil.bailifchanged(repo)
3507
3508
3508 base = opts["base"]
3509 base = opts["base"]
3509 strip = opts["strip"]
3510 strip = opts["strip"]
3510 wlock = lock = tr = None
3511 wlock = lock = tr = None
3511 msgs = []
3512 msgs = []
3512
3513
3513 def checkexact(repo, n, nodeid):
3514 def checkexact(repo, n, nodeid):
3514 if opts.get('exact') and hex(n) != nodeid:
3515 if opts.get('exact') and hex(n) != nodeid:
3515 repo.rollback()
3516 repo.rollback()
3516 raise util.Abort(_('patch is damaged or loses information'))
3517 raise util.Abort(_('patch is damaged or loses information'))
3517
3518
3518 def tryone(ui, hunk, parents):
3519 def tryone(ui, hunk, parents):
3519 tmpname, message, user, date, branch, nodeid, p1, p2 = \
3520 tmpname, message, user, date, branch, nodeid, p1, p2 = \
3520 patch.extract(ui, hunk)
3521 patch.extract(ui, hunk)
3521
3522
3522 if not tmpname:
3523 if not tmpname:
3523 return (None, None)
3524 return (None, None)
3524 msg = _('applied to working directory')
3525 msg = _('applied to working directory')
3525
3526
3526 try:
3527 try:
3527 cmdline_message = cmdutil.logmessage(ui, opts)
3528 cmdline_message = cmdutil.logmessage(ui, opts)
3528 if cmdline_message:
3529 if cmdline_message:
3529 # pickup the cmdline msg
3530 # pickup the cmdline msg
3530 message = cmdline_message
3531 message = cmdline_message
3531 elif message:
3532 elif message:
3532 # pickup the patch msg
3533 # pickup the patch msg
3533 message = message.strip()
3534 message = message.strip()
3534 else:
3535 else:
3535 # launch the editor
3536 # launch the editor
3536 message = None
3537 message = None
3537 ui.debug('message:\n%s\n' % message)
3538 ui.debug('message:\n%s\n' % message)
3538
3539
3539 if len(parents) == 1:
3540 if len(parents) == 1:
3540 parents.append(repo[nullid])
3541 parents.append(repo[nullid])
3541 if opts.get('exact'):
3542 if opts.get('exact'):
3542 if not nodeid or not p1:
3543 if not nodeid or not p1:
3543 raise util.Abort(_('not a Mercurial patch'))
3544 raise util.Abort(_('not a Mercurial patch'))
3544 p1 = repo[p1]
3545 p1 = repo[p1]
3545 p2 = repo[p2 or nullid]
3546 p2 = repo[p2 or nullid]
3546 elif p2:
3547 elif p2:
3547 try:
3548 try:
3548 p1 = repo[p1]
3549 p1 = repo[p1]
3549 p2 = repo[p2]
3550 p2 = repo[p2]
3550 # Without any options, consider p2 only if the
3551 # Without any options, consider p2 only if the
3551 # patch is being applied on top of the recorded
3552 # patch is being applied on top of the recorded
3552 # first parent.
3553 # first parent.
3553 if p1 != parents[0]:
3554 if p1 != parents[0]:
3554 p1 = parents[0]
3555 p1 = parents[0]
3555 p2 = repo[nullid]
3556 p2 = repo[nullid]
3556 except error.RepoError:
3557 except error.RepoError:
3557 p1, p2 = parents
3558 p1, p2 = parents
3558 else:
3559 else:
3559 p1, p2 = parents
3560 p1, p2 = parents
3560
3561
3561 n = None
3562 n = None
3562 if update:
3563 if update:
3563 if p1 != parents[0]:
3564 if p1 != parents[0]:
3564 hg.clean(repo, p1.node())
3565 hg.clean(repo, p1.node())
3565 if p2 != parents[1]:
3566 if p2 != parents[1]:
3566 repo.dirstate.setparents(p1.node(), p2.node())
3567 repo.dirstate.setparents(p1.node(), p2.node())
3567
3568
3568 if opts.get('exact') or opts.get('import_branch'):
3569 if opts.get('exact') or opts.get('import_branch'):
3569 repo.dirstate.setbranch(branch or 'default')
3570 repo.dirstate.setbranch(branch or 'default')
3570
3571
3571 files = set()
3572 files = set()
3572 patch.patch(ui, repo, tmpname, strip=strip, files=files,
3573 patch.patch(ui, repo, tmpname, strip=strip, files=files,
3573 eolmode=None, similarity=sim / 100.0)
3574 eolmode=None, similarity=sim / 100.0)
3574 files = list(files)
3575 files = list(files)
3575 if opts.get('no_commit'):
3576 if opts.get('no_commit'):
3576 if message:
3577 if message:
3577 msgs.append(message)
3578 msgs.append(message)
3578 else:
3579 else:
3579 if opts.get('exact') or p2:
3580 if opts.get('exact') or p2:
3580 # If you got here, you either use --force and know what
3581 # If you got here, you either use --force and know what
3581 # you are doing or used --exact or a merge patch while
3582 # you are doing or used --exact or a merge patch while
3582 # being updated to its first parent.
3583 # being updated to its first parent.
3583 m = None
3584 m = None
3584 else:
3585 else:
3585 m = scmutil.matchfiles(repo, files or [])
3586 m = scmutil.matchfiles(repo, files or [])
3586 n = repo.commit(message, opts.get('user') or user,
3587 n = repo.commit(message, opts.get('user') or user,
3587 opts.get('date') or date, match=m,
3588 opts.get('date') or date, match=m,
3588 editor=editor)
3589 editor=editor)
3589 checkexact(repo, n, nodeid)
3590 checkexact(repo, n, nodeid)
3590 else:
3591 else:
3591 if opts.get('exact') or opts.get('import_branch'):
3592 if opts.get('exact') or opts.get('import_branch'):
3592 branch = branch or 'default'
3593 branch = branch or 'default'
3593 else:
3594 else:
3594 branch = p1.branch()
3595 branch = p1.branch()
3595 store = patch.filestore()
3596 store = patch.filestore()
3596 try:
3597 try:
3597 files = set()
3598 files = set()
3598 try:
3599 try:
3599 patch.patchrepo(ui, repo, p1, store, tmpname, strip,
3600 patch.patchrepo(ui, repo, p1, store, tmpname, strip,
3600 files, eolmode=None)
3601 files, eolmode=None)
3601 except patch.PatchError, e:
3602 except patch.PatchError, e:
3602 raise util.Abort(str(e))
3603 raise util.Abort(str(e))
3603 memctx = patch.makememctx(repo, (p1.node(), p2.node()),
3604 memctx = patch.makememctx(repo, (p1.node(), p2.node()),
3604 message,
3605 message,
3605 opts.get('user') or user,
3606 opts.get('user') or user,
3606 opts.get('date') or date,
3607 opts.get('date') or date,
3607 branch, files, store,
3608 branch, files, store,
3608 editor=cmdutil.commiteditor)
3609 editor=cmdutil.commiteditor)
3609 repo.savecommitmessage(memctx.description())
3610 repo.savecommitmessage(memctx.description())
3610 n = memctx.commit()
3611 n = memctx.commit()
3611 checkexact(repo, n, nodeid)
3612 checkexact(repo, n, nodeid)
3612 finally:
3613 finally:
3613 store.close()
3614 store.close()
3614 if n:
3615 if n:
3615 # i18n: refers to a short changeset id
3616 # i18n: refers to a short changeset id
3616 msg = _('created %s') % short(n)
3617 msg = _('created %s') % short(n)
3617 return (msg, n)
3618 return (msg, n)
3618 finally:
3619 finally:
3619 os.unlink(tmpname)
3620 os.unlink(tmpname)
3620
3621
3621 try:
3622 try:
3622 try:
3623 try:
3623 wlock = repo.wlock()
3624 wlock = repo.wlock()
3624 lock = repo.lock()
3625 lock = repo.lock()
3625 tr = repo.transaction('import')
3626 tr = repo.transaction('import')
3626 parents = repo.parents()
3627 parents = repo.parents()
3627 for patchurl in patches:
3628 for patchurl in patches:
3628 if patchurl == '-':
3629 if patchurl == '-':
3629 ui.status(_('applying patch from stdin\n'))
3630 ui.status(_('applying patch from stdin\n'))
3630 patchfile = ui.fin
3631 patchfile = ui.fin
3631 patchurl = 'stdin' # for error message
3632 patchurl = 'stdin' # for error message
3632 else:
3633 else:
3633 patchurl = os.path.join(base, patchurl)
3634 patchurl = os.path.join(base, patchurl)
3634 ui.status(_('applying %s\n') % patchurl)
3635 ui.status(_('applying %s\n') % patchurl)
3635 patchfile = url.open(ui, patchurl)
3636 patchfile = url.open(ui, patchurl)
3636
3637
3637 haspatch = False
3638 haspatch = False
3638 for hunk in patch.split(patchfile):
3639 for hunk in patch.split(patchfile):
3639 (msg, node) = tryone(ui, hunk, parents)
3640 (msg, node) = tryone(ui, hunk, parents)
3640 if msg:
3641 if msg:
3641 haspatch = True
3642 haspatch = True
3642 ui.note(msg + '\n')
3643 ui.note(msg + '\n')
3643 if update or opts.get('exact'):
3644 if update or opts.get('exact'):
3644 parents = repo.parents()
3645 parents = repo.parents()
3645 else:
3646 else:
3646 parents = [repo[node]]
3647 parents = [repo[node]]
3647
3648
3648 if not haspatch:
3649 if not haspatch:
3649 raise util.Abort(_('%s: no diffs found') % patchurl)
3650 raise util.Abort(_('%s: no diffs found') % patchurl)
3650
3651
3651 tr.close()
3652 tr.close()
3652 if msgs:
3653 if msgs:
3653 repo.savecommitmessage('\n* * *\n'.join(msgs))
3654 repo.savecommitmessage('\n* * *\n'.join(msgs))
3654 except:
3655 except:
3655 # wlock.release() indirectly calls dirstate.write(): since
3656 # wlock.release() indirectly calls dirstate.write(): since
3656 # we're crashing, we do not want to change the working dir
3657 # we're crashing, we do not want to change the working dir
3657 # parent after all, so make sure it writes nothing
3658 # parent after all, so make sure it writes nothing
3658 repo.dirstate.invalidate()
3659 repo.dirstate.invalidate()
3659 raise
3660 raise
3660 finally:
3661 finally:
3661 if tr:
3662 if tr:
3662 tr.release()
3663 tr.release()
3663 release(lock, wlock)
3664 release(lock, wlock)
3664
3665
3665 @command('incoming|in',
3666 @command('incoming|in',
3666 [('f', 'force', None,
3667 [('f', 'force', None,
3667 _('run even if remote repository is unrelated')),
3668 _('run even if remote repository is unrelated')),
3668 ('n', 'newest-first', None, _('show newest record first')),
3669 ('n', 'newest-first', None, _('show newest record first')),
3669 ('', 'bundle', '',
3670 ('', 'bundle', '',
3670 _('file to store the bundles into'), _('FILE')),
3671 _('file to store the bundles into'), _('FILE')),
3671 ('r', 'rev', [], _('a remote changeset intended to be added'), _('REV')),
3672 ('r', 'rev', [], _('a remote changeset intended to be added'), _('REV')),
3672 ('B', 'bookmarks', False, _("compare bookmarks")),
3673 ('B', 'bookmarks', False, _("compare bookmarks")),
3673 ('b', 'branch', [],
3674 ('b', 'branch', [],
3674 _('a specific branch you would like to pull'), _('BRANCH')),
3675 _('a specific branch you would like to pull'), _('BRANCH')),
3675 ] + logopts + remoteopts + subrepoopts,
3676 ] + logopts + remoteopts + subrepoopts,
3676 _('[-p] [-n] [-M] [-f] [-r REV]... [--bundle FILENAME] [SOURCE]'))
3677 _('[-p] [-n] [-M] [-f] [-r REV]... [--bundle FILENAME] [SOURCE]'))
3677 def incoming(ui, repo, source="default", **opts):
3678 def incoming(ui, repo, source="default", **opts):
3678 """show new changesets found in source
3679 """show new changesets found in source
3679
3680
3680 Show new changesets found in the specified path/URL or the default
3681 Show new changesets found in the specified path/URL or the default
3681 pull location. These are the changesets that would have been pulled
3682 pull location. These are the changesets that would have been pulled
3682 if a pull at the time you issued this command.
3683 if a pull at the time you issued this command.
3683
3684
3684 For remote repository, using --bundle avoids downloading the
3685 For remote repository, using --bundle avoids downloading the
3685 changesets twice if the incoming is followed by a pull.
3686 changesets twice if the incoming is followed by a pull.
3686
3687
3687 See pull for valid source format details.
3688 See pull for valid source format details.
3688
3689
3689 Returns 0 if there are incoming changes, 1 otherwise.
3690 Returns 0 if there are incoming changes, 1 otherwise.
3690 """
3691 """
3691 if opts.get('bundle') and opts.get('subrepos'):
3692 if opts.get('bundle') and opts.get('subrepos'):
3692 raise util.Abort(_('cannot combine --bundle and --subrepos'))
3693 raise util.Abort(_('cannot combine --bundle and --subrepos'))
3693
3694
3694 if opts.get('bookmarks'):
3695 if opts.get('bookmarks'):
3695 source, branches = hg.parseurl(ui.expandpath(source),
3696 source, branches = hg.parseurl(ui.expandpath(source),
3696 opts.get('branch'))
3697 opts.get('branch'))
3697 other = hg.peer(repo, opts, source)
3698 other = hg.peer(repo, opts, source)
3698 if 'bookmarks' not in other.listkeys('namespaces'):
3699 if 'bookmarks' not in other.listkeys('namespaces'):
3699 ui.warn(_("remote doesn't support bookmarks\n"))
3700 ui.warn(_("remote doesn't support bookmarks\n"))
3700 return 0
3701 return 0
3701 ui.status(_('comparing with %s\n') % util.hidepassword(source))
3702 ui.status(_('comparing with %s\n') % util.hidepassword(source))
3702 return bookmarks.diff(ui, repo, other)
3703 return bookmarks.diff(ui, repo, other)
3703
3704
3704 repo._subtoppath = ui.expandpath(source)
3705 repo._subtoppath = ui.expandpath(source)
3705 try:
3706 try:
3706 return hg.incoming(ui, repo, source, opts)
3707 return hg.incoming(ui, repo, source, opts)
3707 finally:
3708 finally:
3708 del repo._subtoppath
3709 del repo._subtoppath
3709
3710
3710
3711
3711 @command('^init', remoteopts, _('[-e CMD] [--remotecmd CMD] [DEST]'))
3712 @command('^init', remoteopts, _('[-e CMD] [--remotecmd CMD] [DEST]'))
3712 def init(ui, dest=".", **opts):
3713 def init(ui, dest=".", **opts):
3713 """create a new repository in the given directory
3714 """create a new repository in the given directory
3714
3715
3715 Initialize a new repository in the given directory. If the given
3716 Initialize a new repository in the given directory. If the given
3716 directory does not exist, it will be created.
3717 directory does not exist, it will be created.
3717
3718
3718 If no directory is given, the current directory is used.
3719 If no directory is given, the current directory is used.
3719
3720
3720 It is possible to specify an ``ssh://`` URL as the destination.
3721 It is possible to specify an ``ssh://`` URL as the destination.
3721 See :hg:`help urls` for more information.
3722 See :hg:`help urls` for more information.
3722
3723
3723 Returns 0 on success.
3724 Returns 0 on success.
3724 """
3725 """
3725 hg.peer(ui, opts, ui.expandpath(dest), create=True)
3726 hg.peer(ui, opts, ui.expandpath(dest), create=True)
3726
3727
3727 @command('locate',
3728 @command('locate',
3728 [('r', 'rev', '', _('search the repository as it is in REV'), _('REV')),
3729 [('r', 'rev', '', _('search the repository as it is in REV'), _('REV')),
3729 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
3730 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
3730 ('f', 'fullpath', None, _('print complete paths from the filesystem root')),
3731 ('f', 'fullpath', None, _('print complete paths from the filesystem root')),
3731 ] + walkopts,
3732 ] + walkopts,
3732 _('[OPTION]... [PATTERN]...'))
3733 _('[OPTION]... [PATTERN]...'))
3733 def locate(ui, repo, *pats, **opts):
3734 def locate(ui, repo, *pats, **opts):
3734 """locate files matching specific patterns
3735 """locate files matching specific patterns
3735
3736
3736 Print files under Mercurial control in the working directory whose
3737 Print files under Mercurial control in the working directory whose
3737 names match the given patterns.
3738 names match the given patterns.
3738
3739
3739 By default, this command searches all directories in the working
3740 By default, this command searches all directories in the working
3740 directory. To search just the current directory and its
3741 directory. To search just the current directory and its
3741 subdirectories, use "--include .".
3742 subdirectories, use "--include .".
3742
3743
3743 If no patterns are given to match, this command prints the names
3744 If no patterns are given to match, this command prints the names
3744 of all files under Mercurial control in the working directory.
3745 of all files under Mercurial control in the working directory.
3745
3746
3746 If you want to feed the output of this command into the "xargs"
3747 If you want to feed the output of this command into the "xargs"
3747 command, use the -0 option to both this command and "xargs". This
3748 command, use the -0 option to both this command and "xargs". This
3748 will avoid the problem of "xargs" treating single filenames that
3749 will avoid the problem of "xargs" treating single filenames that
3749 contain whitespace as multiple filenames.
3750 contain whitespace as multiple filenames.
3750
3751
3751 Returns 0 if a match is found, 1 otherwise.
3752 Returns 0 if a match is found, 1 otherwise.
3752 """
3753 """
3753 end = opts.get('print0') and '\0' or '\n'
3754 end = opts.get('print0') and '\0' or '\n'
3754 rev = scmutil.revsingle(repo, opts.get('rev'), None).node()
3755 rev = scmutil.revsingle(repo, opts.get('rev'), None).node()
3755
3756
3756 ret = 1
3757 ret = 1
3757 m = scmutil.match(repo[rev], pats, opts, default='relglob')
3758 m = scmutil.match(repo[rev], pats, opts, default='relglob')
3758 m.bad = lambda x, y: False
3759 m.bad = lambda x, y: False
3759 for abs in repo[rev].walk(m):
3760 for abs in repo[rev].walk(m):
3760 if not rev and abs not in repo.dirstate:
3761 if not rev and abs not in repo.dirstate:
3761 continue
3762 continue
3762 if opts.get('fullpath'):
3763 if opts.get('fullpath'):
3763 ui.write(repo.wjoin(abs), end)
3764 ui.write(repo.wjoin(abs), end)
3764 else:
3765 else:
3765 ui.write(((pats and m.rel(abs)) or abs), end)
3766 ui.write(((pats and m.rel(abs)) or abs), end)
3766 ret = 0
3767 ret = 0
3767
3768
3768 return ret
3769 return ret
3769
3770
3770 @command('^log|history',
3771 @command('^log|history',
3771 [('f', 'follow', None,
3772 [('f', 'follow', None,
3772 _('follow changeset history, or file history across copies and renames')),
3773 _('follow changeset history, or file history across copies and renames')),
3773 ('', 'follow-first', None,
3774 ('', 'follow-first', None,
3774 _('only follow the first parent of merge changesets (DEPRECATED)')),
3775 _('only follow the first parent of merge changesets (DEPRECATED)')),
3775 ('d', 'date', '', _('show revisions matching date spec'), _('DATE')),
3776 ('d', 'date', '', _('show revisions matching date spec'), _('DATE')),
3776 ('C', 'copies', None, _('show copied files')),
3777 ('C', 'copies', None, _('show copied files')),
3777 ('k', 'keyword', [],
3778 ('k', 'keyword', [],
3778 _('do case-insensitive search for a given text'), _('TEXT')),
3779 _('do case-insensitive search for a given text'), _('TEXT')),
3779 ('r', 'rev', [], _('show the specified revision or range'), _('REV')),
3780 ('r', 'rev', [], _('show the specified revision or range'), _('REV')),
3780 ('', 'removed', None, _('include revisions where files were removed')),
3781 ('', 'removed', None, _('include revisions where files were removed')),
3781 ('m', 'only-merges', None, _('show only merges (DEPRECATED)')),
3782 ('m', 'only-merges', None, _('show only merges (DEPRECATED)')),
3782 ('u', 'user', [], _('revisions committed by user'), _('USER')),
3783 ('u', 'user', [], _('revisions committed by user'), _('USER')),
3783 ('', 'only-branch', [],
3784 ('', 'only-branch', [],
3784 _('show only changesets within the given named branch (DEPRECATED)'),
3785 _('show only changesets within the given named branch (DEPRECATED)'),
3785 _('BRANCH')),
3786 _('BRANCH')),
3786 ('b', 'branch', [],
3787 ('b', 'branch', [],
3787 _('show changesets within the given named branch'), _('BRANCH')),
3788 _('show changesets within the given named branch'), _('BRANCH')),
3788 ('P', 'prune', [],
3789 ('P', 'prune', [],
3789 _('do not display revision or any of its ancestors'), _('REV')),
3790 _('do not display revision or any of its ancestors'), _('REV')),
3790 ('', 'hidden', False, _('show hidden changesets (DEPRECATED)')),
3791 ('', 'hidden', False, _('show hidden changesets (DEPRECATED)')),
3791 ] + logopts + walkopts,
3792 ] + logopts + walkopts,
3792 _('[OPTION]... [FILE]'))
3793 _('[OPTION]... [FILE]'))
3793 def log(ui, repo, *pats, **opts):
3794 def log(ui, repo, *pats, **opts):
3794 """show revision history of entire repository or files
3795 """show revision history of entire repository or files
3795
3796
3796 Print the revision history of the specified files or the entire
3797 Print the revision history of the specified files or the entire
3797 project.
3798 project.
3798
3799
3799 If no revision range is specified, the default is ``tip:0`` unless
3800 If no revision range is specified, the default is ``tip:0`` unless
3800 --follow is set, in which case the working directory parent is
3801 --follow is set, in which case the working directory parent is
3801 used as the starting revision.
3802 used as the starting revision.
3802
3803
3803 File history is shown without following rename or copy history of
3804 File history is shown without following rename or copy history of
3804 files. Use -f/--follow with a filename to follow history across
3805 files. Use -f/--follow with a filename to follow history across
3805 renames and copies. --follow without a filename will only show
3806 renames and copies. --follow without a filename will only show
3806 ancestors or descendants of the starting revision.
3807 ancestors or descendants of the starting revision.
3807
3808
3808 By default this command prints revision number and changeset id,
3809 By default this command prints revision number and changeset id,
3809 tags, non-trivial parents, user, date and time, and a summary for
3810 tags, non-trivial parents, user, date and time, and a summary for
3810 each commit. When the -v/--verbose switch is used, the list of
3811 each commit. When the -v/--verbose switch is used, the list of
3811 changed files and full commit message are shown.
3812 changed files and full commit message are shown.
3812
3813
3813 .. note::
3814 .. note::
3814 log -p/--patch may generate unexpected diff output for merge
3815 log -p/--patch may generate unexpected diff output for merge
3815 changesets, as it will only compare the merge changeset against
3816 changesets, as it will only compare the merge changeset against
3816 its first parent. Also, only files different from BOTH parents
3817 its first parent. Also, only files different from BOTH parents
3817 will appear in files:.
3818 will appear in files:.
3818
3819
3819 .. note::
3820 .. note::
3820 for performance reasons, log FILE may omit duplicate changes
3821 for performance reasons, log FILE may omit duplicate changes
3821 made on branches and will not show deletions. To see all
3822 made on branches and will not show deletions. To see all
3822 changes including duplicates and deletions, use the --removed
3823 changes including duplicates and deletions, use the --removed
3823 switch.
3824 switch.
3824
3825
3825 .. container:: verbose
3826 .. container:: verbose
3826
3827
3827 Some examples:
3828 Some examples:
3828
3829
3829 - changesets with full descriptions and file lists::
3830 - changesets with full descriptions and file lists::
3830
3831
3831 hg log -v
3832 hg log -v
3832
3833
3833 - changesets ancestral to the working directory::
3834 - changesets ancestral to the working directory::
3834
3835
3835 hg log -f
3836 hg log -f
3836
3837
3837 - last 10 commits on the current branch::
3838 - last 10 commits on the current branch::
3838
3839
3839 hg log -l 10 -b .
3840 hg log -l 10 -b .
3840
3841
3841 - changesets showing all modifications of a file, including removals::
3842 - changesets showing all modifications of a file, including removals::
3842
3843
3843 hg log --removed file.c
3844 hg log --removed file.c
3844
3845
3845 - all changesets that touch a directory, with diffs, excluding merges::
3846 - all changesets that touch a directory, with diffs, excluding merges::
3846
3847
3847 hg log -Mp lib/
3848 hg log -Mp lib/
3848
3849
3849 - all revision numbers that match a keyword::
3850 - all revision numbers that match a keyword::
3850
3851
3851 hg log -k bug --template "{rev}\\n"
3852 hg log -k bug --template "{rev}\\n"
3852
3853
3853 - check if a given changeset is included is a tagged release::
3854 - check if a given changeset is included is a tagged release::
3854
3855
3855 hg log -r "a21ccf and ancestor(1.9)"
3856 hg log -r "a21ccf and ancestor(1.9)"
3856
3857
3857 - find all changesets by some user in a date range::
3858 - find all changesets by some user in a date range::
3858
3859
3859 hg log -k alice -d "may 2008 to jul 2008"
3860 hg log -k alice -d "may 2008 to jul 2008"
3860
3861
3861 - summary of all changesets after the last tag::
3862 - summary of all changesets after the last tag::
3862
3863
3863 hg log -r "last(tagged())::" --template "{desc|firstline}\\n"
3864 hg log -r "last(tagged())::" --template "{desc|firstline}\\n"
3864
3865
3865 See :hg:`help dates` for a list of formats valid for -d/--date.
3866 See :hg:`help dates` for a list of formats valid for -d/--date.
3866
3867
3867 See :hg:`help revisions` and :hg:`help revsets` for more about
3868 See :hg:`help revisions` and :hg:`help revsets` for more about
3868 specifying revisions.
3869 specifying revisions.
3869
3870
3870 Returns 0 on success.
3871 Returns 0 on success.
3871 """
3872 """
3872
3873
3873 matchfn = scmutil.match(repo[None], pats, opts)
3874 matchfn = scmutil.match(repo[None], pats, opts)
3874 limit = cmdutil.loglimit(opts)
3875 limit = cmdutil.loglimit(opts)
3875 count = 0
3876 count = 0
3876
3877
3877 endrev = None
3878 endrev = None
3878 if opts.get('copies') and opts.get('rev'):
3879 if opts.get('copies') and opts.get('rev'):
3879 endrev = max(scmutil.revrange(repo, opts.get('rev'))) + 1
3880 endrev = max(scmutil.revrange(repo, opts.get('rev'))) + 1
3880
3881
3881 df = False
3882 df = False
3882 if opts["date"]:
3883 if opts["date"]:
3883 df = util.matchdate(opts["date"])
3884 df = util.matchdate(opts["date"])
3884
3885
3885 branches = opts.get('branch', []) + opts.get('only_branch', [])
3886 branches = opts.get('branch', []) + opts.get('only_branch', [])
3886 opts['branch'] = [repo.lookupbranch(b) for b in branches]
3887 opts['branch'] = [repo.lookupbranch(b) for b in branches]
3887
3888
3888 displayer = cmdutil.show_changeset(ui, repo, opts, True)
3889 displayer = cmdutil.show_changeset(ui, repo, opts, True)
3889 def prep(ctx, fns):
3890 def prep(ctx, fns):
3890 rev = ctx.rev()
3891 rev = ctx.rev()
3891 parents = [p for p in repo.changelog.parentrevs(rev)
3892 parents = [p for p in repo.changelog.parentrevs(rev)
3892 if p != nullrev]
3893 if p != nullrev]
3893 if opts.get('no_merges') and len(parents) == 2:
3894 if opts.get('no_merges') and len(parents) == 2:
3894 return
3895 return
3895 if opts.get('only_merges') and len(parents) != 2:
3896 if opts.get('only_merges') and len(parents) != 2:
3896 return
3897 return
3897 if opts.get('branch') and ctx.branch() not in opts['branch']:
3898 if opts.get('branch') and ctx.branch() not in opts['branch']:
3898 return
3899 return
3899 if not opts.get('hidden') and ctx.hidden():
3900 if not opts.get('hidden') and ctx.hidden():
3900 return
3901 return
3901 if df and not df(ctx.date()[0]):
3902 if df and not df(ctx.date()[0]):
3902 return
3903 return
3903
3904
3904 lower = encoding.lower
3905 lower = encoding.lower
3905 if opts.get('user'):
3906 if opts.get('user'):
3906 luser = lower(ctx.user())
3907 luser = lower(ctx.user())
3907 for k in [lower(x) for x in opts['user']]:
3908 for k in [lower(x) for x in opts['user']]:
3908 if (k in luser):
3909 if (k in luser):
3909 break
3910 break
3910 else:
3911 else:
3911 return
3912 return
3912 if opts.get('keyword'):
3913 if opts.get('keyword'):
3913 luser = lower(ctx.user())
3914 luser = lower(ctx.user())
3914 ldesc = lower(ctx.description())
3915 ldesc = lower(ctx.description())
3915 lfiles = lower(" ".join(ctx.files()))
3916 lfiles = lower(" ".join(ctx.files()))
3916 for k in [lower(x) for x in opts['keyword']]:
3917 for k in [lower(x) for x in opts['keyword']]:
3917 if (k in luser or k in ldesc or k in lfiles):
3918 if (k in luser or k in ldesc or k in lfiles):
3918 break
3919 break
3919 else:
3920 else:
3920 return
3921 return
3921
3922
3922 copies = None
3923 copies = None
3923 if opts.get('copies') and rev:
3924 if opts.get('copies') and rev:
3924 copies = []
3925 copies = []
3925 getrenamed = templatekw.getrenamedfn(repo, endrev=endrev)
3926 getrenamed = templatekw.getrenamedfn(repo, endrev=endrev)
3926 for fn in ctx.files():
3927 for fn in ctx.files():
3927 rename = getrenamed(fn, rev)
3928 rename = getrenamed(fn, rev)
3928 if rename:
3929 if rename:
3929 copies.append((fn, rename[0]))
3930 copies.append((fn, rename[0]))
3930
3931
3931 revmatchfn = None
3932 revmatchfn = None
3932 if opts.get('patch') or opts.get('stat'):
3933 if opts.get('patch') or opts.get('stat'):
3933 if opts.get('follow') or opts.get('follow_first'):
3934 if opts.get('follow') or opts.get('follow_first'):
3934 # note: this might be wrong when following through merges
3935 # note: this might be wrong when following through merges
3935 revmatchfn = scmutil.match(repo[None], fns, default='path')
3936 revmatchfn = scmutil.match(repo[None], fns, default='path')
3936 else:
3937 else:
3937 revmatchfn = matchfn
3938 revmatchfn = matchfn
3938
3939
3939 displayer.show(ctx, copies=copies, matchfn=revmatchfn)
3940 displayer.show(ctx, copies=copies, matchfn=revmatchfn)
3940
3941
3941 for ctx in cmdutil.walkchangerevs(repo, matchfn, opts, prep):
3942 for ctx in cmdutil.walkchangerevs(repo, matchfn, opts, prep):
3942 if count == limit:
3943 if count == limit:
3943 break
3944 break
3944 if displayer.flush(ctx.rev()):
3945 if displayer.flush(ctx.rev()):
3945 count += 1
3946 count += 1
3946 displayer.close()
3947 displayer.close()
3947
3948
3948 @command('manifest',
3949 @command('manifest',
3949 [('r', 'rev', '', _('revision to display'), _('REV')),
3950 [('r', 'rev', '', _('revision to display'), _('REV')),
3950 ('', 'all', False, _("list files from all revisions"))],
3951 ('', 'all', False, _("list files from all revisions"))],
3951 _('[-r REV]'))
3952 _('[-r REV]'))
3952 def manifest(ui, repo, node=None, rev=None, **opts):
3953 def manifest(ui, repo, node=None, rev=None, **opts):
3953 """output the current or given revision of the project manifest
3954 """output the current or given revision of the project manifest
3954
3955
3955 Print a list of version controlled files for the given revision.
3956 Print a list of version controlled files for the given revision.
3956 If no revision is given, the first parent of the working directory
3957 If no revision is given, the first parent of the working directory
3957 is used, or the null revision if no revision is checked out.
3958 is used, or the null revision if no revision is checked out.
3958
3959
3959 With -v, print file permissions, symlink and executable bits.
3960 With -v, print file permissions, symlink and executable bits.
3960 With --debug, print file revision hashes.
3961 With --debug, print file revision hashes.
3961
3962
3962 If option --all is specified, the list of all files from all revisions
3963 If option --all is specified, the list of all files from all revisions
3963 is printed. This includes deleted and renamed files.
3964 is printed. This includes deleted and renamed files.
3964
3965
3965 Returns 0 on success.
3966 Returns 0 on success.
3966 """
3967 """
3967 if opts.get('all'):
3968 if opts.get('all'):
3968 if rev or node:
3969 if rev or node:
3969 raise util.Abort(_("can't specify a revision with --all"))
3970 raise util.Abort(_("can't specify a revision with --all"))
3970
3971
3971 res = []
3972 res = []
3972 prefix = "data/"
3973 prefix = "data/"
3973 suffix = ".i"
3974 suffix = ".i"
3974 plen = len(prefix)
3975 plen = len(prefix)
3975 slen = len(suffix)
3976 slen = len(suffix)
3976 lock = repo.lock()
3977 lock = repo.lock()
3977 try:
3978 try:
3978 for fn, b, size in repo.store.datafiles():
3979 for fn, b, size in repo.store.datafiles():
3979 if size != 0 and fn[-slen:] == suffix and fn[:plen] == prefix:
3980 if size != 0 and fn[-slen:] == suffix and fn[:plen] == prefix:
3980 res.append(fn[plen:-slen])
3981 res.append(fn[plen:-slen])
3981 finally:
3982 finally:
3982 lock.release()
3983 lock.release()
3983 for f in sorted(res):
3984 for f in sorted(res):
3984 ui.write("%s\n" % f)
3985 ui.write("%s\n" % f)
3985 return
3986 return
3986
3987
3987 if rev and node:
3988 if rev and node:
3988 raise util.Abort(_("please specify just one revision"))
3989 raise util.Abort(_("please specify just one revision"))
3989
3990
3990 if not node:
3991 if not node:
3991 node = rev
3992 node = rev
3992
3993
3993 decor = {'l':'644 @ ', 'x':'755 * ', '':'644 '}
3994 decor = {'l':'644 @ ', 'x':'755 * ', '':'644 '}
3994 ctx = scmutil.revsingle(repo, node)
3995 ctx = scmutil.revsingle(repo, node)
3995 for f in ctx:
3996 for f in ctx:
3996 if ui.debugflag:
3997 if ui.debugflag:
3997 ui.write("%40s " % hex(ctx.manifest()[f]))
3998 ui.write("%40s " % hex(ctx.manifest()[f]))
3998 if ui.verbose:
3999 if ui.verbose:
3999 ui.write(decor[ctx.flags(f)])
4000 ui.write(decor[ctx.flags(f)])
4000 ui.write("%s\n" % f)
4001 ui.write("%s\n" % f)
4001
4002
4002 @command('^merge',
4003 @command('^merge',
4003 [('f', 'force', None, _('force a merge with outstanding changes')),
4004 [('f', 'force', None, _('force a merge with outstanding changes')),
4004 ('r', 'rev', '', _('revision to merge'), _('REV')),
4005 ('r', 'rev', '', _('revision to merge'), _('REV')),
4005 ('P', 'preview', None,
4006 ('P', 'preview', None,
4006 _('review revisions to merge (no merge is performed)'))
4007 _('review revisions to merge (no merge is performed)'))
4007 ] + mergetoolopts,
4008 ] + mergetoolopts,
4008 _('[-P] [-f] [[-r] REV]'))
4009 _('[-P] [-f] [[-r] REV]'))
4009 def merge(ui, repo, node=None, **opts):
4010 def merge(ui, repo, node=None, **opts):
4010 """merge working directory with another revision
4011 """merge working directory with another revision
4011
4012
4012 The current working directory is updated with all changes made in
4013 The current working directory is updated with all changes made in
4013 the requested revision since the last common predecessor revision.
4014 the requested revision since the last common predecessor revision.
4014
4015
4015 Files that changed between either parent are marked as changed for
4016 Files that changed between either parent are marked as changed for
4016 the next commit and a commit must be performed before any further
4017 the next commit and a commit must be performed before any further
4017 updates to the repository are allowed. The next commit will have
4018 updates to the repository are allowed. The next commit will have
4018 two parents.
4019 two parents.
4019
4020
4020 ``--tool`` can be used to specify the merge tool used for file
4021 ``--tool`` can be used to specify the merge tool used for file
4021 merges. It overrides the HGMERGE environment variable and your
4022 merges. It overrides the HGMERGE environment variable and your
4022 configuration files. See :hg:`help merge-tools` for options.
4023 configuration files. See :hg:`help merge-tools` for options.
4023
4024
4024 If no revision is specified, the working directory's parent is a
4025 If no revision is specified, the working directory's parent is a
4025 head revision, and the current branch contains exactly one other
4026 head revision, and the current branch contains exactly one other
4026 head, the other head is merged with by default. Otherwise, an
4027 head, the other head is merged with by default. Otherwise, an
4027 explicit revision with which to merge with must be provided.
4028 explicit revision with which to merge with must be provided.
4028
4029
4029 :hg:`resolve` must be used to resolve unresolved files.
4030 :hg:`resolve` must be used to resolve unresolved files.
4030
4031
4031 To undo an uncommitted merge, use :hg:`update --clean .` which
4032 To undo an uncommitted merge, use :hg:`update --clean .` which
4032 will check out a clean copy of the original merge parent, losing
4033 will check out a clean copy of the original merge parent, losing
4033 all changes.
4034 all changes.
4034
4035
4035 Returns 0 on success, 1 if there are unresolved files.
4036 Returns 0 on success, 1 if there are unresolved files.
4036 """
4037 """
4037
4038
4038 if opts.get('rev') and node:
4039 if opts.get('rev') and node:
4039 raise util.Abort(_("please specify just one revision"))
4040 raise util.Abort(_("please specify just one revision"))
4040 if not node:
4041 if not node:
4041 node = opts.get('rev')
4042 node = opts.get('rev')
4042
4043
4043 if not node:
4044 if not node:
4044 branch = repo[None].branch()
4045 branch = repo[None].branch()
4045 bheads = repo.branchheads(branch)
4046 bheads = repo.branchheads(branch)
4046 if len(bheads) > 2:
4047 if len(bheads) > 2:
4047 raise util.Abort(_("branch '%s' has %d heads - "
4048 raise util.Abort(_("branch '%s' has %d heads - "
4048 "please merge with an explicit rev")
4049 "please merge with an explicit rev")
4049 % (branch, len(bheads)),
4050 % (branch, len(bheads)),
4050 hint=_("run 'hg heads .' to see heads"))
4051 hint=_("run 'hg heads .' to see heads"))
4051
4052
4052 parent = repo.dirstate.p1()
4053 parent = repo.dirstate.p1()
4053 if len(bheads) == 1:
4054 if len(bheads) == 1:
4054 if len(repo.heads()) > 1:
4055 if len(repo.heads()) > 1:
4055 raise util.Abort(_("branch '%s' has one head - "
4056 raise util.Abort(_("branch '%s' has one head - "
4056 "please merge with an explicit rev")
4057 "please merge with an explicit rev")
4057 % branch,
4058 % branch,
4058 hint=_("run 'hg heads' to see all heads"))
4059 hint=_("run 'hg heads' to see all heads"))
4059 msg, hint = _('nothing to merge'), None
4060 msg, hint = _('nothing to merge'), None
4060 if parent != repo.lookup(branch):
4061 if parent != repo.lookup(branch):
4061 hint = _("use 'hg update' instead")
4062 hint = _("use 'hg update' instead")
4062 raise util.Abort(msg, hint=hint)
4063 raise util.Abort(msg, hint=hint)
4063
4064
4064 if parent not in bheads:
4065 if parent not in bheads:
4065 raise util.Abort(_('working directory not at a head revision'),
4066 raise util.Abort(_('working directory not at a head revision'),
4066 hint=_("use 'hg update' or merge with an "
4067 hint=_("use 'hg update' or merge with an "
4067 "explicit revision"))
4068 "explicit revision"))
4068 node = parent == bheads[0] and bheads[-1] or bheads[0]
4069 node = parent == bheads[0] and bheads[-1] or bheads[0]
4069 else:
4070 else:
4070 node = scmutil.revsingle(repo, node).node()
4071 node = scmutil.revsingle(repo, node).node()
4071
4072
4072 if opts.get('preview'):
4073 if opts.get('preview'):
4073 # find nodes that are ancestors of p2 but not of p1
4074 # find nodes that are ancestors of p2 but not of p1
4074 p1 = repo.lookup('.')
4075 p1 = repo.lookup('.')
4075 p2 = repo.lookup(node)
4076 p2 = repo.lookup(node)
4076 nodes = repo.changelog.findmissing(common=[p1], heads=[p2])
4077 nodes = repo.changelog.findmissing(common=[p1], heads=[p2])
4077
4078
4078 displayer = cmdutil.show_changeset(ui, repo, opts)
4079 displayer = cmdutil.show_changeset(ui, repo, opts)
4079 for node in nodes:
4080 for node in nodes:
4080 displayer.show(repo[node])
4081 displayer.show(repo[node])
4081 displayer.close()
4082 displayer.close()
4082 return 0
4083 return 0
4083
4084
4084 try:
4085 try:
4085 # ui.forcemerge is an internal variable, do not document
4086 # ui.forcemerge is an internal variable, do not document
4086 repo.ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
4087 repo.ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
4087 return hg.merge(repo, node, force=opts.get('force'))
4088 return hg.merge(repo, node, force=opts.get('force'))
4088 finally:
4089 finally:
4089 ui.setconfig('ui', 'forcemerge', '')
4090 ui.setconfig('ui', 'forcemerge', '')
4090
4091
4091 @command('outgoing|out',
4092 @command('outgoing|out',
4092 [('f', 'force', None, _('run even when the destination is unrelated')),
4093 [('f', 'force', None, _('run even when the destination is unrelated')),
4093 ('r', 'rev', [],
4094 ('r', 'rev', [],
4094 _('a changeset intended to be included in the destination'), _('REV')),
4095 _('a changeset intended to be included in the destination'), _('REV')),
4095 ('n', 'newest-first', None, _('show newest record first')),
4096 ('n', 'newest-first', None, _('show newest record first')),
4096 ('B', 'bookmarks', False, _('compare bookmarks')),
4097 ('B', 'bookmarks', False, _('compare bookmarks')),
4097 ('b', 'branch', [], _('a specific branch you would like to push'),
4098 ('b', 'branch', [], _('a specific branch you would like to push'),
4098 _('BRANCH')),
4099 _('BRANCH')),
4099 ] + logopts + remoteopts + subrepoopts,
4100 ] + logopts + remoteopts + subrepoopts,
4100 _('[-M] [-p] [-n] [-f] [-r REV]... [DEST]'))
4101 _('[-M] [-p] [-n] [-f] [-r REV]... [DEST]'))
4101 def outgoing(ui, repo, dest=None, **opts):
4102 def outgoing(ui, repo, dest=None, **opts):
4102 """show changesets not found in the destination
4103 """show changesets not found in the destination
4103
4104
4104 Show changesets not found in the specified destination repository
4105 Show changesets not found in the specified destination repository
4105 or the default push location. These are the changesets that would
4106 or the default push location. These are the changesets that would
4106 be pushed if a push was requested.
4107 be pushed if a push was requested.
4107
4108
4108 See pull for details of valid destination formats.
4109 See pull for details of valid destination formats.
4109
4110
4110 Returns 0 if there are outgoing changes, 1 otherwise.
4111 Returns 0 if there are outgoing changes, 1 otherwise.
4111 """
4112 """
4112
4113
4113 if opts.get('bookmarks'):
4114 if opts.get('bookmarks'):
4114 dest = ui.expandpath(dest or 'default-push', dest or 'default')
4115 dest = ui.expandpath(dest or 'default-push', dest or 'default')
4115 dest, branches = hg.parseurl(dest, opts.get('branch'))
4116 dest, branches = hg.parseurl(dest, opts.get('branch'))
4116 other = hg.peer(repo, opts, dest)
4117 other = hg.peer(repo, opts, dest)
4117 if 'bookmarks' not in other.listkeys('namespaces'):
4118 if 'bookmarks' not in other.listkeys('namespaces'):
4118 ui.warn(_("remote doesn't support bookmarks\n"))
4119 ui.warn(_("remote doesn't support bookmarks\n"))
4119 return 0
4120 return 0
4120 ui.status(_('comparing with %s\n') % util.hidepassword(dest))
4121 ui.status(_('comparing with %s\n') % util.hidepassword(dest))
4121 return bookmarks.diff(ui, other, repo)
4122 return bookmarks.diff(ui, other, repo)
4122
4123
4123 repo._subtoppath = ui.expandpath(dest or 'default-push', dest or 'default')
4124 repo._subtoppath = ui.expandpath(dest or 'default-push', dest or 'default')
4124 try:
4125 try:
4125 return hg.outgoing(ui, repo, dest, opts)
4126 return hg.outgoing(ui, repo, dest, opts)
4126 finally:
4127 finally:
4127 del repo._subtoppath
4128 del repo._subtoppath
4128
4129
4129 @command('parents',
4130 @command('parents',
4130 [('r', 'rev', '', _('show parents of the specified revision'), _('REV')),
4131 [('r', 'rev', '', _('show parents of the specified revision'), _('REV')),
4131 ] + templateopts,
4132 ] + templateopts,
4132 _('[-r REV] [FILE]'))
4133 _('[-r REV] [FILE]'))
4133 def parents(ui, repo, file_=None, **opts):
4134 def parents(ui, repo, file_=None, **opts):
4134 """show the parents of the working directory or revision
4135 """show the parents of the working directory or revision
4135
4136
4136 Print the working directory's parent revisions. If a revision is
4137 Print the working directory's parent revisions. If a revision is
4137 given via -r/--rev, the parent of that revision will be printed.
4138 given via -r/--rev, the parent of that revision will be printed.
4138 If a file argument is given, the revision in which the file was
4139 If a file argument is given, the revision in which the file was
4139 last changed (before the working directory revision or the
4140 last changed (before the working directory revision or the
4140 argument to --rev if given) is printed.
4141 argument to --rev if given) is printed.
4141
4142
4142 Returns 0 on success.
4143 Returns 0 on success.
4143 """
4144 """
4144
4145
4145 ctx = scmutil.revsingle(repo, opts.get('rev'), None)
4146 ctx = scmutil.revsingle(repo, opts.get('rev'), None)
4146
4147
4147 if file_:
4148 if file_:
4148 m = scmutil.match(ctx, (file_,), opts)
4149 m = scmutil.match(ctx, (file_,), opts)
4149 if m.anypats() or len(m.files()) != 1:
4150 if m.anypats() or len(m.files()) != 1:
4150 raise util.Abort(_('can only specify an explicit filename'))
4151 raise util.Abort(_('can only specify an explicit filename'))
4151 file_ = m.files()[0]
4152 file_ = m.files()[0]
4152 filenodes = []
4153 filenodes = []
4153 for cp in ctx.parents():
4154 for cp in ctx.parents():
4154 if not cp:
4155 if not cp:
4155 continue
4156 continue
4156 try:
4157 try:
4157 filenodes.append(cp.filenode(file_))
4158 filenodes.append(cp.filenode(file_))
4158 except error.LookupError:
4159 except error.LookupError:
4159 pass
4160 pass
4160 if not filenodes:
4161 if not filenodes:
4161 raise util.Abort(_("'%s' not found in manifest!") % file_)
4162 raise util.Abort(_("'%s' not found in manifest!") % file_)
4162 fl = repo.file(file_)
4163 fl = repo.file(file_)
4163 p = [repo.lookup(fl.linkrev(fl.rev(fn))) for fn in filenodes]
4164 p = [repo.lookup(fl.linkrev(fl.rev(fn))) for fn in filenodes]
4164 else:
4165 else:
4165 p = [cp.node() for cp in ctx.parents()]
4166 p = [cp.node() for cp in ctx.parents()]
4166
4167
4167 displayer = cmdutil.show_changeset(ui, repo, opts)
4168 displayer = cmdutil.show_changeset(ui, repo, opts)
4168 for n in p:
4169 for n in p:
4169 if n != nullid:
4170 if n != nullid:
4170 displayer.show(repo[n])
4171 displayer.show(repo[n])
4171 displayer.close()
4172 displayer.close()
4172
4173
4173 @command('paths', [], _('[NAME]'))
4174 @command('paths', [], _('[NAME]'))
4174 def paths(ui, repo, search=None):
4175 def paths(ui, repo, search=None):
4175 """show aliases for remote repositories
4176 """show aliases for remote repositories
4176
4177
4177 Show definition of symbolic path name NAME. If no name is given,
4178 Show definition of symbolic path name NAME. If no name is given,
4178 show definition of all available names.
4179 show definition of all available names.
4179
4180
4180 Option -q/--quiet suppresses all output when searching for NAME
4181 Option -q/--quiet suppresses all output when searching for NAME
4181 and shows only the path names when listing all definitions.
4182 and shows only the path names when listing all definitions.
4182
4183
4183 Path names are defined in the [paths] section of your
4184 Path names are defined in the [paths] section of your
4184 configuration file and in ``/etc/mercurial/hgrc``. If run inside a
4185 configuration file and in ``/etc/mercurial/hgrc``. If run inside a
4185 repository, ``.hg/hgrc`` is used, too.
4186 repository, ``.hg/hgrc`` is used, too.
4186
4187
4187 The path names ``default`` and ``default-push`` have a special
4188 The path names ``default`` and ``default-push`` have a special
4188 meaning. When performing a push or pull operation, they are used
4189 meaning. When performing a push or pull operation, they are used
4189 as fallbacks if no location is specified on the command-line.
4190 as fallbacks if no location is specified on the command-line.
4190 When ``default-push`` is set, it will be used for push and
4191 When ``default-push`` is set, it will be used for push and
4191 ``default`` will be used for pull; otherwise ``default`` is used
4192 ``default`` will be used for pull; otherwise ``default`` is used
4192 as the fallback for both. When cloning a repository, the clone
4193 as the fallback for both. When cloning a repository, the clone
4193 source is written as ``default`` in ``.hg/hgrc``. Note that
4194 source is written as ``default`` in ``.hg/hgrc``. Note that
4194 ``default`` and ``default-push`` apply to all inbound (e.g.
4195 ``default`` and ``default-push`` apply to all inbound (e.g.
4195 :hg:`incoming`) and outbound (e.g. :hg:`outgoing`, :hg:`email` and
4196 :hg:`incoming`) and outbound (e.g. :hg:`outgoing`, :hg:`email` and
4196 :hg:`bundle`) operations.
4197 :hg:`bundle`) operations.
4197
4198
4198 See :hg:`help urls` for more information.
4199 See :hg:`help urls` for more information.
4199
4200
4200 Returns 0 on success.
4201 Returns 0 on success.
4201 """
4202 """
4202 if search:
4203 if search:
4203 for name, path in ui.configitems("paths"):
4204 for name, path in ui.configitems("paths"):
4204 if name == search:
4205 if name == search:
4205 ui.status("%s\n" % util.hidepassword(path))
4206 ui.status("%s\n" % util.hidepassword(path))
4206 return
4207 return
4207 if not ui.quiet:
4208 if not ui.quiet:
4208 ui.warn(_("not found!\n"))
4209 ui.warn(_("not found!\n"))
4209 return 1
4210 return 1
4210 else:
4211 else:
4211 for name, path in ui.configitems("paths"):
4212 for name, path in ui.configitems("paths"):
4212 if ui.quiet:
4213 if ui.quiet:
4213 ui.write("%s\n" % name)
4214 ui.write("%s\n" % name)
4214 else:
4215 else:
4215 ui.write("%s = %s\n" % (name, util.hidepassword(path)))
4216 ui.write("%s = %s\n" % (name, util.hidepassword(path)))
4216
4217
4218 @command('^phase',
4219 [('p', 'public', False, _('Set changeset to public')),
4220 ('d', 'draft', False, _('Set changeset to draft')),
4221 ('s', 'secret', False, _('Set changeset to secret')),
4222 ('f', 'force', False, _('allow to move boundary backward')),
4223 ('r', 'rev', [], _('target revision')),
4224 ],
4225 _('[-p|-d|-s] [-f] [-C] [-r] REV'))
4226 def phase(ui, repo, *revs, **opts):
4227 """set or show the current phase name
4228
4229 With no argument, show the phase name of specified revisions.
4230
4231 With on one of `--public`, `--draft` or `--secret`, change the phase value.
4232
4233 Unless -f/--force is specified, :hg:`phase` won't move changeset from a
4234 lower phase to an higher phase. Phase are ordered as follow:
4235
4236 public < draft < secret.
4237 """
4238 # search for a unique phase argument
4239 targetphase = None
4240 for idx, name in enumerate(phasesmod.phasenames):
4241 if opts[name]:
4242 if targetphase is not None:
4243 raise util.Abort('only one phase can be specified')
4244 targetphase = idx
4245
4246 # look for specified revision
4247 revs = list(revs)
4248 revs.extend(opts['rev'])
4249 if not revs:
4250 raise NotImplementedError('working directory phase not implemented '
4251 'yet')
4252 lock = None
4253 if targetphase is None:
4254 # display
4255 for ctx in repo.set('%lr', revs):
4256 ui.write('%i: %s\n' % (ctx.rev(), ctx.phasestr()))
4257 else:
4258 lock = repo.lock()
4259 try:
4260 # set phase
4261 nodes = [ctx.node() for ctx in repo.set('%lr', revs)]
4262 if not nodes:
4263 raise util.Abort(_('empty revision set'))
4264 phasesmod.advanceboundary(repo, targetphase, nodes)
4265 if opts['force']:
4266 phasesmod.retractboundary(repo, targetphase, nodes)
4267 finally:
4268 lock.release()
4269
4217 def postincoming(ui, repo, modheads, optupdate, checkout):
4270 def postincoming(ui, repo, modheads, optupdate, checkout):
4218 if modheads == 0:
4271 if modheads == 0:
4219 return
4272 return
4220 if optupdate:
4273 if optupdate:
4221 try:
4274 try:
4222 return hg.update(repo, checkout)
4275 return hg.update(repo, checkout)
4223 except util.Abort, inst:
4276 except util.Abort, inst:
4224 ui.warn(_("not updating: %s\n" % str(inst)))
4277 ui.warn(_("not updating: %s\n" % str(inst)))
4225 return 0
4278 return 0
4226 if modheads > 1:
4279 if modheads > 1:
4227 currentbranchheads = len(repo.branchheads())
4280 currentbranchheads = len(repo.branchheads())
4228 if currentbranchheads == modheads:
4281 if currentbranchheads == modheads:
4229 ui.status(_("(run 'hg heads' to see heads, 'hg merge' to merge)\n"))
4282 ui.status(_("(run 'hg heads' to see heads, 'hg merge' to merge)\n"))
4230 elif currentbranchheads > 1:
4283 elif currentbranchheads > 1:
4231 ui.status(_("(run 'hg heads .' to see heads, 'hg merge' to merge)\n"))
4284 ui.status(_("(run 'hg heads .' to see heads, 'hg merge' to merge)\n"))
4232 else:
4285 else:
4233 ui.status(_("(run 'hg heads' to see heads)\n"))
4286 ui.status(_("(run 'hg heads' to see heads)\n"))
4234 else:
4287 else:
4235 ui.status(_("(run 'hg update' to get a working copy)\n"))
4288 ui.status(_("(run 'hg update' to get a working copy)\n"))
4236
4289
4237 @command('^pull',
4290 @command('^pull',
4238 [('u', 'update', None,
4291 [('u', 'update', None,
4239 _('update to new branch head if changesets were pulled')),
4292 _('update to new branch head if changesets were pulled')),
4240 ('f', 'force', None, _('run even when remote repository is unrelated')),
4293 ('f', 'force', None, _('run even when remote repository is unrelated')),
4241 ('r', 'rev', [], _('a remote changeset intended to be added'), _('REV')),
4294 ('r', 'rev', [], _('a remote changeset intended to be added'), _('REV')),
4242 ('B', 'bookmark', [], _("bookmark to pull"), _('BOOKMARK')),
4295 ('B', 'bookmark', [], _("bookmark to pull"), _('BOOKMARK')),
4243 ('b', 'branch', [], _('a specific branch you would like to pull'),
4296 ('b', 'branch', [], _('a specific branch you would like to pull'),
4244 _('BRANCH')),
4297 _('BRANCH')),
4245 ] + remoteopts,
4298 ] + remoteopts,
4246 _('[-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]'))
4299 _('[-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]'))
4247 def pull(ui, repo, source="default", **opts):
4300 def pull(ui, repo, source="default", **opts):
4248 """pull changes from the specified source
4301 """pull changes from the specified source
4249
4302
4250 Pull changes from a remote repository to a local one.
4303 Pull changes from a remote repository to a local one.
4251
4304
4252 This finds all changes from the repository at the specified path
4305 This finds all changes from the repository at the specified path
4253 or URL and adds them to a local repository (the current one unless
4306 or URL and adds them to a local repository (the current one unless
4254 -R is specified). By default, this does not update the copy of the
4307 -R is specified). By default, this does not update the copy of the
4255 project in the working directory.
4308 project in the working directory.
4256
4309
4257 Use :hg:`incoming` if you want to see what would have been added
4310 Use :hg:`incoming` if you want to see what would have been added
4258 by a pull at the time you issued this command. If you then decide
4311 by a pull at the time you issued this command. If you then decide
4259 to add those changes to the repository, you should use :hg:`pull
4312 to add those changes to the repository, you should use :hg:`pull
4260 -r X` where ``X`` is the last changeset listed by :hg:`incoming`.
4313 -r X` where ``X`` is the last changeset listed by :hg:`incoming`.
4261
4314
4262 If SOURCE is omitted, the 'default' path will be used.
4315 If SOURCE is omitted, the 'default' path will be used.
4263 See :hg:`help urls` for more information.
4316 See :hg:`help urls` for more information.
4264
4317
4265 Returns 0 on success, 1 if an update had unresolved files.
4318 Returns 0 on success, 1 if an update had unresolved files.
4266 """
4319 """
4267 source, branches = hg.parseurl(ui.expandpath(source), opts.get('branch'))
4320 source, branches = hg.parseurl(ui.expandpath(source), opts.get('branch'))
4268 other = hg.peer(repo, opts, source)
4321 other = hg.peer(repo, opts, source)
4269 ui.status(_('pulling from %s\n') % util.hidepassword(source))
4322 ui.status(_('pulling from %s\n') % util.hidepassword(source))
4270 revs, checkout = hg.addbranchrevs(repo, other, branches, opts.get('rev'))
4323 revs, checkout = hg.addbranchrevs(repo, other, branches, opts.get('rev'))
4271
4324
4272 if opts.get('bookmark'):
4325 if opts.get('bookmark'):
4273 if not revs:
4326 if not revs:
4274 revs = []
4327 revs = []
4275 rb = other.listkeys('bookmarks')
4328 rb = other.listkeys('bookmarks')
4276 for b in opts['bookmark']:
4329 for b in opts['bookmark']:
4277 if b not in rb:
4330 if b not in rb:
4278 raise util.Abort(_('remote bookmark %s not found!') % b)
4331 raise util.Abort(_('remote bookmark %s not found!') % b)
4279 revs.append(rb[b])
4332 revs.append(rb[b])
4280
4333
4281 if revs:
4334 if revs:
4282 try:
4335 try:
4283 revs = [other.lookup(rev) for rev in revs]
4336 revs = [other.lookup(rev) for rev in revs]
4284 except error.CapabilityError:
4337 except error.CapabilityError:
4285 err = _("other repository doesn't support revision lookup, "
4338 err = _("other repository doesn't support revision lookup, "
4286 "so a rev cannot be specified.")
4339 "so a rev cannot be specified.")
4287 raise util.Abort(err)
4340 raise util.Abort(err)
4288
4341
4289 modheads = repo.pull(other, heads=revs, force=opts.get('force'))
4342 modheads = repo.pull(other, heads=revs, force=opts.get('force'))
4290 bookmarks.updatefromremote(ui, repo, other, source)
4343 bookmarks.updatefromremote(ui, repo, other, source)
4291 if checkout:
4344 if checkout:
4292 checkout = str(repo.changelog.rev(other.lookup(checkout)))
4345 checkout = str(repo.changelog.rev(other.lookup(checkout)))
4293 repo._subtoppath = source
4346 repo._subtoppath = source
4294 try:
4347 try:
4295 ret = postincoming(ui, repo, modheads, opts.get('update'), checkout)
4348 ret = postincoming(ui, repo, modheads, opts.get('update'), checkout)
4296
4349
4297 finally:
4350 finally:
4298 del repo._subtoppath
4351 del repo._subtoppath
4299
4352
4300 # update specified bookmarks
4353 # update specified bookmarks
4301 if opts.get('bookmark'):
4354 if opts.get('bookmark'):
4302 for b in opts['bookmark']:
4355 for b in opts['bookmark']:
4303 # explicit pull overrides local bookmark if any
4356 # explicit pull overrides local bookmark if any
4304 ui.status(_("importing bookmark %s\n") % b)
4357 ui.status(_("importing bookmark %s\n") % b)
4305 repo._bookmarks[b] = repo[rb[b]].node()
4358 repo._bookmarks[b] = repo[rb[b]].node()
4306 bookmarks.write(repo)
4359 bookmarks.write(repo)
4307
4360
4308 return ret
4361 return ret
4309
4362
4310 @command('^push',
4363 @command('^push',
4311 [('f', 'force', None, _('force push')),
4364 [('f', 'force', None, _('force push')),
4312 ('r', 'rev', [],
4365 ('r', 'rev', [],
4313 _('a changeset intended to be included in the destination'),
4366 _('a changeset intended to be included in the destination'),
4314 _('REV')),
4367 _('REV')),
4315 ('B', 'bookmark', [], _("bookmark to push"), _('BOOKMARK')),
4368 ('B', 'bookmark', [], _("bookmark to push"), _('BOOKMARK')),
4316 ('b', 'branch', [],
4369 ('b', 'branch', [],
4317 _('a specific branch you would like to push'), _('BRANCH')),
4370 _('a specific branch you would like to push'), _('BRANCH')),
4318 ('', 'new-branch', False, _('allow pushing a new branch')),
4371 ('', 'new-branch', False, _('allow pushing a new branch')),
4319 ] + remoteopts,
4372 ] + remoteopts,
4320 _('[-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]'))
4373 _('[-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]'))
4321 def push(ui, repo, dest=None, **opts):
4374 def push(ui, repo, dest=None, **opts):
4322 """push changes to the specified destination
4375 """push changes to the specified destination
4323
4376
4324 Push changesets from the local repository to the specified
4377 Push changesets from the local repository to the specified
4325 destination.
4378 destination.
4326
4379
4327 This operation is symmetrical to pull: it is identical to a pull
4380 This operation is symmetrical to pull: it is identical to a pull
4328 in the destination repository from the current one.
4381 in the destination repository from the current one.
4329
4382
4330 By default, push will not allow creation of new heads at the
4383 By default, push will not allow creation of new heads at the
4331 destination, since multiple heads would make it unclear which head
4384 destination, since multiple heads would make it unclear which head
4332 to use. In this situation, it is recommended to pull and merge
4385 to use. In this situation, it is recommended to pull and merge
4333 before pushing.
4386 before pushing.
4334
4387
4335 Use --new-branch if you want to allow push to create a new named
4388 Use --new-branch if you want to allow push to create a new named
4336 branch that is not present at the destination. This allows you to
4389 branch that is not present at the destination. This allows you to
4337 only create a new branch without forcing other changes.
4390 only create a new branch without forcing other changes.
4338
4391
4339 Use -f/--force to override the default behavior and push all
4392 Use -f/--force to override the default behavior and push all
4340 changesets on all branches.
4393 changesets on all branches.
4341
4394
4342 If -r/--rev is used, the specified revision and all its ancestors
4395 If -r/--rev is used, the specified revision and all its ancestors
4343 will be pushed to the remote repository.
4396 will be pushed to the remote repository.
4344
4397
4345 Please see :hg:`help urls` for important details about ``ssh://``
4398 Please see :hg:`help urls` for important details about ``ssh://``
4346 URLs. If DESTINATION is omitted, a default path will be used.
4399 URLs. If DESTINATION is omitted, a default path will be used.
4347
4400
4348 Returns 0 if push was successful, 1 if nothing to push.
4401 Returns 0 if push was successful, 1 if nothing to push.
4349 """
4402 """
4350
4403
4351 if opts.get('bookmark'):
4404 if opts.get('bookmark'):
4352 for b in opts['bookmark']:
4405 for b in opts['bookmark']:
4353 # translate -B options to -r so changesets get pushed
4406 # translate -B options to -r so changesets get pushed
4354 if b in repo._bookmarks:
4407 if b in repo._bookmarks:
4355 opts.setdefault('rev', []).append(b)
4408 opts.setdefault('rev', []).append(b)
4356 else:
4409 else:
4357 # if we try to push a deleted bookmark, translate it to null
4410 # if we try to push a deleted bookmark, translate it to null
4358 # this lets simultaneous -r, -b options continue working
4411 # this lets simultaneous -r, -b options continue working
4359 opts.setdefault('rev', []).append("null")
4412 opts.setdefault('rev', []).append("null")
4360
4413
4361 dest = ui.expandpath(dest or 'default-push', dest or 'default')
4414 dest = ui.expandpath(dest or 'default-push', dest or 'default')
4362 dest, branches = hg.parseurl(dest, opts.get('branch'))
4415 dest, branches = hg.parseurl(dest, opts.get('branch'))
4363 ui.status(_('pushing to %s\n') % util.hidepassword(dest))
4416 ui.status(_('pushing to %s\n') % util.hidepassword(dest))
4364 revs, checkout = hg.addbranchrevs(repo, repo, branches, opts.get('rev'))
4417 revs, checkout = hg.addbranchrevs(repo, repo, branches, opts.get('rev'))
4365 other = hg.peer(repo, opts, dest)
4418 other = hg.peer(repo, opts, dest)
4366 if revs:
4419 if revs:
4367 revs = [repo.lookup(rev) for rev in revs]
4420 revs = [repo.lookup(rev) for rev in revs]
4368
4421
4369 repo._subtoppath = dest
4422 repo._subtoppath = dest
4370 try:
4423 try:
4371 # push subrepos depth-first for coherent ordering
4424 # push subrepos depth-first for coherent ordering
4372 c = repo['']
4425 c = repo['']
4373 subs = c.substate # only repos that are committed
4426 subs = c.substate # only repos that are committed
4374 for s in sorted(subs):
4427 for s in sorted(subs):
4375 if not c.sub(s).push(opts):
4428 if not c.sub(s).push(opts):
4376 return False
4429 return False
4377 finally:
4430 finally:
4378 del repo._subtoppath
4431 del repo._subtoppath
4379 result = repo.push(other, opts.get('force'), revs=revs,
4432 result = repo.push(other, opts.get('force'), revs=revs,
4380 newbranch=opts.get('new_branch'))
4433 newbranch=opts.get('new_branch'))
4381
4434
4382 result = (result == 0)
4435 result = (result == 0)
4383
4436
4384 if opts.get('bookmark'):
4437 if opts.get('bookmark'):
4385 rb = other.listkeys('bookmarks')
4438 rb = other.listkeys('bookmarks')
4386 for b in opts['bookmark']:
4439 for b in opts['bookmark']:
4387 # explicit push overrides remote bookmark if any
4440 # explicit push overrides remote bookmark if any
4388 if b in repo._bookmarks:
4441 if b in repo._bookmarks:
4389 ui.status(_("exporting bookmark %s\n") % b)
4442 ui.status(_("exporting bookmark %s\n") % b)
4390 new = repo[b].hex()
4443 new = repo[b].hex()
4391 elif b in rb:
4444 elif b in rb:
4392 ui.status(_("deleting remote bookmark %s\n") % b)
4445 ui.status(_("deleting remote bookmark %s\n") % b)
4393 new = '' # delete
4446 new = '' # delete
4394 else:
4447 else:
4395 ui.warn(_('bookmark %s does not exist on the local '
4448 ui.warn(_('bookmark %s does not exist on the local '
4396 'or remote repository!\n') % b)
4449 'or remote repository!\n') % b)
4397 return 2
4450 return 2
4398 old = rb.get(b, '')
4451 old = rb.get(b, '')
4399 r = other.pushkey('bookmarks', b, old, new)
4452 r = other.pushkey('bookmarks', b, old, new)
4400 if not r:
4453 if not r:
4401 ui.warn(_('updating bookmark %s failed!\n') % b)
4454 ui.warn(_('updating bookmark %s failed!\n') % b)
4402 if not result:
4455 if not result:
4403 result = 2
4456 result = 2
4404
4457
4405 return result
4458 return result
4406
4459
4407 @command('recover', [])
4460 @command('recover', [])
4408 def recover(ui, repo):
4461 def recover(ui, repo):
4409 """roll back an interrupted transaction
4462 """roll back an interrupted transaction
4410
4463
4411 Recover from an interrupted commit or pull.
4464 Recover from an interrupted commit or pull.
4412
4465
4413 This command tries to fix the repository status after an
4466 This command tries to fix the repository status after an
4414 interrupted operation. It should only be necessary when Mercurial
4467 interrupted operation. It should only be necessary when Mercurial
4415 suggests it.
4468 suggests it.
4416
4469
4417 Returns 0 if successful, 1 if nothing to recover or verify fails.
4470 Returns 0 if successful, 1 if nothing to recover or verify fails.
4418 """
4471 """
4419 if repo.recover():
4472 if repo.recover():
4420 return hg.verify(repo)
4473 return hg.verify(repo)
4421 return 1
4474 return 1
4422
4475
4423 @command('^remove|rm',
4476 @command('^remove|rm',
4424 [('A', 'after', None, _('record delete for missing files')),
4477 [('A', 'after', None, _('record delete for missing files')),
4425 ('f', 'force', None,
4478 ('f', 'force', None,
4426 _('remove (and delete) file even if added or modified')),
4479 _('remove (and delete) file even if added or modified')),
4427 ] + walkopts,
4480 ] + walkopts,
4428 _('[OPTION]... FILE...'))
4481 _('[OPTION]... FILE...'))
4429 def remove(ui, repo, *pats, **opts):
4482 def remove(ui, repo, *pats, **opts):
4430 """remove the specified files on the next commit
4483 """remove the specified files on the next commit
4431
4484
4432 Schedule the indicated files for removal from the current branch.
4485 Schedule the indicated files for removal from the current branch.
4433
4486
4434 This command schedules the files to be removed at the next commit.
4487 This command schedules the files to be removed at the next commit.
4435 To undo a remove before that, see :hg:`revert`. To undo added
4488 To undo a remove before that, see :hg:`revert`. To undo added
4436 files, see :hg:`forget`.
4489 files, see :hg:`forget`.
4437
4490
4438 .. container:: verbose
4491 .. container:: verbose
4439
4492
4440 -A/--after can be used to remove only files that have already
4493 -A/--after can be used to remove only files that have already
4441 been deleted, -f/--force can be used to force deletion, and -Af
4494 been deleted, -f/--force can be used to force deletion, and -Af
4442 can be used to remove files from the next revision without
4495 can be used to remove files from the next revision without
4443 deleting them from the working directory.
4496 deleting them from the working directory.
4444
4497
4445 The following table details the behavior of remove for different
4498 The following table details the behavior of remove for different
4446 file states (columns) and option combinations (rows). The file
4499 file states (columns) and option combinations (rows). The file
4447 states are Added [A], Clean [C], Modified [M] and Missing [!]
4500 states are Added [A], Clean [C], Modified [M] and Missing [!]
4448 (as reported by :hg:`status`). The actions are Warn, Remove
4501 (as reported by :hg:`status`). The actions are Warn, Remove
4449 (from branch) and Delete (from disk):
4502 (from branch) and Delete (from disk):
4450
4503
4451 ======= == == == ==
4504 ======= == == == ==
4452 A C M !
4505 A C M !
4453 ======= == == == ==
4506 ======= == == == ==
4454 none W RD W R
4507 none W RD W R
4455 -f R RD RD R
4508 -f R RD RD R
4456 -A W W W R
4509 -A W W W R
4457 -Af R R R R
4510 -Af R R R R
4458 ======= == == == ==
4511 ======= == == == ==
4459
4512
4460 Note that remove never deletes files in Added [A] state from the
4513 Note that remove never deletes files in Added [A] state from the
4461 working directory, not even if option --force is specified.
4514 working directory, not even if option --force is specified.
4462
4515
4463 Returns 0 on success, 1 if any warnings encountered.
4516 Returns 0 on success, 1 if any warnings encountered.
4464 """
4517 """
4465
4518
4466 ret = 0
4519 ret = 0
4467 after, force = opts.get('after'), opts.get('force')
4520 after, force = opts.get('after'), opts.get('force')
4468 if not pats and not after:
4521 if not pats and not after:
4469 raise util.Abort(_('no files specified'))
4522 raise util.Abort(_('no files specified'))
4470
4523
4471 m = scmutil.match(repo[None], pats, opts)
4524 m = scmutil.match(repo[None], pats, opts)
4472 s = repo.status(match=m, clean=True)
4525 s = repo.status(match=m, clean=True)
4473 modified, added, deleted, clean = s[0], s[1], s[3], s[6]
4526 modified, added, deleted, clean = s[0], s[1], s[3], s[6]
4474
4527
4475 for f in m.files():
4528 for f in m.files():
4476 if f not in repo.dirstate and not os.path.isdir(m.rel(f)):
4529 if f not in repo.dirstate and not os.path.isdir(m.rel(f)):
4477 if os.path.exists(m.rel(f)):
4530 if os.path.exists(m.rel(f)):
4478 ui.warn(_('not removing %s: file is untracked\n') % m.rel(f))
4531 ui.warn(_('not removing %s: file is untracked\n') % m.rel(f))
4479 ret = 1
4532 ret = 1
4480
4533
4481 if force:
4534 if force:
4482 list = modified + deleted + clean + added
4535 list = modified + deleted + clean + added
4483 elif after:
4536 elif after:
4484 list = deleted
4537 list = deleted
4485 for f in modified + added + clean:
4538 for f in modified + added + clean:
4486 ui.warn(_('not removing %s: file still exists (use -f'
4539 ui.warn(_('not removing %s: file still exists (use -f'
4487 ' to force removal)\n') % m.rel(f))
4540 ' to force removal)\n') % m.rel(f))
4488 ret = 1
4541 ret = 1
4489 else:
4542 else:
4490 list = deleted + clean
4543 list = deleted + clean
4491 for f in modified:
4544 for f in modified:
4492 ui.warn(_('not removing %s: file is modified (use -f'
4545 ui.warn(_('not removing %s: file is modified (use -f'
4493 ' to force removal)\n') % m.rel(f))
4546 ' to force removal)\n') % m.rel(f))
4494 ret = 1
4547 ret = 1
4495 for f in added:
4548 for f in added:
4496 ui.warn(_('not removing %s: file has been marked for add'
4549 ui.warn(_('not removing %s: file has been marked for add'
4497 ' (use forget to undo)\n') % m.rel(f))
4550 ' (use forget to undo)\n') % m.rel(f))
4498 ret = 1
4551 ret = 1
4499
4552
4500 for f in sorted(list):
4553 for f in sorted(list):
4501 if ui.verbose or not m.exact(f):
4554 if ui.verbose or not m.exact(f):
4502 ui.status(_('removing %s\n') % m.rel(f))
4555 ui.status(_('removing %s\n') % m.rel(f))
4503
4556
4504 wlock = repo.wlock()
4557 wlock = repo.wlock()
4505 try:
4558 try:
4506 if not after:
4559 if not after:
4507 for f in list:
4560 for f in list:
4508 if f in added:
4561 if f in added:
4509 continue # we never unlink added files on remove
4562 continue # we never unlink added files on remove
4510 try:
4563 try:
4511 util.unlinkpath(repo.wjoin(f))
4564 util.unlinkpath(repo.wjoin(f))
4512 except OSError, inst:
4565 except OSError, inst:
4513 if inst.errno != errno.ENOENT:
4566 if inst.errno != errno.ENOENT:
4514 raise
4567 raise
4515 repo[None].forget(list)
4568 repo[None].forget(list)
4516 finally:
4569 finally:
4517 wlock.release()
4570 wlock.release()
4518
4571
4519 return ret
4572 return ret
4520
4573
4521 @command('rename|move|mv',
4574 @command('rename|move|mv',
4522 [('A', 'after', None, _('record a rename that has already occurred')),
4575 [('A', 'after', None, _('record a rename that has already occurred')),
4523 ('f', 'force', None, _('forcibly copy over an existing managed file')),
4576 ('f', 'force', None, _('forcibly copy over an existing managed file')),
4524 ] + walkopts + dryrunopts,
4577 ] + walkopts + dryrunopts,
4525 _('[OPTION]... SOURCE... DEST'))
4578 _('[OPTION]... SOURCE... DEST'))
4526 def rename(ui, repo, *pats, **opts):
4579 def rename(ui, repo, *pats, **opts):
4527 """rename files; equivalent of copy + remove
4580 """rename files; equivalent of copy + remove
4528
4581
4529 Mark dest as copies of sources; mark sources for deletion. If dest
4582 Mark dest as copies of sources; mark sources for deletion. If dest
4530 is a directory, copies are put in that directory. If dest is a
4583 is a directory, copies are put in that directory. If dest is a
4531 file, there can only be one source.
4584 file, there can only be one source.
4532
4585
4533 By default, this command copies the contents of files as they
4586 By default, this command copies the contents of files as they
4534 exist in the working directory. If invoked with -A/--after, the
4587 exist in the working directory. If invoked with -A/--after, the
4535 operation is recorded, but no copying is performed.
4588 operation is recorded, but no copying is performed.
4536
4589
4537 This command takes effect at the next commit. To undo a rename
4590 This command takes effect at the next commit. To undo a rename
4538 before that, see :hg:`revert`.
4591 before that, see :hg:`revert`.
4539
4592
4540 Returns 0 on success, 1 if errors are encountered.
4593 Returns 0 on success, 1 if errors are encountered.
4541 """
4594 """
4542 wlock = repo.wlock(False)
4595 wlock = repo.wlock(False)
4543 try:
4596 try:
4544 return cmdutil.copy(ui, repo, pats, opts, rename=True)
4597 return cmdutil.copy(ui, repo, pats, opts, rename=True)
4545 finally:
4598 finally:
4546 wlock.release()
4599 wlock.release()
4547
4600
4548 @command('resolve',
4601 @command('resolve',
4549 [('a', 'all', None, _('select all unresolved files')),
4602 [('a', 'all', None, _('select all unresolved files')),
4550 ('l', 'list', None, _('list state of files needing merge')),
4603 ('l', 'list', None, _('list state of files needing merge')),
4551 ('m', 'mark', None, _('mark files as resolved')),
4604 ('m', 'mark', None, _('mark files as resolved')),
4552 ('u', 'unmark', None, _('mark files as unresolved')),
4605 ('u', 'unmark', None, _('mark files as unresolved')),
4553 ('n', 'no-status', None, _('hide status prefix'))]
4606 ('n', 'no-status', None, _('hide status prefix'))]
4554 + mergetoolopts + walkopts,
4607 + mergetoolopts + walkopts,
4555 _('[OPTION]... [FILE]...'))
4608 _('[OPTION]... [FILE]...'))
4556 def resolve(ui, repo, *pats, **opts):
4609 def resolve(ui, repo, *pats, **opts):
4557 """redo merges or set/view the merge status of files
4610 """redo merges or set/view the merge status of files
4558
4611
4559 Merges with unresolved conflicts are often the result of
4612 Merges with unresolved conflicts are often the result of
4560 non-interactive merging using the ``internal:merge`` configuration
4613 non-interactive merging using the ``internal:merge`` configuration
4561 setting, or a command-line merge tool like ``diff3``. The resolve
4614 setting, or a command-line merge tool like ``diff3``. The resolve
4562 command is used to manage the files involved in a merge, after
4615 command is used to manage the files involved in a merge, after
4563 :hg:`merge` has been run, and before :hg:`commit` is run (i.e. the
4616 :hg:`merge` has been run, and before :hg:`commit` is run (i.e. the
4564 working directory must have two parents).
4617 working directory must have two parents).
4565
4618
4566 The resolve command can be used in the following ways:
4619 The resolve command can be used in the following ways:
4567
4620
4568 - :hg:`resolve [--tool TOOL] FILE...`: attempt to re-merge the specified
4621 - :hg:`resolve [--tool TOOL] FILE...`: attempt to re-merge the specified
4569 files, discarding any previous merge attempts. Re-merging is not
4622 files, discarding any previous merge attempts. Re-merging is not
4570 performed for files already marked as resolved. Use ``--all/-a``
4623 performed for files already marked as resolved. Use ``--all/-a``
4571 to select all unresolved files. ``--tool`` can be used to specify
4624 to select all unresolved files. ``--tool`` can be used to specify
4572 the merge tool used for the given files. It overrides the HGMERGE
4625 the merge tool used for the given files. It overrides the HGMERGE
4573 environment variable and your configuration files. Previous file
4626 environment variable and your configuration files. Previous file
4574 contents are saved with a ``.orig`` suffix.
4627 contents are saved with a ``.orig`` suffix.
4575
4628
4576 - :hg:`resolve -m [FILE]`: mark a file as having been resolved
4629 - :hg:`resolve -m [FILE]`: mark a file as having been resolved
4577 (e.g. after having manually fixed-up the files). The default is
4630 (e.g. after having manually fixed-up the files). The default is
4578 to mark all unresolved files.
4631 to mark all unresolved files.
4579
4632
4580 - :hg:`resolve -u [FILE]...`: mark a file as unresolved. The
4633 - :hg:`resolve -u [FILE]...`: mark a file as unresolved. The
4581 default is to mark all resolved files.
4634 default is to mark all resolved files.
4582
4635
4583 - :hg:`resolve -l`: list files which had or still have conflicts.
4636 - :hg:`resolve -l`: list files which had or still have conflicts.
4584 In the printed list, ``U`` = unresolved and ``R`` = resolved.
4637 In the printed list, ``U`` = unresolved and ``R`` = resolved.
4585
4638
4586 Note that Mercurial will not let you commit files with unresolved
4639 Note that Mercurial will not let you commit files with unresolved
4587 merge conflicts. You must use :hg:`resolve -m ...` before you can
4640 merge conflicts. You must use :hg:`resolve -m ...` before you can
4588 commit after a conflicting merge.
4641 commit after a conflicting merge.
4589
4642
4590 Returns 0 on success, 1 if any files fail a resolve attempt.
4643 Returns 0 on success, 1 if any files fail a resolve attempt.
4591 """
4644 """
4592
4645
4593 all, mark, unmark, show, nostatus = \
4646 all, mark, unmark, show, nostatus = \
4594 [opts.get(o) for o in 'all mark unmark list no_status'.split()]
4647 [opts.get(o) for o in 'all mark unmark list no_status'.split()]
4595
4648
4596 if (show and (mark or unmark)) or (mark and unmark):
4649 if (show and (mark or unmark)) or (mark and unmark):
4597 raise util.Abort(_("too many options specified"))
4650 raise util.Abort(_("too many options specified"))
4598 if pats and all:
4651 if pats and all:
4599 raise util.Abort(_("can't specify --all and patterns"))
4652 raise util.Abort(_("can't specify --all and patterns"))
4600 if not (all or pats or show or mark or unmark):
4653 if not (all or pats or show or mark or unmark):
4601 raise util.Abort(_('no files or directories specified; '
4654 raise util.Abort(_('no files or directories specified; '
4602 'use --all to remerge all files'))
4655 'use --all to remerge all files'))
4603
4656
4604 ms = mergemod.mergestate(repo)
4657 ms = mergemod.mergestate(repo)
4605 m = scmutil.match(repo[None], pats, opts)
4658 m = scmutil.match(repo[None], pats, opts)
4606 ret = 0
4659 ret = 0
4607
4660
4608 for f in ms:
4661 for f in ms:
4609 if m(f):
4662 if m(f):
4610 if show:
4663 if show:
4611 if nostatus:
4664 if nostatus:
4612 ui.write("%s\n" % f)
4665 ui.write("%s\n" % f)
4613 else:
4666 else:
4614 ui.write("%s %s\n" % (ms[f].upper(), f),
4667 ui.write("%s %s\n" % (ms[f].upper(), f),
4615 label='resolve.' +
4668 label='resolve.' +
4616 {'u': 'unresolved', 'r': 'resolved'}[ms[f]])
4669 {'u': 'unresolved', 'r': 'resolved'}[ms[f]])
4617 elif mark:
4670 elif mark:
4618 ms.mark(f, "r")
4671 ms.mark(f, "r")
4619 elif unmark:
4672 elif unmark:
4620 ms.mark(f, "u")
4673 ms.mark(f, "u")
4621 else:
4674 else:
4622 wctx = repo[None]
4675 wctx = repo[None]
4623 mctx = wctx.parents()[-1]
4676 mctx = wctx.parents()[-1]
4624
4677
4625 # backup pre-resolve (merge uses .orig for its own purposes)
4678 # backup pre-resolve (merge uses .orig for its own purposes)
4626 a = repo.wjoin(f)
4679 a = repo.wjoin(f)
4627 util.copyfile(a, a + ".resolve")
4680 util.copyfile(a, a + ".resolve")
4628
4681
4629 try:
4682 try:
4630 # resolve file
4683 # resolve file
4631 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
4684 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
4632 if ms.resolve(f, wctx, mctx):
4685 if ms.resolve(f, wctx, mctx):
4633 ret = 1
4686 ret = 1
4634 finally:
4687 finally:
4635 ui.setconfig('ui', 'forcemerge', '')
4688 ui.setconfig('ui', 'forcemerge', '')
4636
4689
4637 # replace filemerge's .orig file with our resolve file
4690 # replace filemerge's .orig file with our resolve file
4638 util.rename(a + ".resolve", a + ".orig")
4691 util.rename(a + ".resolve", a + ".orig")
4639
4692
4640 ms.commit()
4693 ms.commit()
4641 return ret
4694 return ret
4642
4695
4643 @command('revert',
4696 @command('revert',
4644 [('a', 'all', None, _('revert all changes when no arguments given')),
4697 [('a', 'all', None, _('revert all changes when no arguments given')),
4645 ('d', 'date', '', _('tipmost revision matching date'), _('DATE')),
4698 ('d', 'date', '', _('tipmost revision matching date'), _('DATE')),
4646 ('r', 'rev', '', _('revert to the specified revision'), _('REV')),
4699 ('r', 'rev', '', _('revert to the specified revision'), _('REV')),
4647 ('C', 'no-backup', None, _('do not save backup copies of files')),
4700 ('C', 'no-backup', None, _('do not save backup copies of files')),
4648 ] + walkopts + dryrunopts,
4701 ] + walkopts + dryrunopts,
4649 _('[OPTION]... [-r REV] [NAME]...'))
4702 _('[OPTION]... [-r REV] [NAME]...'))
4650 def revert(ui, repo, *pats, **opts):
4703 def revert(ui, repo, *pats, **opts):
4651 """restore files to their checkout state
4704 """restore files to their checkout state
4652
4705
4653 .. note::
4706 .. note::
4654 To check out earlier revisions, you should use :hg:`update REV`.
4707 To check out earlier revisions, you should use :hg:`update REV`.
4655 To cancel a merge (and lose your changes), use :hg:`update --clean .`.
4708 To cancel a merge (and lose your changes), use :hg:`update --clean .`.
4656
4709
4657 With no revision specified, revert the specified files or directories
4710 With no revision specified, revert the specified files or directories
4658 to the contents they had in the parent of the working directory.
4711 to the contents they had in the parent of the working directory.
4659 This restores the contents of files to an unmodified
4712 This restores the contents of files to an unmodified
4660 state and unschedules adds, removes, copies, and renames. If the
4713 state and unschedules adds, removes, copies, and renames. If the
4661 working directory has two parents, you must explicitly specify a
4714 working directory has two parents, you must explicitly specify a
4662 revision.
4715 revision.
4663
4716
4664 Using the -r/--rev or -d/--date options, revert the given files or
4717 Using the -r/--rev or -d/--date options, revert the given files or
4665 directories to their states as of a specific revision. Because
4718 directories to their states as of a specific revision. Because
4666 revert does not change the working directory parents, this will
4719 revert does not change the working directory parents, this will
4667 cause these files to appear modified. This can be helpful to "back
4720 cause these files to appear modified. This can be helpful to "back
4668 out" some or all of an earlier change. See :hg:`backout` for a
4721 out" some or all of an earlier change. See :hg:`backout` for a
4669 related method.
4722 related method.
4670
4723
4671 Modified files are saved with a .orig suffix before reverting.
4724 Modified files are saved with a .orig suffix before reverting.
4672 To disable these backups, use --no-backup.
4725 To disable these backups, use --no-backup.
4673
4726
4674 See :hg:`help dates` for a list of formats valid for -d/--date.
4727 See :hg:`help dates` for a list of formats valid for -d/--date.
4675
4728
4676 Returns 0 on success.
4729 Returns 0 on success.
4677 """
4730 """
4678
4731
4679 if opts.get("date"):
4732 if opts.get("date"):
4680 if opts.get("rev"):
4733 if opts.get("rev"):
4681 raise util.Abort(_("you can't specify a revision and a date"))
4734 raise util.Abort(_("you can't specify a revision and a date"))
4682 opts["rev"] = cmdutil.finddate(ui, repo, opts["date"])
4735 opts["rev"] = cmdutil.finddate(ui, repo, opts["date"])
4683
4736
4684 parent, p2 = repo.dirstate.parents()
4737 parent, p2 = repo.dirstate.parents()
4685 if not opts.get('rev') and p2 != nullid:
4738 if not opts.get('rev') and p2 != nullid:
4686 # revert after merge is a trap for new users (issue2915)
4739 # revert after merge is a trap for new users (issue2915)
4687 raise util.Abort(_('uncommitted merge with no revision specified'),
4740 raise util.Abort(_('uncommitted merge with no revision specified'),
4688 hint=_('use "hg update" or see "hg help revert"'))
4741 hint=_('use "hg update" or see "hg help revert"'))
4689
4742
4690 ctx = scmutil.revsingle(repo, opts.get('rev'))
4743 ctx = scmutil.revsingle(repo, opts.get('rev'))
4691 node = ctx.node()
4744 node = ctx.node()
4692
4745
4693 if not pats and not opts.get('all'):
4746 if not pats and not opts.get('all'):
4694 msg = _("no files or directories specified")
4747 msg = _("no files or directories specified")
4695 if p2 != nullid:
4748 if p2 != nullid:
4696 hint = _("uncommitted merge, use --all to discard all changes,"
4749 hint = _("uncommitted merge, use --all to discard all changes,"
4697 " or 'hg update -C .' to abort the merge")
4750 " or 'hg update -C .' to abort the merge")
4698 raise util.Abort(msg, hint=hint)
4751 raise util.Abort(msg, hint=hint)
4699 dirty = util.any(repo.status())
4752 dirty = util.any(repo.status())
4700 if node != parent:
4753 if node != parent:
4701 if dirty:
4754 if dirty:
4702 hint = _("uncommitted changes, use --all to discard all"
4755 hint = _("uncommitted changes, use --all to discard all"
4703 " changes, or 'hg update %s' to update") % ctx.rev()
4756 " changes, or 'hg update %s' to update") % ctx.rev()
4704 else:
4757 else:
4705 hint = _("use --all to revert all files,"
4758 hint = _("use --all to revert all files,"
4706 " or 'hg update %s' to update") % ctx.rev()
4759 " or 'hg update %s' to update") % ctx.rev()
4707 elif dirty:
4760 elif dirty:
4708 hint = _("uncommitted changes, use --all to discard all changes")
4761 hint = _("uncommitted changes, use --all to discard all changes")
4709 else:
4762 else:
4710 hint = _("use --all to revert all files")
4763 hint = _("use --all to revert all files")
4711 raise util.Abort(msg, hint=hint)
4764 raise util.Abort(msg, hint=hint)
4712
4765
4713 mf = ctx.manifest()
4766 mf = ctx.manifest()
4714 if node == parent:
4767 if node == parent:
4715 pmf = mf
4768 pmf = mf
4716 else:
4769 else:
4717 pmf = None
4770 pmf = None
4718
4771
4719 # need all matching names in dirstate and manifest of target rev,
4772 # need all matching names in dirstate and manifest of target rev,
4720 # so have to walk both. do not print errors if files exist in one
4773 # so have to walk both. do not print errors if files exist in one
4721 # but not other.
4774 # but not other.
4722
4775
4723 names = {}
4776 names = {}
4724
4777
4725 wlock = repo.wlock()
4778 wlock = repo.wlock()
4726 try:
4779 try:
4727 # walk dirstate.
4780 # walk dirstate.
4728
4781
4729 m = scmutil.match(repo[None], pats, opts)
4782 m = scmutil.match(repo[None], pats, opts)
4730 m.bad = lambda x, y: False
4783 m.bad = lambda x, y: False
4731 for abs in repo.walk(m):
4784 for abs in repo.walk(m):
4732 names[abs] = m.rel(abs), m.exact(abs)
4785 names[abs] = m.rel(abs), m.exact(abs)
4733
4786
4734 # walk target manifest.
4787 # walk target manifest.
4735
4788
4736 def badfn(path, msg):
4789 def badfn(path, msg):
4737 if path in names:
4790 if path in names:
4738 return
4791 return
4739 if path in repo[node].substate:
4792 if path in repo[node].substate:
4740 ui.warn("%s: %s\n" % (m.rel(path),
4793 ui.warn("%s: %s\n" % (m.rel(path),
4741 'reverting subrepos is unsupported'))
4794 'reverting subrepos is unsupported'))
4742 return
4795 return
4743 path_ = path + '/'
4796 path_ = path + '/'
4744 for f in names:
4797 for f in names:
4745 if f.startswith(path_):
4798 if f.startswith(path_):
4746 return
4799 return
4747 ui.warn("%s: %s\n" % (m.rel(path), msg))
4800 ui.warn("%s: %s\n" % (m.rel(path), msg))
4748
4801
4749 m = scmutil.match(repo[node], pats, opts)
4802 m = scmutil.match(repo[node], pats, opts)
4750 m.bad = badfn
4803 m.bad = badfn
4751 for abs in repo[node].walk(m):
4804 for abs in repo[node].walk(m):
4752 if abs not in names:
4805 if abs not in names:
4753 names[abs] = m.rel(abs), m.exact(abs)
4806 names[abs] = m.rel(abs), m.exact(abs)
4754
4807
4755 m = scmutil.matchfiles(repo, names)
4808 m = scmutil.matchfiles(repo, names)
4756 changes = repo.status(match=m)[:4]
4809 changes = repo.status(match=m)[:4]
4757 modified, added, removed, deleted = map(set, changes)
4810 modified, added, removed, deleted = map(set, changes)
4758
4811
4759 # if f is a rename, also revert the source
4812 # if f is a rename, also revert the source
4760 cwd = repo.getcwd()
4813 cwd = repo.getcwd()
4761 for f in added:
4814 for f in added:
4762 src = repo.dirstate.copied(f)
4815 src = repo.dirstate.copied(f)
4763 if src and src not in names and repo.dirstate[src] == 'r':
4816 if src and src not in names and repo.dirstate[src] == 'r':
4764 removed.add(src)
4817 removed.add(src)
4765 names[src] = (repo.pathto(src, cwd), True)
4818 names[src] = (repo.pathto(src, cwd), True)
4766
4819
4767 def removeforget(abs):
4820 def removeforget(abs):
4768 if repo.dirstate[abs] == 'a':
4821 if repo.dirstate[abs] == 'a':
4769 return _('forgetting %s\n')
4822 return _('forgetting %s\n')
4770 return _('removing %s\n')
4823 return _('removing %s\n')
4771
4824
4772 revert = ([], _('reverting %s\n'))
4825 revert = ([], _('reverting %s\n'))
4773 add = ([], _('adding %s\n'))
4826 add = ([], _('adding %s\n'))
4774 remove = ([], removeforget)
4827 remove = ([], removeforget)
4775 undelete = ([], _('undeleting %s\n'))
4828 undelete = ([], _('undeleting %s\n'))
4776
4829
4777 disptable = (
4830 disptable = (
4778 # dispatch table:
4831 # dispatch table:
4779 # file state
4832 # file state
4780 # action if in target manifest
4833 # action if in target manifest
4781 # action if not in target manifest
4834 # action if not in target manifest
4782 # make backup if in target manifest
4835 # make backup if in target manifest
4783 # make backup if not in target manifest
4836 # make backup if not in target manifest
4784 (modified, revert, remove, True, True),
4837 (modified, revert, remove, True, True),
4785 (added, revert, remove, True, False),
4838 (added, revert, remove, True, False),
4786 (removed, undelete, None, False, False),
4839 (removed, undelete, None, False, False),
4787 (deleted, revert, remove, False, False),
4840 (deleted, revert, remove, False, False),
4788 )
4841 )
4789
4842
4790 for abs, (rel, exact) in sorted(names.items()):
4843 for abs, (rel, exact) in sorted(names.items()):
4791 mfentry = mf.get(abs)
4844 mfentry = mf.get(abs)
4792 target = repo.wjoin(abs)
4845 target = repo.wjoin(abs)
4793 def handle(xlist, dobackup):
4846 def handle(xlist, dobackup):
4794 xlist[0].append(abs)
4847 xlist[0].append(abs)
4795 if (dobackup and not opts.get('no_backup') and
4848 if (dobackup and not opts.get('no_backup') and
4796 os.path.lexists(target)):
4849 os.path.lexists(target)):
4797 bakname = "%s.orig" % rel
4850 bakname = "%s.orig" % rel
4798 ui.note(_('saving current version of %s as %s\n') %
4851 ui.note(_('saving current version of %s as %s\n') %
4799 (rel, bakname))
4852 (rel, bakname))
4800 if not opts.get('dry_run'):
4853 if not opts.get('dry_run'):
4801 util.rename(target, bakname)
4854 util.rename(target, bakname)
4802 if ui.verbose or not exact:
4855 if ui.verbose or not exact:
4803 msg = xlist[1]
4856 msg = xlist[1]
4804 if not isinstance(msg, basestring):
4857 if not isinstance(msg, basestring):
4805 msg = msg(abs)
4858 msg = msg(abs)
4806 ui.status(msg % rel)
4859 ui.status(msg % rel)
4807 for table, hitlist, misslist, backuphit, backupmiss in disptable:
4860 for table, hitlist, misslist, backuphit, backupmiss in disptable:
4808 if abs not in table:
4861 if abs not in table:
4809 continue
4862 continue
4810 # file has changed in dirstate
4863 # file has changed in dirstate
4811 if mfentry:
4864 if mfentry:
4812 handle(hitlist, backuphit)
4865 handle(hitlist, backuphit)
4813 elif misslist is not None:
4866 elif misslist is not None:
4814 handle(misslist, backupmiss)
4867 handle(misslist, backupmiss)
4815 break
4868 break
4816 else:
4869 else:
4817 if abs not in repo.dirstate:
4870 if abs not in repo.dirstate:
4818 if mfentry:
4871 if mfentry:
4819 handle(add, True)
4872 handle(add, True)
4820 elif exact:
4873 elif exact:
4821 ui.warn(_('file not managed: %s\n') % rel)
4874 ui.warn(_('file not managed: %s\n') % rel)
4822 continue
4875 continue
4823 # file has not changed in dirstate
4876 # file has not changed in dirstate
4824 if node == parent:
4877 if node == parent:
4825 if exact:
4878 if exact:
4826 ui.warn(_('no changes needed to %s\n') % rel)
4879 ui.warn(_('no changes needed to %s\n') % rel)
4827 continue
4880 continue
4828 if pmf is None:
4881 if pmf is None:
4829 # only need parent manifest in this unlikely case,
4882 # only need parent manifest in this unlikely case,
4830 # so do not read by default
4883 # so do not read by default
4831 pmf = repo[parent].manifest()
4884 pmf = repo[parent].manifest()
4832 if abs in pmf and mfentry:
4885 if abs in pmf and mfentry:
4833 # if version of file is same in parent and target
4886 # if version of file is same in parent and target
4834 # manifests, do nothing
4887 # manifests, do nothing
4835 if (pmf[abs] != mfentry or
4888 if (pmf[abs] != mfentry or
4836 pmf.flags(abs) != mf.flags(abs)):
4889 pmf.flags(abs) != mf.flags(abs)):
4837 handle(revert, False)
4890 handle(revert, False)
4838 else:
4891 else:
4839 handle(remove, False)
4892 handle(remove, False)
4840
4893
4841 if not opts.get('dry_run'):
4894 if not opts.get('dry_run'):
4842 def checkout(f):
4895 def checkout(f):
4843 fc = ctx[f]
4896 fc = ctx[f]
4844 repo.wwrite(f, fc.data(), fc.flags())
4897 repo.wwrite(f, fc.data(), fc.flags())
4845
4898
4846 audit_path = scmutil.pathauditor(repo.root)
4899 audit_path = scmutil.pathauditor(repo.root)
4847 for f in remove[0]:
4900 for f in remove[0]:
4848 if repo.dirstate[f] == 'a':
4901 if repo.dirstate[f] == 'a':
4849 repo.dirstate.drop(f)
4902 repo.dirstate.drop(f)
4850 continue
4903 continue
4851 audit_path(f)
4904 audit_path(f)
4852 try:
4905 try:
4853 util.unlinkpath(repo.wjoin(f))
4906 util.unlinkpath(repo.wjoin(f))
4854 except OSError:
4907 except OSError:
4855 pass
4908 pass
4856 repo.dirstate.remove(f)
4909 repo.dirstate.remove(f)
4857
4910
4858 normal = None
4911 normal = None
4859 if node == parent:
4912 if node == parent:
4860 # We're reverting to our parent. If possible, we'd like status
4913 # We're reverting to our parent. If possible, we'd like status
4861 # to report the file as clean. We have to use normallookup for
4914 # to report the file as clean. We have to use normallookup for
4862 # merges to avoid losing information about merged/dirty files.
4915 # merges to avoid losing information about merged/dirty files.
4863 if p2 != nullid:
4916 if p2 != nullid:
4864 normal = repo.dirstate.normallookup
4917 normal = repo.dirstate.normallookup
4865 else:
4918 else:
4866 normal = repo.dirstate.normal
4919 normal = repo.dirstate.normal
4867 for f in revert[0]:
4920 for f in revert[0]:
4868 checkout(f)
4921 checkout(f)
4869 if normal:
4922 if normal:
4870 normal(f)
4923 normal(f)
4871
4924
4872 for f in add[0]:
4925 for f in add[0]:
4873 checkout(f)
4926 checkout(f)
4874 repo.dirstate.add(f)
4927 repo.dirstate.add(f)
4875
4928
4876 normal = repo.dirstate.normallookup
4929 normal = repo.dirstate.normallookup
4877 if node == parent and p2 == nullid:
4930 if node == parent and p2 == nullid:
4878 normal = repo.dirstate.normal
4931 normal = repo.dirstate.normal
4879 for f in undelete[0]:
4932 for f in undelete[0]:
4880 checkout(f)
4933 checkout(f)
4881 normal(f)
4934 normal(f)
4882
4935
4883 finally:
4936 finally:
4884 wlock.release()
4937 wlock.release()
4885
4938
4886 @command('rollback', dryrunopts +
4939 @command('rollback', dryrunopts +
4887 [('f', 'force', False, _('ignore safety measures'))])
4940 [('f', 'force', False, _('ignore safety measures'))])
4888 def rollback(ui, repo, **opts):
4941 def rollback(ui, repo, **opts):
4889 """roll back the last transaction (dangerous)
4942 """roll back the last transaction (dangerous)
4890
4943
4891 This command should be used with care. There is only one level of
4944 This command should be used with care. There is only one level of
4892 rollback, and there is no way to undo a rollback. It will also
4945 rollback, and there is no way to undo a rollback. It will also
4893 restore the dirstate at the time of the last transaction, losing
4946 restore the dirstate at the time of the last transaction, losing
4894 any dirstate changes since that time. This command does not alter
4947 any dirstate changes since that time. This command does not alter
4895 the working directory.
4948 the working directory.
4896
4949
4897 Transactions are used to encapsulate the effects of all commands
4950 Transactions are used to encapsulate the effects of all commands
4898 that create new changesets or propagate existing changesets into a
4951 that create new changesets or propagate existing changesets into a
4899 repository. For example, the following commands are transactional,
4952 repository. For example, the following commands are transactional,
4900 and their effects can be rolled back:
4953 and their effects can be rolled back:
4901
4954
4902 - commit
4955 - commit
4903 - import
4956 - import
4904 - pull
4957 - pull
4905 - push (with this repository as the destination)
4958 - push (with this repository as the destination)
4906 - unbundle
4959 - unbundle
4907
4960
4908 To avoid permanent data loss, rollback will refuse to rollback a
4961 To avoid permanent data loss, rollback will refuse to rollback a
4909 commit transaction if it isn't checked out. Use --force to
4962 commit transaction if it isn't checked out. Use --force to
4910 override this protection.
4963 override this protection.
4911
4964
4912 This command is not intended for use on public repositories. Once
4965 This command is not intended for use on public repositories. Once
4913 changes are visible for pull by other users, rolling a transaction
4966 changes are visible for pull by other users, rolling a transaction
4914 back locally is ineffective (someone else may already have pulled
4967 back locally is ineffective (someone else may already have pulled
4915 the changes). Furthermore, a race is possible with readers of the
4968 the changes). Furthermore, a race is possible with readers of the
4916 repository; for example an in-progress pull from the repository
4969 repository; for example an in-progress pull from the repository
4917 may fail if a rollback is performed.
4970 may fail if a rollback is performed.
4918
4971
4919 Returns 0 on success, 1 if no rollback data is available.
4972 Returns 0 on success, 1 if no rollback data is available.
4920 """
4973 """
4921 return repo.rollback(dryrun=opts.get('dry_run'),
4974 return repo.rollback(dryrun=opts.get('dry_run'),
4922 force=opts.get('force'))
4975 force=opts.get('force'))
4923
4976
4924 @command('root', [])
4977 @command('root', [])
4925 def root(ui, repo):
4978 def root(ui, repo):
4926 """print the root (top) of the current working directory
4979 """print the root (top) of the current working directory
4927
4980
4928 Print the root directory of the current repository.
4981 Print the root directory of the current repository.
4929
4982
4930 Returns 0 on success.
4983 Returns 0 on success.
4931 """
4984 """
4932 ui.write(repo.root + "\n")
4985 ui.write(repo.root + "\n")
4933
4986
4934 @command('^serve',
4987 @command('^serve',
4935 [('A', 'accesslog', '', _('name of access log file to write to'),
4988 [('A', 'accesslog', '', _('name of access log file to write to'),
4936 _('FILE')),
4989 _('FILE')),
4937 ('d', 'daemon', None, _('run server in background')),
4990 ('d', 'daemon', None, _('run server in background')),
4938 ('', 'daemon-pipefds', '', _('used internally by daemon mode'), _('NUM')),
4991 ('', 'daemon-pipefds', '', _('used internally by daemon mode'), _('NUM')),
4939 ('E', 'errorlog', '', _('name of error log file to write to'), _('FILE')),
4992 ('E', 'errorlog', '', _('name of error log file to write to'), _('FILE')),
4940 # use string type, then we can check if something was passed
4993 # use string type, then we can check if something was passed
4941 ('p', 'port', '', _('port to listen on (default: 8000)'), _('PORT')),
4994 ('p', 'port', '', _('port to listen on (default: 8000)'), _('PORT')),
4942 ('a', 'address', '', _('address to listen on (default: all interfaces)'),
4995 ('a', 'address', '', _('address to listen on (default: all interfaces)'),
4943 _('ADDR')),
4996 _('ADDR')),
4944 ('', 'prefix', '', _('prefix path to serve from (default: server root)'),
4997 ('', 'prefix', '', _('prefix path to serve from (default: server root)'),
4945 _('PREFIX')),
4998 _('PREFIX')),
4946 ('n', 'name', '',
4999 ('n', 'name', '',
4947 _('name to show in web pages (default: working directory)'), _('NAME')),
5000 _('name to show in web pages (default: working directory)'), _('NAME')),
4948 ('', 'web-conf', '',
5001 ('', 'web-conf', '',
4949 _('name of the hgweb config file (see "hg help hgweb")'), _('FILE')),
5002 _('name of the hgweb config file (see "hg help hgweb")'), _('FILE')),
4950 ('', 'webdir-conf', '', _('name of the hgweb config file (DEPRECATED)'),
5003 ('', 'webdir-conf', '', _('name of the hgweb config file (DEPRECATED)'),
4951 _('FILE')),
5004 _('FILE')),
4952 ('', 'pid-file', '', _('name of file to write process ID to'), _('FILE')),
5005 ('', 'pid-file', '', _('name of file to write process ID to'), _('FILE')),
4953 ('', 'stdio', None, _('for remote clients')),
5006 ('', 'stdio', None, _('for remote clients')),
4954 ('', 'cmdserver', '', _('for remote clients'), _('MODE')),
5007 ('', 'cmdserver', '', _('for remote clients'), _('MODE')),
4955 ('t', 'templates', '', _('web templates to use'), _('TEMPLATE')),
5008 ('t', 'templates', '', _('web templates to use'), _('TEMPLATE')),
4956 ('', 'style', '', _('template style to use'), _('STYLE')),
5009 ('', 'style', '', _('template style to use'), _('STYLE')),
4957 ('6', 'ipv6', None, _('use IPv6 in addition to IPv4')),
5010 ('6', 'ipv6', None, _('use IPv6 in addition to IPv4')),
4958 ('', 'certificate', '', _('SSL certificate file'), _('FILE'))],
5011 ('', 'certificate', '', _('SSL certificate file'), _('FILE'))],
4959 _('[OPTION]...'))
5012 _('[OPTION]...'))
4960 def serve(ui, repo, **opts):
5013 def serve(ui, repo, **opts):
4961 """start stand-alone webserver
5014 """start stand-alone webserver
4962
5015
4963 Start a local HTTP repository browser and pull server. You can use
5016 Start a local HTTP repository browser and pull server. You can use
4964 this for ad-hoc sharing and browsing of repositories. It is
5017 this for ad-hoc sharing and browsing of repositories. It is
4965 recommended to use a real web server to serve a repository for
5018 recommended to use a real web server to serve a repository for
4966 longer periods of time.
5019 longer periods of time.
4967
5020
4968 Please note that the server does not implement access control.
5021 Please note that the server does not implement access control.
4969 This means that, by default, anybody can read from the server and
5022 This means that, by default, anybody can read from the server and
4970 nobody can write to it by default. Set the ``web.allow_push``
5023 nobody can write to it by default. Set the ``web.allow_push``
4971 option to ``*`` to allow everybody to push to the server. You
5024 option to ``*`` to allow everybody to push to the server. You
4972 should use a real web server if you need to authenticate users.
5025 should use a real web server if you need to authenticate users.
4973
5026
4974 By default, the server logs accesses to stdout and errors to
5027 By default, the server logs accesses to stdout and errors to
4975 stderr. Use the -A/--accesslog and -E/--errorlog options to log to
5028 stderr. Use the -A/--accesslog and -E/--errorlog options to log to
4976 files.
5029 files.
4977
5030
4978 To have the server choose a free port number to listen on, specify
5031 To have the server choose a free port number to listen on, specify
4979 a port number of 0; in this case, the server will print the port
5032 a port number of 0; in this case, the server will print the port
4980 number it uses.
5033 number it uses.
4981
5034
4982 Returns 0 on success.
5035 Returns 0 on success.
4983 """
5036 """
4984
5037
4985 if opts["stdio"] and opts["cmdserver"]:
5038 if opts["stdio"] and opts["cmdserver"]:
4986 raise util.Abort(_("cannot use --stdio with --cmdserver"))
5039 raise util.Abort(_("cannot use --stdio with --cmdserver"))
4987
5040
4988 def checkrepo():
5041 def checkrepo():
4989 if repo is None:
5042 if repo is None:
4990 raise error.RepoError(_("There is no Mercurial repository here"
5043 raise error.RepoError(_("There is no Mercurial repository here"
4991 " (.hg not found)"))
5044 " (.hg not found)"))
4992
5045
4993 if opts["stdio"]:
5046 if opts["stdio"]:
4994 checkrepo()
5047 checkrepo()
4995 s = sshserver.sshserver(ui, repo)
5048 s = sshserver.sshserver(ui, repo)
4996 s.serve_forever()
5049 s.serve_forever()
4997
5050
4998 if opts["cmdserver"]:
5051 if opts["cmdserver"]:
4999 checkrepo()
5052 checkrepo()
5000 s = commandserver.server(ui, repo, opts["cmdserver"])
5053 s = commandserver.server(ui, repo, opts["cmdserver"])
5001 return s.serve()
5054 return s.serve()
5002
5055
5003 # this way we can check if something was given in the command-line
5056 # this way we can check if something was given in the command-line
5004 if opts.get('port'):
5057 if opts.get('port'):
5005 opts['port'] = util.getport(opts.get('port'))
5058 opts['port'] = util.getport(opts.get('port'))
5006
5059
5007 baseui = repo and repo.baseui or ui
5060 baseui = repo and repo.baseui or ui
5008 optlist = ("name templates style address port prefix ipv6"
5061 optlist = ("name templates style address port prefix ipv6"
5009 " accesslog errorlog certificate encoding")
5062 " accesslog errorlog certificate encoding")
5010 for o in optlist.split():
5063 for o in optlist.split():
5011 val = opts.get(o, '')
5064 val = opts.get(o, '')
5012 if val in (None, ''): # should check against default options instead
5065 if val in (None, ''): # should check against default options instead
5013 continue
5066 continue
5014 baseui.setconfig("web", o, val)
5067 baseui.setconfig("web", o, val)
5015 if repo and repo.ui != baseui:
5068 if repo and repo.ui != baseui:
5016 repo.ui.setconfig("web", o, val)
5069 repo.ui.setconfig("web", o, val)
5017
5070
5018 o = opts.get('web_conf') or opts.get('webdir_conf')
5071 o = opts.get('web_conf') or opts.get('webdir_conf')
5019 if not o:
5072 if not o:
5020 if not repo:
5073 if not repo:
5021 raise error.RepoError(_("There is no Mercurial repository"
5074 raise error.RepoError(_("There is no Mercurial repository"
5022 " here (.hg not found)"))
5075 " here (.hg not found)"))
5023 o = repo.root
5076 o = repo.root
5024
5077
5025 app = hgweb.hgweb(o, baseui=ui)
5078 app = hgweb.hgweb(o, baseui=ui)
5026
5079
5027 class service(object):
5080 class service(object):
5028 def init(self):
5081 def init(self):
5029 util.setsignalhandler()
5082 util.setsignalhandler()
5030 self.httpd = hgweb.server.create_server(ui, app)
5083 self.httpd = hgweb.server.create_server(ui, app)
5031
5084
5032 if opts['port'] and not ui.verbose:
5085 if opts['port'] and not ui.verbose:
5033 return
5086 return
5034
5087
5035 if self.httpd.prefix:
5088 if self.httpd.prefix:
5036 prefix = self.httpd.prefix.strip('/') + '/'
5089 prefix = self.httpd.prefix.strip('/') + '/'
5037 else:
5090 else:
5038 prefix = ''
5091 prefix = ''
5039
5092
5040 port = ':%d' % self.httpd.port
5093 port = ':%d' % self.httpd.port
5041 if port == ':80':
5094 if port == ':80':
5042 port = ''
5095 port = ''
5043
5096
5044 bindaddr = self.httpd.addr
5097 bindaddr = self.httpd.addr
5045 if bindaddr == '0.0.0.0':
5098 if bindaddr == '0.0.0.0':
5046 bindaddr = '*'
5099 bindaddr = '*'
5047 elif ':' in bindaddr: # IPv6
5100 elif ':' in bindaddr: # IPv6
5048 bindaddr = '[%s]' % bindaddr
5101 bindaddr = '[%s]' % bindaddr
5049
5102
5050 fqaddr = self.httpd.fqaddr
5103 fqaddr = self.httpd.fqaddr
5051 if ':' in fqaddr:
5104 if ':' in fqaddr:
5052 fqaddr = '[%s]' % fqaddr
5105 fqaddr = '[%s]' % fqaddr
5053 if opts['port']:
5106 if opts['port']:
5054 write = ui.status
5107 write = ui.status
5055 else:
5108 else:
5056 write = ui.write
5109 write = ui.write
5057 write(_('listening at http://%s%s/%s (bound to %s:%d)\n') %
5110 write(_('listening at http://%s%s/%s (bound to %s:%d)\n') %
5058 (fqaddr, port, prefix, bindaddr, self.httpd.port))
5111 (fqaddr, port, prefix, bindaddr, self.httpd.port))
5059
5112
5060 def run(self):
5113 def run(self):
5061 self.httpd.serve_forever()
5114 self.httpd.serve_forever()
5062
5115
5063 service = service()
5116 service = service()
5064
5117
5065 cmdutil.service(opts, initfn=service.init, runfn=service.run)
5118 cmdutil.service(opts, initfn=service.init, runfn=service.run)
5066
5119
5067 @command('showconfig|debugconfig',
5120 @command('showconfig|debugconfig',
5068 [('u', 'untrusted', None, _('show untrusted configuration options'))],
5121 [('u', 'untrusted', None, _('show untrusted configuration options'))],
5069 _('[-u] [NAME]...'))
5122 _('[-u] [NAME]...'))
5070 def showconfig(ui, repo, *values, **opts):
5123 def showconfig(ui, repo, *values, **opts):
5071 """show combined config settings from all hgrc files
5124 """show combined config settings from all hgrc files
5072
5125
5073 With no arguments, print names and values of all config items.
5126 With no arguments, print names and values of all config items.
5074
5127
5075 With one argument of the form section.name, print just the value
5128 With one argument of the form section.name, print just the value
5076 of that config item.
5129 of that config item.
5077
5130
5078 With multiple arguments, print names and values of all config
5131 With multiple arguments, print names and values of all config
5079 items with matching section names.
5132 items with matching section names.
5080
5133
5081 With --debug, the source (filename and line number) is printed
5134 With --debug, the source (filename and line number) is printed
5082 for each config item.
5135 for each config item.
5083
5136
5084 Returns 0 on success.
5137 Returns 0 on success.
5085 """
5138 """
5086
5139
5087 for f in scmutil.rcpath():
5140 for f in scmutil.rcpath():
5088 ui.debug('read config from: %s\n' % f)
5141 ui.debug('read config from: %s\n' % f)
5089 untrusted = bool(opts.get('untrusted'))
5142 untrusted = bool(opts.get('untrusted'))
5090 if values:
5143 if values:
5091 sections = [v for v in values if '.' not in v]
5144 sections = [v for v in values if '.' not in v]
5092 items = [v for v in values if '.' in v]
5145 items = [v for v in values if '.' in v]
5093 if len(items) > 1 or items and sections:
5146 if len(items) > 1 or items and sections:
5094 raise util.Abort(_('only one config item permitted'))
5147 raise util.Abort(_('only one config item permitted'))
5095 for section, name, value in ui.walkconfig(untrusted=untrusted):
5148 for section, name, value in ui.walkconfig(untrusted=untrusted):
5096 value = str(value).replace('\n', '\\n')
5149 value = str(value).replace('\n', '\\n')
5097 sectname = section + '.' + name
5150 sectname = section + '.' + name
5098 if values:
5151 if values:
5099 for v in values:
5152 for v in values:
5100 if v == section:
5153 if v == section:
5101 ui.debug('%s: ' %
5154 ui.debug('%s: ' %
5102 ui.configsource(section, name, untrusted))
5155 ui.configsource(section, name, untrusted))
5103 ui.write('%s=%s\n' % (sectname, value))
5156 ui.write('%s=%s\n' % (sectname, value))
5104 elif v == sectname:
5157 elif v == sectname:
5105 ui.debug('%s: ' %
5158 ui.debug('%s: ' %
5106 ui.configsource(section, name, untrusted))
5159 ui.configsource(section, name, untrusted))
5107 ui.write(value, '\n')
5160 ui.write(value, '\n')
5108 else:
5161 else:
5109 ui.debug('%s: ' %
5162 ui.debug('%s: ' %
5110 ui.configsource(section, name, untrusted))
5163 ui.configsource(section, name, untrusted))
5111 ui.write('%s=%s\n' % (sectname, value))
5164 ui.write('%s=%s\n' % (sectname, value))
5112
5165
5113 @command('^status|st',
5166 @command('^status|st',
5114 [('A', 'all', None, _('show status of all files')),
5167 [('A', 'all', None, _('show status of all files')),
5115 ('m', 'modified', None, _('show only modified files')),
5168 ('m', 'modified', None, _('show only modified files')),
5116 ('a', 'added', None, _('show only added files')),
5169 ('a', 'added', None, _('show only added files')),
5117 ('r', 'removed', None, _('show only removed files')),
5170 ('r', 'removed', None, _('show only removed files')),
5118 ('d', 'deleted', None, _('show only deleted (but tracked) files')),
5171 ('d', 'deleted', None, _('show only deleted (but tracked) files')),
5119 ('c', 'clean', None, _('show only files without changes')),
5172 ('c', 'clean', None, _('show only files without changes')),
5120 ('u', 'unknown', None, _('show only unknown (not tracked) files')),
5173 ('u', 'unknown', None, _('show only unknown (not tracked) files')),
5121 ('i', 'ignored', None, _('show only ignored files')),
5174 ('i', 'ignored', None, _('show only ignored files')),
5122 ('n', 'no-status', None, _('hide status prefix')),
5175 ('n', 'no-status', None, _('hide status prefix')),
5123 ('C', 'copies', None, _('show source of copied files')),
5176 ('C', 'copies', None, _('show source of copied files')),
5124 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
5177 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
5125 ('', 'rev', [], _('show difference from revision'), _('REV')),
5178 ('', 'rev', [], _('show difference from revision'), _('REV')),
5126 ('', 'change', '', _('list the changed files of a revision'), _('REV')),
5179 ('', 'change', '', _('list the changed files of a revision'), _('REV')),
5127 ] + walkopts + subrepoopts,
5180 ] + walkopts + subrepoopts,
5128 _('[OPTION]... [FILE]...'))
5181 _('[OPTION]... [FILE]...'))
5129 def status(ui, repo, *pats, **opts):
5182 def status(ui, repo, *pats, **opts):
5130 """show changed files in the working directory
5183 """show changed files in the working directory
5131
5184
5132 Show status of files in the repository. If names are given, only
5185 Show status of files in the repository. If names are given, only
5133 files that match are shown. Files that are clean or ignored or
5186 files that match are shown. Files that are clean or ignored or
5134 the source of a copy/move operation, are not listed unless
5187 the source of a copy/move operation, are not listed unless
5135 -c/--clean, -i/--ignored, -C/--copies or -A/--all are given.
5188 -c/--clean, -i/--ignored, -C/--copies or -A/--all are given.
5136 Unless options described with "show only ..." are given, the
5189 Unless options described with "show only ..." are given, the
5137 options -mardu are used.
5190 options -mardu are used.
5138
5191
5139 Option -q/--quiet hides untracked (unknown and ignored) files
5192 Option -q/--quiet hides untracked (unknown and ignored) files
5140 unless explicitly requested with -u/--unknown or -i/--ignored.
5193 unless explicitly requested with -u/--unknown or -i/--ignored.
5141
5194
5142 .. note::
5195 .. note::
5143 status may appear to disagree with diff if permissions have
5196 status may appear to disagree with diff if permissions have
5144 changed or a merge has occurred. The standard diff format does
5197 changed or a merge has occurred. The standard diff format does
5145 not report permission changes and diff only reports changes
5198 not report permission changes and diff only reports changes
5146 relative to one merge parent.
5199 relative to one merge parent.
5147
5200
5148 If one revision is given, it is used as the base revision.
5201 If one revision is given, it is used as the base revision.
5149 If two revisions are given, the differences between them are
5202 If two revisions are given, the differences between them are
5150 shown. The --change option can also be used as a shortcut to list
5203 shown. The --change option can also be used as a shortcut to list
5151 the changed files of a revision from its first parent.
5204 the changed files of a revision from its first parent.
5152
5205
5153 The codes used to show the status of files are::
5206 The codes used to show the status of files are::
5154
5207
5155 M = modified
5208 M = modified
5156 A = added
5209 A = added
5157 R = removed
5210 R = removed
5158 C = clean
5211 C = clean
5159 ! = missing (deleted by non-hg command, but still tracked)
5212 ! = missing (deleted by non-hg command, but still tracked)
5160 ? = not tracked
5213 ? = not tracked
5161 I = ignored
5214 I = ignored
5162 = origin of the previous file listed as A (added)
5215 = origin of the previous file listed as A (added)
5163
5216
5164 .. container:: verbose
5217 .. container:: verbose
5165
5218
5166 Examples:
5219 Examples:
5167
5220
5168 - show changes in the working directory relative to a
5221 - show changes in the working directory relative to a
5169 changeset::
5222 changeset::
5170
5223
5171 hg status --rev 9353
5224 hg status --rev 9353
5172
5225
5173 - show all changes including copies in an existing changeset::
5226 - show all changes including copies in an existing changeset::
5174
5227
5175 hg status --copies --change 9353
5228 hg status --copies --change 9353
5176
5229
5177 - get a NUL separated list of added files, suitable for xargs::
5230 - get a NUL separated list of added files, suitable for xargs::
5178
5231
5179 hg status -an0
5232 hg status -an0
5180
5233
5181 Returns 0 on success.
5234 Returns 0 on success.
5182 """
5235 """
5183
5236
5184 revs = opts.get('rev')
5237 revs = opts.get('rev')
5185 change = opts.get('change')
5238 change = opts.get('change')
5186
5239
5187 if revs and change:
5240 if revs and change:
5188 msg = _('cannot specify --rev and --change at the same time')
5241 msg = _('cannot specify --rev and --change at the same time')
5189 raise util.Abort(msg)
5242 raise util.Abort(msg)
5190 elif change:
5243 elif change:
5191 node2 = scmutil.revsingle(repo, change, None).node()
5244 node2 = scmutil.revsingle(repo, change, None).node()
5192 node1 = repo[node2].p1().node()
5245 node1 = repo[node2].p1().node()
5193 else:
5246 else:
5194 node1, node2 = scmutil.revpair(repo, revs)
5247 node1, node2 = scmutil.revpair(repo, revs)
5195
5248
5196 cwd = (pats and repo.getcwd()) or ''
5249 cwd = (pats and repo.getcwd()) or ''
5197 end = opts.get('print0') and '\0' or '\n'
5250 end = opts.get('print0') and '\0' or '\n'
5198 copy = {}
5251 copy = {}
5199 states = 'modified added removed deleted unknown ignored clean'.split()
5252 states = 'modified added removed deleted unknown ignored clean'.split()
5200 show = [k for k in states if opts.get(k)]
5253 show = [k for k in states if opts.get(k)]
5201 if opts.get('all'):
5254 if opts.get('all'):
5202 show += ui.quiet and (states[:4] + ['clean']) or states
5255 show += ui.quiet and (states[:4] + ['clean']) or states
5203 if not show:
5256 if not show:
5204 show = ui.quiet and states[:4] or states[:5]
5257 show = ui.quiet and states[:4] or states[:5]
5205
5258
5206 stat = repo.status(node1, node2, scmutil.match(repo[node2], pats, opts),
5259 stat = repo.status(node1, node2, scmutil.match(repo[node2], pats, opts),
5207 'ignored' in show, 'clean' in show, 'unknown' in show,
5260 'ignored' in show, 'clean' in show, 'unknown' in show,
5208 opts.get('subrepos'))
5261 opts.get('subrepos'))
5209 changestates = zip(states, 'MAR!?IC', stat)
5262 changestates = zip(states, 'MAR!?IC', stat)
5210
5263
5211 if (opts.get('all') or opts.get('copies')) and not opts.get('no_status'):
5264 if (opts.get('all') or opts.get('copies')) and not opts.get('no_status'):
5212 copy = copies.pathcopies(repo[node1], repo[node2])
5265 copy = copies.pathcopies(repo[node1], repo[node2])
5213
5266
5214 for state, char, files in changestates:
5267 for state, char, files in changestates:
5215 if state in show:
5268 if state in show:
5216 format = "%s %%s%s" % (char, end)
5269 format = "%s %%s%s" % (char, end)
5217 if opts.get('no_status'):
5270 if opts.get('no_status'):
5218 format = "%%s%s" % end
5271 format = "%%s%s" % end
5219
5272
5220 for f in files:
5273 for f in files:
5221 ui.write(format % repo.pathto(f, cwd),
5274 ui.write(format % repo.pathto(f, cwd),
5222 label='status.' + state)
5275 label='status.' + state)
5223 if f in copy:
5276 if f in copy:
5224 ui.write(' %s%s' % (repo.pathto(copy[f], cwd), end),
5277 ui.write(' %s%s' % (repo.pathto(copy[f], cwd), end),
5225 label='status.copied')
5278 label='status.copied')
5226
5279
5227 @command('^summary|sum',
5280 @command('^summary|sum',
5228 [('', 'remote', None, _('check for push and pull'))], '[--remote]')
5281 [('', 'remote', None, _('check for push and pull'))], '[--remote]')
5229 def summary(ui, repo, **opts):
5282 def summary(ui, repo, **opts):
5230 """summarize working directory state
5283 """summarize working directory state
5231
5284
5232 This generates a brief summary of the working directory state,
5285 This generates a brief summary of the working directory state,
5233 including parents, branch, commit status, and available updates.
5286 including parents, branch, commit status, and available updates.
5234
5287
5235 With the --remote option, this will check the default paths for
5288 With the --remote option, this will check the default paths for
5236 incoming and outgoing changes. This can be time-consuming.
5289 incoming and outgoing changes. This can be time-consuming.
5237
5290
5238 Returns 0 on success.
5291 Returns 0 on success.
5239 """
5292 """
5240
5293
5241 ctx = repo[None]
5294 ctx = repo[None]
5242 parents = ctx.parents()
5295 parents = ctx.parents()
5243 pnode = parents[0].node()
5296 pnode = parents[0].node()
5244 marks = []
5297 marks = []
5245
5298
5246 for p in parents:
5299 for p in parents:
5247 # label with log.changeset (instead of log.parent) since this
5300 # label with log.changeset (instead of log.parent) since this
5248 # shows a working directory parent *changeset*:
5301 # shows a working directory parent *changeset*:
5249 ui.write(_('parent: %d:%s ') % (p.rev(), str(p)),
5302 ui.write(_('parent: %d:%s ') % (p.rev(), str(p)),
5250 label='log.changeset')
5303 label='log.changeset')
5251 ui.write(' '.join(p.tags()), label='log.tag')
5304 ui.write(' '.join(p.tags()), label='log.tag')
5252 if p.bookmarks():
5305 if p.bookmarks():
5253 marks.extend(p.bookmarks())
5306 marks.extend(p.bookmarks())
5254 if p.rev() == -1:
5307 if p.rev() == -1:
5255 if not len(repo):
5308 if not len(repo):
5256 ui.write(_(' (empty repository)'))
5309 ui.write(_(' (empty repository)'))
5257 else:
5310 else:
5258 ui.write(_(' (no revision checked out)'))
5311 ui.write(_(' (no revision checked out)'))
5259 ui.write('\n')
5312 ui.write('\n')
5260 if p.description():
5313 if p.description():
5261 ui.status(' ' + p.description().splitlines()[0].strip() + '\n',
5314 ui.status(' ' + p.description().splitlines()[0].strip() + '\n',
5262 label='log.summary')
5315 label='log.summary')
5263
5316
5264 branch = ctx.branch()
5317 branch = ctx.branch()
5265 bheads = repo.branchheads(branch)
5318 bheads = repo.branchheads(branch)
5266 m = _('branch: %s\n') % branch
5319 m = _('branch: %s\n') % branch
5267 if branch != 'default':
5320 if branch != 'default':
5268 ui.write(m, label='log.branch')
5321 ui.write(m, label='log.branch')
5269 else:
5322 else:
5270 ui.status(m, label='log.branch')
5323 ui.status(m, label='log.branch')
5271
5324
5272 if marks:
5325 if marks:
5273 current = repo._bookmarkcurrent
5326 current = repo._bookmarkcurrent
5274 ui.write(_('bookmarks:'), label='log.bookmark')
5327 ui.write(_('bookmarks:'), label='log.bookmark')
5275 if current is not None:
5328 if current is not None:
5276 try:
5329 try:
5277 marks.remove(current)
5330 marks.remove(current)
5278 ui.write(' *' + current, label='bookmarks.current')
5331 ui.write(' *' + current, label='bookmarks.current')
5279 except ValueError:
5332 except ValueError:
5280 # current bookmark not in parent ctx marks
5333 # current bookmark not in parent ctx marks
5281 pass
5334 pass
5282 for m in marks:
5335 for m in marks:
5283 ui.write(' ' + m, label='log.bookmark')
5336 ui.write(' ' + m, label='log.bookmark')
5284 ui.write('\n', label='log.bookmark')
5337 ui.write('\n', label='log.bookmark')
5285
5338
5286 st = list(repo.status(unknown=True))[:6]
5339 st = list(repo.status(unknown=True))[:6]
5287
5340
5288 c = repo.dirstate.copies()
5341 c = repo.dirstate.copies()
5289 copied, renamed = [], []
5342 copied, renamed = [], []
5290 for d, s in c.iteritems():
5343 for d, s in c.iteritems():
5291 if s in st[2]:
5344 if s in st[2]:
5292 st[2].remove(s)
5345 st[2].remove(s)
5293 renamed.append(d)
5346 renamed.append(d)
5294 else:
5347 else:
5295 copied.append(d)
5348 copied.append(d)
5296 if d in st[1]:
5349 if d in st[1]:
5297 st[1].remove(d)
5350 st[1].remove(d)
5298 st.insert(3, renamed)
5351 st.insert(3, renamed)
5299 st.insert(4, copied)
5352 st.insert(4, copied)
5300
5353
5301 ms = mergemod.mergestate(repo)
5354 ms = mergemod.mergestate(repo)
5302 st.append([f for f in ms if ms[f] == 'u'])
5355 st.append([f for f in ms if ms[f] == 'u'])
5303
5356
5304 subs = [s for s in ctx.substate if ctx.sub(s).dirty()]
5357 subs = [s for s in ctx.substate if ctx.sub(s).dirty()]
5305 st.append(subs)
5358 st.append(subs)
5306
5359
5307 labels = [ui.label(_('%d modified'), 'status.modified'),
5360 labels = [ui.label(_('%d modified'), 'status.modified'),
5308 ui.label(_('%d added'), 'status.added'),
5361 ui.label(_('%d added'), 'status.added'),
5309 ui.label(_('%d removed'), 'status.removed'),
5362 ui.label(_('%d removed'), 'status.removed'),
5310 ui.label(_('%d renamed'), 'status.copied'),
5363 ui.label(_('%d renamed'), 'status.copied'),
5311 ui.label(_('%d copied'), 'status.copied'),
5364 ui.label(_('%d copied'), 'status.copied'),
5312 ui.label(_('%d deleted'), 'status.deleted'),
5365 ui.label(_('%d deleted'), 'status.deleted'),
5313 ui.label(_('%d unknown'), 'status.unknown'),
5366 ui.label(_('%d unknown'), 'status.unknown'),
5314 ui.label(_('%d ignored'), 'status.ignored'),
5367 ui.label(_('%d ignored'), 'status.ignored'),
5315 ui.label(_('%d unresolved'), 'resolve.unresolved'),
5368 ui.label(_('%d unresolved'), 'resolve.unresolved'),
5316 ui.label(_('%d subrepos'), 'status.modified')]
5369 ui.label(_('%d subrepos'), 'status.modified')]
5317 t = []
5370 t = []
5318 for s, l in zip(st, labels):
5371 for s, l in zip(st, labels):
5319 if s:
5372 if s:
5320 t.append(l % len(s))
5373 t.append(l % len(s))
5321
5374
5322 t = ', '.join(t)
5375 t = ', '.join(t)
5323 cleanworkdir = False
5376 cleanworkdir = False
5324
5377
5325 if len(parents) > 1:
5378 if len(parents) > 1:
5326 t += _(' (merge)')
5379 t += _(' (merge)')
5327 elif branch != parents[0].branch():
5380 elif branch != parents[0].branch():
5328 t += _(' (new branch)')
5381 t += _(' (new branch)')
5329 elif (parents[0].extra().get('close') and
5382 elif (parents[0].extra().get('close') and
5330 pnode in repo.branchheads(branch, closed=True)):
5383 pnode in repo.branchheads(branch, closed=True)):
5331 t += _(' (head closed)')
5384 t += _(' (head closed)')
5332 elif not (st[0] or st[1] or st[2] or st[3] or st[4] or st[9]):
5385 elif not (st[0] or st[1] or st[2] or st[3] or st[4] or st[9]):
5333 t += _(' (clean)')
5386 t += _(' (clean)')
5334 cleanworkdir = True
5387 cleanworkdir = True
5335 elif pnode not in bheads:
5388 elif pnode not in bheads:
5336 t += _(' (new branch head)')
5389 t += _(' (new branch head)')
5337
5390
5338 if cleanworkdir:
5391 if cleanworkdir:
5339 ui.status(_('commit: %s\n') % t.strip())
5392 ui.status(_('commit: %s\n') % t.strip())
5340 else:
5393 else:
5341 ui.write(_('commit: %s\n') % t.strip())
5394 ui.write(_('commit: %s\n') % t.strip())
5342
5395
5343 # all ancestors of branch heads - all ancestors of parent = new csets
5396 # all ancestors of branch heads - all ancestors of parent = new csets
5344 new = [0] * len(repo)
5397 new = [0] * len(repo)
5345 cl = repo.changelog
5398 cl = repo.changelog
5346 for a in [cl.rev(n) for n in bheads]:
5399 for a in [cl.rev(n) for n in bheads]:
5347 new[a] = 1
5400 new[a] = 1
5348 for a in cl.ancestors(*[cl.rev(n) for n in bheads]):
5401 for a in cl.ancestors(*[cl.rev(n) for n in bheads]):
5349 new[a] = 1
5402 new[a] = 1
5350 for a in [p.rev() for p in parents]:
5403 for a in [p.rev() for p in parents]:
5351 if a >= 0:
5404 if a >= 0:
5352 new[a] = 0
5405 new[a] = 0
5353 for a in cl.ancestors(*[p.rev() for p in parents]):
5406 for a in cl.ancestors(*[p.rev() for p in parents]):
5354 new[a] = 0
5407 new[a] = 0
5355 new = sum(new)
5408 new = sum(new)
5356
5409
5357 if new == 0:
5410 if new == 0:
5358 ui.status(_('update: (current)\n'))
5411 ui.status(_('update: (current)\n'))
5359 elif pnode not in bheads:
5412 elif pnode not in bheads:
5360 ui.write(_('update: %d new changesets (update)\n') % new)
5413 ui.write(_('update: %d new changesets (update)\n') % new)
5361 else:
5414 else:
5362 ui.write(_('update: %d new changesets, %d branch heads (merge)\n') %
5415 ui.write(_('update: %d new changesets, %d branch heads (merge)\n') %
5363 (new, len(bheads)))
5416 (new, len(bheads)))
5364
5417
5365 if opts.get('remote'):
5418 if opts.get('remote'):
5366 t = []
5419 t = []
5367 source, branches = hg.parseurl(ui.expandpath('default'))
5420 source, branches = hg.parseurl(ui.expandpath('default'))
5368 other = hg.peer(repo, {}, source)
5421 other = hg.peer(repo, {}, source)
5369 revs, checkout = hg.addbranchrevs(repo, other, branches, opts.get('rev'))
5422 revs, checkout = hg.addbranchrevs(repo, other, branches, opts.get('rev'))
5370 ui.debug('comparing with %s\n' % util.hidepassword(source))
5423 ui.debug('comparing with %s\n' % util.hidepassword(source))
5371 repo.ui.pushbuffer()
5424 repo.ui.pushbuffer()
5372 commoninc = discovery.findcommonincoming(repo, other)
5425 commoninc = discovery.findcommonincoming(repo, other)
5373 _common, incoming, _rheads = commoninc
5426 _common, incoming, _rheads = commoninc
5374 repo.ui.popbuffer()
5427 repo.ui.popbuffer()
5375 if incoming:
5428 if incoming:
5376 t.append(_('1 or more incoming'))
5429 t.append(_('1 or more incoming'))
5377
5430
5378 dest, branches = hg.parseurl(ui.expandpath('default-push', 'default'))
5431 dest, branches = hg.parseurl(ui.expandpath('default-push', 'default'))
5379 revs, checkout = hg.addbranchrevs(repo, repo, branches, None)
5432 revs, checkout = hg.addbranchrevs(repo, repo, branches, None)
5380 if source != dest:
5433 if source != dest:
5381 other = hg.peer(repo, {}, dest)
5434 other = hg.peer(repo, {}, dest)
5382 commoninc = None
5435 commoninc = None
5383 ui.debug('comparing with %s\n' % util.hidepassword(dest))
5436 ui.debug('comparing with %s\n' % util.hidepassword(dest))
5384 repo.ui.pushbuffer()
5437 repo.ui.pushbuffer()
5385 common, outheads = discovery.findcommonoutgoing(repo, other,
5438 common, outheads = discovery.findcommonoutgoing(repo, other,
5386 commoninc=commoninc)
5439 commoninc=commoninc)
5387 repo.ui.popbuffer()
5440 repo.ui.popbuffer()
5388 o = repo.changelog.findmissing(common=common, heads=outheads)
5441 o = repo.changelog.findmissing(common=common, heads=outheads)
5389 if o:
5442 if o:
5390 t.append(_('%d outgoing') % len(o))
5443 t.append(_('%d outgoing') % len(o))
5391 if 'bookmarks' in other.listkeys('namespaces'):
5444 if 'bookmarks' in other.listkeys('namespaces'):
5392 lmarks = repo.listkeys('bookmarks')
5445 lmarks = repo.listkeys('bookmarks')
5393 rmarks = other.listkeys('bookmarks')
5446 rmarks = other.listkeys('bookmarks')
5394 diff = set(rmarks) - set(lmarks)
5447 diff = set(rmarks) - set(lmarks)
5395 if len(diff) > 0:
5448 if len(diff) > 0:
5396 t.append(_('%d incoming bookmarks') % len(diff))
5449 t.append(_('%d incoming bookmarks') % len(diff))
5397 diff = set(lmarks) - set(rmarks)
5450 diff = set(lmarks) - set(rmarks)
5398 if len(diff) > 0:
5451 if len(diff) > 0:
5399 t.append(_('%d outgoing bookmarks') % len(diff))
5452 t.append(_('%d outgoing bookmarks') % len(diff))
5400
5453
5401 if t:
5454 if t:
5402 ui.write(_('remote: %s\n') % (', '.join(t)))
5455 ui.write(_('remote: %s\n') % (', '.join(t)))
5403 else:
5456 else:
5404 ui.status(_('remote: (synced)\n'))
5457 ui.status(_('remote: (synced)\n'))
5405
5458
5406 @command('tag',
5459 @command('tag',
5407 [('f', 'force', None, _('force tag')),
5460 [('f', 'force', None, _('force tag')),
5408 ('l', 'local', None, _('make the tag local')),
5461 ('l', 'local', None, _('make the tag local')),
5409 ('r', 'rev', '', _('revision to tag'), _('REV')),
5462 ('r', 'rev', '', _('revision to tag'), _('REV')),
5410 ('', 'remove', None, _('remove a tag')),
5463 ('', 'remove', None, _('remove a tag')),
5411 # -l/--local is already there, commitopts cannot be used
5464 # -l/--local is already there, commitopts cannot be used
5412 ('e', 'edit', None, _('edit commit message')),
5465 ('e', 'edit', None, _('edit commit message')),
5413 ('m', 'message', '', _('use <text> as commit message'), _('TEXT')),
5466 ('m', 'message', '', _('use <text> as commit message'), _('TEXT')),
5414 ] + commitopts2,
5467 ] + commitopts2,
5415 _('[-f] [-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME...'))
5468 _('[-f] [-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME...'))
5416 def tag(ui, repo, name1, *names, **opts):
5469 def tag(ui, repo, name1, *names, **opts):
5417 """add one or more tags for the current or given revision
5470 """add one or more tags for the current or given revision
5418
5471
5419 Name a particular revision using <name>.
5472 Name a particular revision using <name>.
5420
5473
5421 Tags are used to name particular revisions of the repository and are
5474 Tags are used to name particular revisions of the repository and are
5422 very useful to compare different revisions, to go back to significant
5475 very useful to compare different revisions, to go back to significant
5423 earlier versions or to mark branch points as releases, etc. Changing
5476 earlier versions or to mark branch points as releases, etc. Changing
5424 an existing tag is normally disallowed; use -f/--force to override.
5477 an existing tag is normally disallowed; use -f/--force to override.
5425
5478
5426 If no revision is given, the parent of the working directory is
5479 If no revision is given, the parent of the working directory is
5427 used, or tip if no revision is checked out.
5480 used, or tip if no revision is checked out.
5428
5481
5429 To facilitate version control, distribution, and merging of tags,
5482 To facilitate version control, distribution, and merging of tags,
5430 they are stored as a file named ".hgtags" which is managed similarly
5483 they are stored as a file named ".hgtags" which is managed similarly
5431 to other project files and can be hand-edited if necessary. This
5484 to other project files and can be hand-edited if necessary. This
5432 also means that tagging creates a new commit. The file
5485 also means that tagging creates a new commit. The file
5433 ".hg/localtags" is used for local tags (not shared among
5486 ".hg/localtags" is used for local tags (not shared among
5434 repositories).
5487 repositories).
5435
5488
5436 Tag commits are usually made at the head of a branch. If the parent
5489 Tag commits are usually made at the head of a branch. If the parent
5437 of the working directory is not a branch head, :hg:`tag` aborts; use
5490 of the working directory is not a branch head, :hg:`tag` aborts; use
5438 -f/--force to force the tag commit to be based on a non-head
5491 -f/--force to force the tag commit to be based on a non-head
5439 changeset.
5492 changeset.
5440
5493
5441 See :hg:`help dates` for a list of formats valid for -d/--date.
5494 See :hg:`help dates` for a list of formats valid for -d/--date.
5442
5495
5443 Since tag names have priority over branch names during revision
5496 Since tag names have priority over branch names during revision
5444 lookup, using an existing branch name as a tag name is discouraged.
5497 lookup, using an existing branch name as a tag name is discouraged.
5445
5498
5446 Returns 0 on success.
5499 Returns 0 on success.
5447 """
5500 """
5448
5501
5449 rev_ = "."
5502 rev_ = "."
5450 names = [t.strip() for t in (name1,) + names]
5503 names = [t.strip() for t in (name1,) + names]
5451 if len(names) != len(set(names)):
5504 if len(names) != len(set(names)):
5452 raise util.Abort(_('tag names must be unique'))
5505 raise util.Abort(_('tag names must be unique'))
5453 for n in names:
5506 for n in names:
5454 if n in ['tip', '.', 'null']:
5507 if n in ['tip', '.', 'null']:
5455 raise util.Abort(_("the name '%s' is reserved") % n)
5508 raise util.Abort(_("the name '%s' is reserved") % n)
5456 if not n:
5509 if not n:
5457 raise util.Abort(_('tag names cannot consist entirely of whitespace'))
5510 raise util.Abort(_('tag names cannot consist entirely of whitespace'))
5458 if opts.get('rev') and opts.get('remove'):
5511 if opts.get('rev') and opts.get('remove'):
5459 raise util.Abort(_("--rev and --remove are incompatible"))
5512 raise util.Abort(_("--rev and --remove are incompatible"))
5460 if opts.get('rev'):
5513 if opts.get('rev'):
5461 rev_ = opts['rev']
5514 rev_ = opts['rev']
5462 message = opts.get('message')
5515 message = opts.get('message')
5463 if opts.get('remove'):
5516 if opts.get('remove'):
5464 expectedtype = opts.get('local') and 'local' or 'global'
5517 expectedtype = opts.get('local') and 'local' or 'global'
5465 for n in names:
5518 for n in names:
5466 if not repo.tagtype(n):
5519 if not repo.tagtype(n):
5467 raise util.Abort(_("tag '%s' does not exist") % n)
5520 raise util.Abort(_("tag '%s' does not exist") % n)
5468 if repo.tagtype(n) != expectedtype:
5521 if repo.tagtype(n) != expectedtype:
5469 if expectedtype == 'global':
5522 if expectedtype == 'global':
5470 raise util.Abort(_("tag '%s' is not a global tag") % n)
5523 raise util.Abort(_("tag '%s' is not a global tag") % n)
5471 else:
5524 else:
5472 raise util.Abort(_("tag '%s' is not a local tag") % n)
5525 raise util.Abort(_("tag '%s' is not a local tag") % n)
5473 rev_ = nullid
5526 rev_ = nullid
5474 if not message:
5527 if not message:
5475 # we don't translate commit messages
5528 # we don't translate commit messages
5476 message = 'Removed tag %s' % ', '.join(names)
5529 message = 'Removed tag %s' % ', '.join(names)
5477 elif not opts.get('force'):
5530 elif not opts.get('force'):
5478 for n in names:
5531 for n in names:
5479 if n in repo.tags():
5532 if n in repo.tags():
5480 raise util.Abort(_("tag '%s' already exists "
5533 raise util.Abort(_("tag '%s' already exists "
5481 "(use -f to force)") % n)
5534 "(use -f to force)") % n)
5482 if not opts.get('local'):
5535 if not opts.get('local'):
5483 p1, p2 = repo.dirstate.parents()
5536 p1, p2 = repo.dirstate.parents()
5484 if p2 != nullid:
5537 if p2 != nullid:
5485 raise util.Abort(_('uncommitted merge'))
5538 raise util.Abort(_('uncommitted merge'))
5486 bheads = repo.branchheads()
5539 bheads = repo.branchheads()
5487 if not opts.get('force') and bheads and p1 not in bheads:
5540 if not opts.get('force') and bheads and p1 not in bheads:
5488 raise util.Abort(_('not at a branch head (use -f to force)'))
5541 raise util.Abort(_('not at a branch head (use -f to force)'))
5489 r = scmutil.revsingle(repo, rev_).node()
5542 r = scmutil.revsingle(repo, rev_).node()
5490
5543
5491 if not message:
5544 if not message:
5492 # we don't translate commit messages
5545 # we don't translate commit messages
5493 message = ('Added tag %s for changeset %s' %
5546 message = ('Added tag %s for changeset %s' %
5494 (', '.join(names), short(r)))
5547 (', '.join(names), short(r)))
5495
5548
5496 date = opts.get('date')
5549 date = opts.get('date')
5497 if date:
5550 if date:
5498 date = util.parsedate(date)
5551 date = util.parsedate(date)
5499
5552
5500 if opts.get('edit'):
5553 if opts.get('edit'):
5501 message = ui.edit(message, ui.username())
5554 message = ui.edit(message, ui.username())
5502
5555
5503 repo.tag(names, r, message, opts.get('local'), opts.get('user'), date)
5556 repo.tag(names, r, message, opts.get('local'), opts.get('user'), date)
5504
5557
5505 @command('tags', [], '')
5558 @command('tags', [], '')
5506 def tags(ui, repo):
5559 def tags(ui, repo):
5507 """list repository tags
5560 """list repository tags
5508
5561
5509 This lists both regular and local tags. When the -v/--verbose
5562 This lists both regular and local tags. When the -v/--verbose
5510 switch is used, a third column "local" is printed for local tags.
5563 switch is used, a third column "local" is printed for local tags.
5511
5564
5512 Returns 0 on success.
5565 Returns 0 on success.
5513 """
5566 """
5514
5567
5515 hexfunc = ui.debugflag and hex or short
5568 hexfunc = ui.debugflag and hex or short
5516 tagtype = ""
5569 tagtype = ""
5517
5570
5518 for t, n in reversed(repo.tagslist()):
5571 for t, n in reversed(repo.tagslist()):
5519 if ui.quiet:
5572 if ui.quiet:
5520 ui.write("%s\n" % t, label='tags.normal')
5573 ui.write("%s\n" % t, label='tags.normal')
5521 continue
5574 continue
5522
5575
5523 hn = hexfunc(n)
5576 hn = hexfunc(n)
5524 r = "%5d:%s" % (repo.changelog.rev(n), hn)
5577 r = "%5d:%s" % (repo.changelog.rev(n), hn)
5525 rev = ui.label(r, 'log.changeset')
5578 rev = ui.label(r, 'log.changeset')
5526 spaces = " " * (30 - encoding.colwidth(t))
5579 spaces = " " * (30 - encoding.colwidth(t))
5527
5580
5528 tag = ui.label(t, 'tags.normal')
5581 tag = ui.label(t, 'tags.normal')
5529 if ui.verbose:
5582 if ui.verbose:
5530 if repo.tagtype(t) == 'local':
5583 if repo.tagtype(t) == 'local':
5531 tagtype = " local"
5584 tagtype = " local"
5532 tag = ui.label(t, 'tags.local')
5585 tag = ui.label(t, 'tags.local')
5533 else:
5586 else:
5534 tagtype = ""
5587 tagtype = ""
5535 ui.write("%s%s %s%s\n" % (tag, spaces, rev, tagtype))
5588 ui.write("%s%s %s%s\n" % (tag, spaces, rev, tagtype))
5536
5589
5537 @command('tip',
5590 @command('tip',
5538 [('p', 'patch', None, _('show patch')),
5591 [('p', 'patch', None, _('show patch')),
5539 ('g', 'git', None, _('use git extended diff format')),
5592 ('g', 'git', None, _('use git extended diff format')),
5540 ] + templateopts,
5593 ] + templateopts,
5541 _('[-p] [-g]'))
5594 _('[-p] [-g]'))
5542 def tip(ui, repo, **opts):
5595 def tip(ui, repo, **opts):
5543 """show the tip revision
5596 """show the tip revision
5544
5597
5545 The tip revision (usually just called the tip) is the changeset
5598 The tip revision (usually just called the tip) is the changeset
5546 most recently added to the repository (and therefore the most
5599 most recently added to the repository (and therefore the most
5547 recently changed head).
5600 recently changed head).
5548
5601
5549 If you have just made a commit, that commit will be the tip. If
5602 If you have just made a commit, that commit will be the tip. If
5550 you have just pulled changes from another repository, the tip of
5603 you have just pulled changes from another repository, the tip of
5551 that repository becomes the current tip. The "tip" tag is special
5604 that repository becomes the current tip. The "tip" tag is special
5552 and cannot be renamed or assigned to a different changeset.
5605 and cannot be renamed or assigned to a different changeset.
5553
5606
5554 Returns 0 on success.
5607 Returns 0 on success.
5555 """
5608 """
5556 displayer = cmdutil.show_changeset(ui, repo, opts)
5609 displayer = cmdutil.show_changeset(ui, repo, opts)
5557 displayer.show(repo[len(repo) - 1])
5610 displayer.show(repo[len(repo) - 1])
5558 displayer.close()
5611 displayer.close()
5559
5612
5560 @command('unbundle',
5613 @command('unbundle',
5561 [('u', 'update', None,
5614 [('u', 'update', None,
5562 _('update to new branch head if changesets were unbundled'))],
5615 _('update to new branch head if changesets were unbundled'))],
5563 _('[-u] FILE...'))
5616 _('[-u] FILE...'))
5564 def unbundle(ui, repo, fname1, *fnames, **opts):
5617 def unbundle(ui, repo, fname1, *fnames, **opts):
5565 """apply one or more changegroup files
5618 """apply one or more changegroup files
5566
5619
5567 Apply one or more compressed changegroup files generated by the
5620 Apply one or more compressed changegroup files generated by the
5568 bundle command.
5621 bundle command.
5569
5622
5570 Returns 0 on success, 1 if an update has unresolved files.
5623 Returns 0 on success, 1 if an update has unresolved files.
5571 """
5624 """
5572 fnames = (fname1,) + fnames
5625 fnames = (fname1,) + fnames
5573
5626
5574 lock = repo.lock()
5627 lock = repo.lock()
5575 wc = repo['.']
5628 wc = repo['.']
5576 try:
5629 try:
5577 for fname in fnames:
5630 for fname in fnames:
5578 f = url.open(ui, fname)
5631 f = url.open(ui, fname)
5579 gen = changegroup.readbundle(f, fname)
5632 gen = changegroup.readbundle(f, fname)
5580 modheads = repo.addchangegroup(gen, 'unbundle', 'bundle:' + fname)
5633 modheads = repo.addchangegroup(gen, 'unbundle', 'bundle:' + fname)
5581 bookmarks.updatecurrentbookmark(repo, wc.node(), wc.branch())
5634 bookmarks.updatecurrentbookmark(repo, wc.node(), wc.branch())
5582 finally:
5635 finally:
5583 lock.release()
5636 lock.release()
5584 return postincoming(ui, repo, modheads, opts.get('update'), None)
5637 return postincoming(ui, repo, modheads, opts.get('update'), None)
5585
5638
5586 @command('^update|up|checkout|co',
5639 @command('^update|up|checkout|co',
5587 [('C', 'clean', None, _('discard uncommitted changes (no backup)')),
5640 [('C', 'clean', None, _('discard uncommitted changes (no backup)')),
5588 ('c', 'check', None,
5641 ('c', 'check', None,
5589 _('update across branches if no uncommitted changes')),
5642 _('update across branches if no uncommitted changes')),
5590 ('d', 'date', '', _('tipmost revision matching date'), _('DATE')),
5643 ('d', 'date', '', _('tipmost revision matching date'), _('DATE')),
5591 ('r', 'rev', '', _('revision'), _('REV'))],
5644 ('r', 'rev', '', _('revision'), _('REV'))],
5592 _('[-c] [-C] [-d DATE] [[-r] REV]'))
5645 _('[-c] [-C] [-d DATE] [[-r] REV]'))
5593 def update(ui, repo, node=None, rev=None, clean=False, date=None, check=False):
5646 def update(ui, repo, node=None, rev=None, clean=False, date=None, check=False):
5594 """update working directory (or switch revisions)
5647 """update working directory (or switch revisions)
5595
5648
5596 Update the repository's working directory to the specified
5649 Update the repository's working directory to the specified
5597 changeset. If no changeset is specified, update to the tip of the
5650 changeset. If no changeset is specified, update to the tip of the
5598 current named branch.
5651 current named branch.
5599
5652
5600 If the changeset is not a descendant of the working directory's
5653 If the changeset is not a descendant of the working directory's
5601 parent, the update is aborted. With the -c/--check option, the
5654 parent, the update is aborted. With the -c/--check option, the
5602 working directory is checked for uncommitted changes; if none are
5655 working directory is checked for uncommitted changes; if none are
5603 found, the working directory is updated to the specified
5656 found, the working directory is updated to the specified
5604 changeset.
5657 changeset.
5605
5658
5606 Update sets the working directory's parent revison to the specified
5659 Update sets the working directory's parent revison to the specified
5607 changeset (see :hg:`help parents`).
5660 changeset (see :hg:`help parents`).
5608
5661
5609 The following rules apply when the working directory contains
5662 The following rules apply when the working directory contains
5610 uncommitted changes:
5663 uncommitted changes:
5611
5664
5612 1. If neither -c/--check nor -C/--clean is specified, and if
5665 1. If neither -c/--check nor -C/--clean is specified, and if
5613 the requested changeset is an ancestor or descendant of
5666 the requested changeset is an ancestor or descendant of
5614 the working directory's parent, the uncommitted changes
5667 the working directory's parent, the uncommitted changes
5615 are merged into the requested changeset and the merged
5668 are merged into the requested changeset and the merged
5616 result is left uncommitted. If the requested changeset is
5669 result is left uncommitted. If the requested changeset is
5617 not an ancestor or descendant (that is, it is on another
5670 not an ancestor or descendant (that is, it is on another
5618 branch), the update is aborted and the uncommitted changes
5671 branch), the update is aborted and the uncommitted changes
5619 are preserved.
5672 are preserved.
5620
5673
5621 2. With the -c/--check option, the update is aborted and the
5674 2. With the -c/--check option, the update is aborted and the
5622 uncommitted changes are preserved.
5675 uncommitted changes are preserved.
5623
5676
5624 3. With the -C/--clean option, uncommitted changes are discarded and
5677 3. With the -C/--clean option, uncommitted changes are discarded and
5625 the working directory is updated to the requested changeset.
5678 the working directory is updated to the requested changeset.
5626
5679
5627 Use null as the changeset to remove the working directory (like
5680 Use null as the changeset to remove the working directory (like
5628 :hg:`clone -U`).
5681 :hg:`clone -U`).
5629
5682
5630 If you want to revert just one file to an older revision, use
5683 If you want to revert just one file to an older revision, use
5631 :hg:`revert [-r REV] NAME`.
5684 :hg:`revert [-r REV] NAME`.
5632
5685
5633 See :hg:`help dates` for a list of formats valid for -d/--date.
5686 See :hg:`help dates` for a list of formats valid for -d/--date.
5634
5687
5635 Returns 0 on success, 1 if there are unresolved files.
5688 Returns 0 on success, 1 if there are unresolved files.
5636 """
5689 """
5637 if rev and node:
5690 if rev and node:
5638 raise util.Abort(_("please specify just one revision"))
5691 raise util.Abort(_("please specify just one revision"))
5639
5692
5640 if rev is None or rev == '':
5693 if rev is None or rev == '':
5641 rev = node
5694 rev = node
5642
5695
5643 # if we defined a bookmark, we have to remember the original bookmark name
5696 # if we defined a bookmark, we have to remember the original bookmark name
5644 brev = rev
5697 brev = rev
5645 rev = scmutil.revsingle(repo, rev, rev).rev()
5698 rev = scmutil.revsingle(repo, rev, rev).rev()
5646
5699
5647 if check and clean:
5700 if check and clean:
5648 raise util.Abort(_("cannot specify both -c/--check and -C/--clean"))
5701 raise util.Abort(_("cannot specify both -c/--check and -C/--clean"))
5649
5702
5650 if check:
5703 if check:
5651 # we could use dirty() but we can ignore merge and branch trivia
5704 # we could use dirty() but we can ignore merge and branch trivia
5652 c = repo[None]
5705 c = repo[None]
5653 if c.modified() or c.added() or c.removed():
5706 if c.modified() or c.added() or c.removed():
5654 raise util.Abort(_("uncommitted local changes"))
5707 raise util.Abort(_("uncommitted local changes"))
5655
5708
5656 if date:
5709 if date:
5657 if rev is not None:
5710 if rev is not None:
5658 raise util.Abort(_("you can't specify a revision and a date"))
5711 raise util.Abort(_("you can't specify a revision and a date"))
5659 rev = cmdutil.finddate(ui, repo, date)
5712 rev = cmdutil.finddate(ui, repo, date)
5660
5713
5661 if clean or check:
5714 if clean or check:
5662 ret = hg.clean(repo, rev)
5715 ret = hg.clean(repo, rev)
5663 else:
5716 else:
5664 ret = hg.update(repo, rev)
5717 ret = hg.update(repo, rev)
5665
5718
5666 if brev in repo._bookmarks:
5719 if brev in repo._bookmarks:
5667 bookmarks.setcurrent(repo, brev)
5720 bookmarks.setcurrent(repo, brev)
5668
5721
5669 return ret
5722 return ret
5670
5723
5671 @command('verify', [])
5724 @command('verify', [])
5672 def verify(ui, repo):
5725 def verify(ui, repo):
5673 """verify the integrity of the repository
5726 """verify the integrity of the repository
5674
5727
5675 Verify the integrity of the current repository.
5728 Verify the integrity of the current repository.
5676
5729
5677 This will perform an extensive check of the repository's
5730 This will perform an extensive check of the repository's
5678 integrity, validating the hashes and checksums of each entry in
5731 integrity, validating the hashes and checksums of each entry in
5679 the changelog, manifest, and tracked files, as well as the
5732 the changelog, manifest, and tracked files, as well as the
5680 integrity of their crosslinks and indices.
5733 integrity of their crosslinks and indices.
5681
5734
5682 Returns 0 on success, 1 if errors are encountered.
5735 Returns 0 on success, 1 if errors are encountered.
5683 """
5736 """
5684 return hg.verify(repo)
5737 return hg.verify(repo)
5685
5738
5686 @command('version', [])
5739 @command('version', [])
5687 def version_(ui):
5740 def version_(ui):
5688 """output version and copyright information"""
5741 """output version and copyright information"""
5689 ui.write(_("Mercurial Distributed SCM (version %s)\n")
5742 ui.write(_("Mercurial Distributed SCM (version %s)\n")
5690 % util.version())
5743 % util.version())
5691 ui.status(_(
5744 ui.status(_(
5692 "(see http://mercurial.selenic.com for more information)\n"
5745 "(see http://mercurial.selenic.com for more information)\n"
5693 "\nCopyright (C) 2005-2011 Matt Mackall and others\n"
5746 "\nCopyright (C) 2005-2011 Matt Mackall and others\n"
5694 "This is free software; see the source for copying conditions. "
5747 "This is free software; see the source for copying conditions. "
5695 "There is NO\nwarranty; "
5748 "There is NO\nwarranty; "
5696 "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
5749 "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
5697 ))
5750 ))
5698
5751
5699 norepo = ("clone init version help debugcommands debugcomplete"
5752 norepo = ("clone init version help debugcommands debugcomplete"
5700 " debugdate debuginstall debugfsinfo debugpushkey debugwireargs"
5753 " debugdate debuginstall debugfsinfo debugpushkey debugwireargs"
5701 " debugknown debuggetbundle debugbundle")
5754 " debugknown debuggetbundle debugbundle")
5702 optionalrepo = ("identify paths serve showconfig debugancestor debugdag"
5755 optionalrepo = ("identify paths serve showconfig debugancestor debugdag"
5703 " debugdata debugindex debugindexdot debugrevlog")
5756 " debugdata debugindex debugindexdot debugrevlog")
@@ -1,407 +1,410
1 $ "$TESTDIR/hghave" system-sh || exit 80
1 $ "$TESTDIR/hghave" system-sh || exit 80
2
2
3 $ HGFOO=BAR; export HGFOO
3 $ HGFOO=BAR; export HGFOO
4 $ cat >> $HGRCPATH <<EOF
4 $ cat >> $HGRCPATH <<EOF
5 > [extensions]
5 > [extensions]
6 > graphlog=
6 > graphlog=
7 >
7 >
8 > [alias]
8 > [alias]
9 > # should clobber ci but not commit (issue2993)
9 > # should clobber ci but not commit (issue2993)
10 > ci = version
10 > ci = version
11 > myinit = init
11 > myinit = init
12 > cleanstatus = status -c
12 > cleanstatus = status -c
13 > unknown = bargle
13 > unknown = bargle
14 > ambiguous = s
14 > ambiguous = s
15 > recursive = recursive
15 > recursive = recursive
16 > nodefinition =
16 > nodefinition =
17 > no--cwd = status --cwd elsewhere
17 > no--cwd = status --cwd elsewhere
18 > no-R = status -R elsewhere
18 > no-R = status -R elsewhere
19 > no--repo = status --repo elsewhere
19 > no--repo = status --repo elsewhere
20 > no--repository = status --repository elsewhere
20 > no--repository = status --repository elsewhere
21 > mylog = log
21 > mylog = log
22 > lognull = log -r null
22 > lognull = log -r null
23 > shortlog = log --template '{rev} {node|short} | {date|isodate}\n'
23 > shortlog = log --template '{rev} {node|short} | {date|isodate}\n'
24 > positional = log --template '{\$2} {\$1} | {date|isodate}\n'
24 > positional = log --template '{\$2} {\$1} | {date|isodate}\n'
25 > dln = lognull --debug
25 > dln = lognull --debug
26 > nousage = rollback
26 > nousage = rollback
27 > put = export -r 0 -o "\$FOO/%R.diff"
27 > put = export -r 0 -o "\$FOO/%R.diff"
28 > blank = !echo
28 > blank = !echo
29 > self = !echo '\$0'
29 > self = !echo '\$0'
30 > echo = !echo '\$@'
30 > echo = !echo '\$@'
31 > echo1 = !echo '\$1'
31 > echo1 = !echo '\$1'
32 > echo2 = !echo '\$2'
32 > echo2 = !echo '\$2'
33 > echo13 = !echo '\$1' '\$3'
33 > echo13 = !echo '\$1' '\$3'
34 > count = !hg log -r '\$@' --template='.' | wc -c | sed -e 's/ //g'
34 > count = !hg log -r '\$@' --template='.' | wc -c | sed -e 's/ //g'
35 > mcount = !hg log \$@ --template='.' | wc -c | sed -e 's/ //g'
35 > mcount = !hg log \$@ --template='.' | wc -c | sed -e 's/ //g'
36 > rt = root
36 > rt = root
37 > tglog = glog --template "{rev}:{node|short}: '{desc}' {branches}\n"
37 > tglog = glog --template "{rev}:{node|short}: '{desc}' {branches}\n"
38 > idalias = id
38 > idalias = id
39 > idaliaslong = id
39 > idaliaslong = id
40 > idaliasshell = !echo test
40 > idaliasshell = !echo test
41 > parentsshell1 = !echo one
41 > parentsshell1 = !echo one
42 > parentsshell2 = !echo two
42 > parentsshell2 = !echo two
43 > escaped1 = !echo 'test\$\$test'
43 > escaped1 = !echo 'test\$\$test'
44 > escaped2 = !echo "HGFOO is \$\$HGFOO"
44 > escaped2 = !echo "HGFOO is \$\$HGFOO"
45 > escaped3 = !echo "\$1 is \$\$\$1"
45 > escaped3 = !echo "\$1 is \$\$\$1"
46 > escaped4 = !echo '\$\$0' '\$\$@'
46 > escaped4 = !echo '\$\$0' '\$\$@'
47 >
47 >
48 > [defaults]
48 > [defaults]
49 > mylog = -q
49 > mylog = -q
50 > lognull = -q
50 > lognull = -q
51 > log = -v
51 > log = -v
52 > EOF
52 > EOF
53
53
54
54
55 basic
55 basic
56
56
57 $ hg myinit alias
57 $ hg myinit alias
58
58
59
59
60 unknown
60 unknown
61
61
62 $ hg unknown
62 $ hg unknown
63 alias 'unknown' resolves to unknown command 'bargle'
63 alias 'unknown' resolves to unknown command 'bargle'
64 $ hg help unknown
64 $ hg help unknown
65 alias 'unknown' resolves to unknown command 'bargle'
65 alias 'unknown' resolves to unknown command 'bargle'
66
66
67
67
68 ambiguous
68 ambiguous
69
69
70 $ hg ambiguous
70 $ hg ambiguous
71 alias 'ambiguous' resolves to ambiguous command 's'
71 alias 'ambiguous' resolves to ambiguous command 's'
72 $ hg help ambiguous
72 $ hg help ambiguous
73 alias 'ambiguous' resolves to ambiguous command 's'
73 alias 'ambiguous' resolves to ambiguous command 's'
74
74
75
75
76 recursive
76 recursive
77
77
78 $ hg recursive
78 $ hg recursive
79 alias 'recursive' resolves to unknown command 'recursive'
79 alias 'recursive' resolves to unknown command 'recursive'
80 $ hg help recursive
80 $ hg help recursive
81 alias 'recursive' resolves to unknown command 'recursive'
81 alias 'recursive' resolves to unknown command 'recursive'
82
82
83
83
84 no definition
84 no definition
85
85
86 $ hg nodef
86 $ hg nodef
87 no definition for alias 'nodefinition'
87 no definition for alias 'nodefinition'
88 $ hg help nodef
88 $ hg help nodef
89 no definition for alias 'nodefinition'
89 no definition for alias 'nodefinition'
90
90
91
91
92 invalid options
92 invalid options
93
93
94 $ hg no--cwd
94 $ hg no--cwd
95 error in definition for alias 'no--cwd': --cwd may only be given on the command line
95 error in definition for alias 'no--cwd': --cwd may only be given on the command line
96 $ hg help no--cwd
96 $ hg help no--cwd
97 error in definition for alias 'no--cwd': --cwd may only be given on the command line
97 error in definition for alias 'no--cwd': --cwd may only be given on the command line
98 $ hg no-R
98 $ hg no-R
99 error in definition for alias 'no-R': -R may only be given on the command line
99 error in definition for alias 'no-R': -R may only be given on the command line
100 $ hg help no-R
100 $ hg help no-R
101 error in definition for alias 'no-R': -R may only be given on the command line
101 error in definition for alias 'no-R': -R may only be given on the command line
102 $ hg no--repo
102 $ hg no--repo
103 error in definition for alias 'no--repo': --repo may only be given on the command line
103 error in definition for alias 'no--repo': --repo may only be given on the command line
104 $ hg help no--repo
104 $ hg help no--repo
105 error in definition for alias 'no--repo': --repo may only be given on the command line
105 error in definition for alias 'no--repo': --repo may only be given on the command line
106 $ hg no--repository
106 $ hg no--repository
107 error in definition for alias 'no--repository': --repository may only be given on the command line
107 error in definition for alias 'no--repository': --repository may only be given on the command line
108 $ hg help no--repository
108 $ hg help no--repository
109 error in definition for alias 'no--repository': --repository may only be given on the command line
109 error in definition for alias 'no--repository': --repository may only be given on the command line
110
110
111 $ cd alias
111 $ cd alias
112
112
113
113
114 no usage
114 no usage
115
115
116 $ hg nousage
116 $ hg nousage
117 no rollback information available
117 no rollback information available
118
118
119 $ echo foo > foo
119 $ echo foo > foo
120 $ hg commit -Amfoo
120 $ hg commit -Amfoo
121 adding foo
121 adding foo
122
122
123
123
124 with opts
124 with opts
125
125
126 $ hg cleanst
126 $ hg cleanst
127 C foo
127 C foo
128
128
129
129
130 with opts and whitespace
130 with opts and whitespace
131
131
132 $ hg shortlog
132 $ hg shortlog
133 0 e63c23eaa88a | 1970-01-01 00:00 +0000
133 0 e63c23eaa88a | 1970-01-01 00:00 +0000
134
134
135 positional arguments
135 positional arguments
136
136
137 $ hg positional 'node|short' rev
137 $ hg positional 'node|short' rev
138 0 e63c23eaa88a | 1970-01-01 00:00 +0000
138 0 e63c23eaa88a | 1970-01-01 00:00 +0000
139
139
140 interaction with defaults
140 interaction with defaults
141
141
142 $ hg mylog
142 $ hg mylog
143 0:e63c23eaa88a
143 0:e63c23eaa88a
144 $ hg lognull
144 $ hg lognull
145 -1:000000000000
145 -1:000000000000
146
146
147
147
148 properly recursive
148 properly recursive
149
149
150 $ hg dln
150 $ hg dln
151 changeset: -1:0000000000000000000000000000000000000000
151 changeset: -1:0000000000000000000000000000000000000000
152 parent: -1:0000000000000000000000000000000000000000
152 parent: -1:0000000000000000000000000000000000000000
153 parent: -1:0000000000000000000000000000000000000000
153 parent: -1:0000000000000000000000000000000000000000
154 manifest: -1:0000000000000000000000000000000000000000
154 manifest: -1:0000000000000000000000000000000000000000
155 user:
155 user:
156 date: Thu Jan 01 00:00:00 1970 +0000
156 date: Thu Jan 01 00:00:00 1970 +0000
157 extra: branch=default
157 extra: branch=default
158
158
159
159
160
160
161 path expanding
161 path expanding
162
162
163 $ FOO=`pwd` hg put
163 $ FOO=`pwd` hg put
164 $ cat 0.diff
164 $ cat 0.diff
165 # HG changeset patch
165 # HG changeset patch
166 # User test
166 # User test
167 # Date 0 0
167 # Date 0 0
168 # Node ID e63c23eaa88ae77967edcf4ea194d31167c478b0
168 # Node ID e63c23eaa88ae77967edcf4ea194d31167c478b0
169 # Parent 0000000000000000000000000000000000000000
169 # Parent 0000000000000000000000000000000000000000
170 foo
170 foo
171
171
172 diff -r 000000000000 -r e63c23eaa88a foo
172 diff -r 000000000000 -r e63c23eaa88a foo
173 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
173 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
174 +++ b/foo Thu Jan 01 00:00:00 1970 +0000
174 +++ b/foo Thu Jan 01 00:00:00 1970 +0000
175 @@ -0,0 +1,1 @@
175 @@ -0,0 +1,1 @@
176 +foo
176 +foo
177
177
178
178
179 simple shell aliases
179 simple shell aliases
180
180
181 $ hg blank
181 $ hg blank
182
182
183 $ hg blank foo
183 $ hg blank foo
184
184
185 $ hg self
185 $ hg self
186 self
186 self
187 $ hg echo
187 $ hg echo
188
188
189 $ hg echo foo
189 $ hg echo foo
190 foo
190 foo
191 $ hg echo 'test $2' foo
191 $ hg echo 'test $2' foo
192 test $2 foo
192 test $2 foo
193 $ hg echo1 foo bar baz
193 $ hg echo1 foo bar baz
194 foo
194 foo
195 $ hg echo2 foo bar baz
195 $ hg echo2 foo bar baz
196 bar
196 bar
197 $ hg echo13 foo bar baz test
197 $ hg echo13 foo bar baz test
198 foo baz
198 foo baz
199 $ hg echo2 foo
199 $ hg echo2 foo
200
200
201 $ echo bar > bar
201 $ echo bar > bar
202 $ hg commit -qA -m bar
202 $ hg commit -qA -m bar
203 $ hg count .
203 $ hg count .
204 1
204 1
205 $ hg count 'branch(default)'
205 $ hg count 'branch(default)'
206 2
206 2
207 $ hg mcount -r '"branch(default)"'
207 $ hg mcount -r '"branch(default)"'
208 2
208 2
209
209
210 $ hg tglog
210 $ hg tglog
211 @ 1:7e7f92de180e: 'bar'
211 @ 1:7e7f92de180e: 'bar'
212 |
212 |
213 o 0:e63c23eaa88a: 'foo'
213 o 0:e63c23eaa88a: 'foo'
214
214
215
215
216
216
217 shadowing
217 shadowing
218
218
219 $ hg i
219 $ hg i
220 hg: command 'i' is ambiguous:
220 hg: command 'i' is ambiguous:
221 idalias idaliaslong idaliasshell identify import incoming init
221 idalias idaliaslong idaliasshell identify import incoming init
222 [255]
222 [255]
223 $ hg id
223 $ hg id
224 7e7f92de180e tip
224 7e7f92de180e tip
225 $ hg ida
225 $ hg ida
226 hg: command 'ida' is ambiguous:
226 hg: command 'ida' is ambiguous:
227 idalias idaliaslong idaliasshell
227 idalias idaliaslong idaliasshell
228 [255]
228 [255]
229 $ hg idalias
229 $ hg idalias
230 7e7f92de180e tip
230 7e7f92de180e tip
231 $ hg idaliasl
231 $ hg idaliasl
232 7e7f92de180e tip
232 7e7f92de180e tip
233 $ hg idaliass
233 $ hg idaliass
234 test
234 test
235 $ hg parentsshell
235 $ hg parentsshell
236 hg: command 'parentsshell' is ambiguous:
236 hg: command 'parentsshell' is ambiguous:
237 parentsshell1 parentsshell2
237 parentsshell1 parentsshell2
238 [255]
238 [255]
239 $ hg parentsshell1
239 $ hg parentsshell1
240 one
240 one
241 $ hg parentsshell2
241 $ hg parentsshell2
242 two
242 two
243
243
244
244
245 shell aliases with global options
245 shell aliases with global options
246
246
247 $ hg init sub
247 $ hg init sub
248 $ cd sub
248 $ cd sub
249 $ hg count 'branch(default)'
249 $ hg count 'branch(default)'
250 0
250 0
251 $ hg -v count 'branch(default)'
251 $ hg -v count 'branch(default)'
252 0
252 0
253 $ hg -R .. count 'branch(default)'
253 $ hg -R .. count 'branch(default)'
254 0
254 0
255 $ hg --cwd .. count 'branch(default)'
255 $ hg --cwd .. count 'branch(default)'
256 2
256 2
257 $ hg echo --cwd ..
257 $ hg echo --cwd ..
258
258
259
259
260
260
261 repo specific shell aliases
261 repo specific shell aliases
262
262
263 $ cat >> .hg/hgrc <<EOF
263 $ cat >> .hg/hgrc <<EOF
264 > [alias]
264 > [alias]
265 > subalias = !echo sub \$@
265 > subalias = !echo sub \$@
266 > EOF
266 > EOF
267 $ cat >> ../.hg/hgrc <<EOF
267 $ cat >> ../.hg/hgrc <<EOF
268 > [alias]
268 > [alias]
269 > mainalias = !echo main \$@
269 > mainalias = !echo main \$@
270 > EOF
270 > EOF
271
271
272
272
273 shell alias defined in current repo
273 shell alias defined in current repo
274
274
275 $ hg subalias
275 $ hg subalias
276 sub
276 sub
277 $ hg --cwd .. subalias > /dev/null
277 $ hg --cwd .. subalias > /dev/null
278 hg: unknown command 'subalias'
278 hg: unknown command 'subalias'
279 [255]
279 [255]
280 $ hg -R .. subalias > /dev/null
280 $ hg -R .. subalias > /dev/null
281 hg: unknown command 'subalias'
281 hg: unknown command 'subalias'
282 [255]
282 [255]
283
283
284
284
285 shell alias defined in other repo
285 shell alias defined in other repo
286
286
287 $ hg mainalias > /dev/null
287 $ hg mainalias > /dev/null
288 hg: unknown command 'mainalias'
288 hg: unknown command 'mainalias'
289 [255]
289 [255]
290 $ hg -R .. mainalias
290 $ hg -R .. mainalias
291 main
291 main
292 $ hg --cwd .. mainalias
292 $ hg --cwd .. mainalias
293 main
293 main
294
294
295
295
296 shell aliases with escaped $ chars
296 shell aliases with escaped $ chars
297
297
298 $ hg escaped1
298 $ hg escaped1
299 test$test
299 test$test
300 $ hg escaped2
300 $ hg escaped2
301 HGFOO is BAR
301 HGFOO is BAR
302 $ hg escaped3 HGFOO
302 $ hg escaped3 HGFOO
303 HGFOO is BAR
303 HGFOO is BAR
304 $ hg escaped4 test
304 $ hg escaped4 test
305 $0 $@
305 $0 $@
306
306
307
307
308 invalid arguments
308 invalid arguments
309
309
310 $ hg rt foo
310 $ hg rt foo
311 hg rt: invalid arguments
311 hg rt: invalid arguments
312 hg rt
312 hg rt
313
313
314 alias for: hg root
314 alias for: hg root
315
315
316 use "hg help rt" to show the full help text
316 use "hg help rt" to show the full help text
317 [255]
317 [255]
318
318
319 invalid global arguments for normal commands, aliases, and shell aliases
319 invalid global arguments for normal commands, aliases, and shell aliases
320
320
321 $ hg --invalid root
321 $ hg --invalid root
322 hg: option --invalid not recognized
322 hg: option --invalid not recognized
323 Mercurial Distributed SCM
323 Mercurial Distributed SCM
324
324
325 basic commands:
325 basic commands:
326
326
327 add add the specified files on the next commit
327 add add the specified files on the next commit
328 annotate show changeset information by line for each file
328 annotate show changeset information by line for each file
329 clone make a copy of an existing repository
329 clone make a copy of an existing repository
330 commit commit the specified files or all outstanding changes
330 commit commit the specified files or all outstanding changes
331 diff diff repository (or selected files)
331 diff diff repository (or selected files)
332 export dump the header and diffs for one or more changesets
332 export dump the header and diffs for one or more changesets
333 forget forget the specified files on the next commit
333 forget forget the specified files on the next commit
334 init create a new repository in the given directory
334 init create a new repository in the given directory
335 log show revision history of entire repository or files
335 log show revision history of entire repository or files
336 merge merge working directory with another revision
336 merge merge working directory with another revision
337 phase set or show the current phase name
337 pull pull changes from the specified source
338 pull pull changes from the specified source
338 push push changes to the specified destination
339 push push changes to the specified destination
339 remove remove the specified files on the next commit
340 remove remove the specified files on the next commit
340 serve start stand-alone webserver
341 serve start stand-alone webserver
341 status show changed files in the working directory
342 status show changed files in the working directory
342 summary summarize working directory state
343 summary summarize working directory state
343 update update working directory (or switch revisions)
344 update update working directory (or switch revisions)
344
345
345 use "hg help" for the full list of commands or "hg -v" for details
346 use "hg help" for the full list of commands or "hg -v" for details
346 [255]
347 [255]
347 $ hg --invalid mylog
348 $ hg --invalid mylog
348 hg: option --invalid not recognized
349 hg: option --invalid not recognized
349 Mercurial Distributed SCM
350 Mercurial Distributed SCM
350
351
351 basic commands:
352 basic commands:
352
353
353 add add the specified files on the next commit
354 add add the specified files on the next commit
354 annotate show changeset information by line for each file
355 annotate show changeset information by line for each file
355 clone make a copy of an existing repository
356 clone make a copy of an existing repository
356 commit commit the specified files or all outstanding changes
357 commit commit the specified files or all outstanding changes
357 diff diff repository (or selected files)
358 diff diff repository (or selected files)
358 export dump the header and diffs for one or more changesets
359 export dump the header and diffs for one or more changesets
359 forget forget the specified files on the next commit
360 forget forget the specified files on the next commit
360 init create a new repository in the given directory
361 init create a new repository in the given directory
361 log show revision history of entire repository or files
362 log show revision history of entire repository or files
362 merge merge working directory with another revision
363 merge merge working directory with another revision
364 phase set or show the current phase name
363 pull pull changes from the specified source
365 pull pull changes from the specified source
364 push push changes to the specified destination
366 push push changes to the specified destination
365 remove remove the specified files on the next commit
367 remove remove the specified files on the next commit
366 serve start stand-alone webserver
368 serve start stand-alone webserver
367 status show changed files in the working directory
369 status show changed files in the working directory
368 summary summarize working directory state
370 summary summarize working directory state
369 update update working directory (or switch revisions)
371 update update working directory (or switch revisions)
370
372
371 use "hg help" for the full list of commands or "hg -v" for details
373 use "hg help" for the full list of commands or "hg -v" for details
372 [255]
374 [255]
373 $ hg --invalid blank
375 $ hg --invalid blank
374 hg: option --invalid not recognized
376 hg: option --invalid not recognized
375 Mercurial Distributed SCM
377 Mercurial Distributed SCM
376
378
377 basic commands:
379 basic commands:
378
380
379 add add the specified files on the next commit
381 add add the specified files on the next commit
380 annotate show changeset information by line for each file
382 annotate show changeset information by line for each file
381 clone make a copy of an existing repository
383 clone make a copy of an existing repository
382 commit commit the specified files or all outstanding changes
384 commit commit the specified files or all outstanding changes
383 diff diff repository (or selected files)
385 diff diff repository (or selected files)
384 export dump the header and diffs for one or more changesets
386 export dump the header and diffs for one or more changesets
385 forget forget the specified files on the next commit
387 forget forget the specified files on the next commit
386 init create a new repository in the given directory
388 init create a new repository in the given directory
387 log show revision history of entire repository or files
389 log show revision history of entire repository or files
388 merge merge working directory with another revision
390 merge merge working directory with another revision
391 phase set or show the current phase name
389 pull pull changes from the specified source
392 pull pull changes from the specified source
390 push push changes to the specified destination
393 push push changes to the specified destination
391 remove remove the specified files on the next commit
394 remove remove the specified files on the next commit
392 serve start stand-alone webserver
395 serve start stand-alone webserver
393 status show changed files in the working directory
396 status show changed files in the working directory
394 summary summarize working directory state
397 summary summarize working directory state
395 update update working directory (or switch revisions)
398 update update working directory (or switch revisions)
396
399
397 use "hg help" for the full list of commands or "hg -v" for details
400 use "hg help" for the full list of commands or "hg -v" for details
398 [255]
401 [255]
399
402
400 This should show id:
403 This should show id:
401
404
402 $ hg --config alias.log='id' log
405 $ hg --config alias.log='id' log
403 000000000000 tip
406 000000000000 tip
404
407
405 This shouldn't:
408 This shouldn't:
406
409
407 $ hg --config alias.log='id' history
410 $ hg --config alias.log='id' history
@@ -1,119 +1,120
1
1
2 testing hellomessage:
2 testing hellomessage:
3
3
4 o, 'capabilities: getencoding runcommand\nencoding: ***'
4 o, 'capabilities: getencoding runcommand\nencoding: ***'
5 runcommand id
5 runcommand id
6 000000000000 tip
6 000000000000 tip
7 abort: unknown command unknowncommand
7 abort: unknown command unknowncommand
8
8
9 testing unknowncommand:
9 testing unknowncommand:
10
10
11
11
12 testing checkruncommand:
12 testing checkruncommand:
13
13
14 runcommand
14 runcommand
15 Mercurial Distributed SCM
15 Mercurial Distributed SCM
16
16
17 basic commands:
17 basic commands:
18
18
19 add add the specified files on the next commit
19 add add the specified files on the next commit
20 annotate show changeset information by line for each file
20 annotate show changeset information by line for each file
21 clone make a copy of an existing repository
21 clone make a copy of an existing repository
22 commit commit the specified files or all outstanding changes
22 commit commit the specified files or all outstanding changes
23 diff diff repository (or selected files)
23 diff diff repository (or selected files)
24 export dump the header and diffs for one or more changesets
24 export dump the header and diffs for one or more changesets
25 forget forget the specified files on the next commit
25 forget forget the specified files on the next commit
26 init create a new repository in the given directory
26 init create a new repository in the given directory
27 log show revision history of entire repository or files
27 log show revision history of entire repository or files
28 merge merge working directory with another revision
28 merge merge working directory with another revision
29 phase set or show the current phase name
29 pull pull changes from the specified source
30 pull pull changes from the specified source
30 push push changes to the specified destination
31 push push changes to the specified destination
31 remove remove the specified files on the next commit
32 remove remove the specified files on the next commit
32 serve start stand-alone webserver
33 serve start stand-alone webserver
33 status show changed files in the working directory
34 status show changed files in the working directory
34 summary summarize working directory state
35 summary summarize working directory state
35 update update working directory (or switch revisions)
36 update update working directory (or switch revisions)
36
37
37 use "hg help" for the full list of commands or "hg -v" for details
38 use "hg help" for the full list of commands or "hg -v" for details
38 runcommand id --quiet
39 runcommand id --quiet
39 000000000000
40 000000000000
40 runcommand id
41 runcommand id
41 000000000000 tip
42 000000000000 tip
42 runcommand id --config ui.quiet=True
43 runcommand id --config ui.quiet=True
43 000000000000
44 000000000000
44 runcommand id
45 runcommand id
45 000000000000 tip
46 000000000000 tip
46
47
47 testing inputeof:
48 testing inputeof:
48
49
49 server exit code = 1
50 server exit code = 1
50
51
51 testing serverinput:
52 testing serverinput:
52
53
53 runcommand import -
54 runcommand import -
54 applying patch from stdin
55 applying patch from stdin
55 runcommand log
56 runcommand log
56 changeset: 0:eff892de26ec
57 changeset: 0:eff892de26ec
57 tag: tip
58 tag: tip
58 user: test
59 user: test
59 date: Thu Jan 01 00:00:00 1970 +0000
60 date: Thu Jan 01 00:00:00 1970 +0000
60 summary: 1
61 summary: 1
61
62
62
63
63 testing cwd:
64 testing cwd:
64
65
65 runcommand --cwd foo st bar
66 runcommand --cwd foo st bar
66 ? bar
67 ? bar
67 runcommand st foo/bar
68 runcommand st foo/bar
68 ? foo/bar
69 ? foo/bar
69
70
70 testing localhgrc:
71 testing localhgrc:
71
72
72 runcommand showconfig
73 runcommand showconfig
73 bundle.mainreporoot=$TESTTMP
74 bundle.mainreporoot=$TESTTMP
74 defaults.backout=-d "0 0"
75 defaults.backout=-d "0 0"
75 defaults.commit=-d "0 0"
76 defaults.commit=-d "0 0"
76 defaults.tag=-d "0 0"
77 defaults.tag=-d "0 0"
77 ui.slash=True
78 ui.slash=True
78 ui.foo=bar
79 ui.foo=bar
79 runcommand init foo
80 runcommand init foo
80 runcommand -R foo showconfig ui defaults
81 runcommand -R foo showconfig ui defaults
81 defaults.backout=-d "0 0"
82 defaults.backout=-d "0 0"
82 defaults.commit=-d "0 0"
83 defaults.commit=-d "0 0"
83 defaults.tag=-d "0 0"
84 defaults.tag=-d "0 0"
84 ui.slash=True
85 ui.slash=True
85
86
86 testing hookoutput:
87 testing hookoutput:
87
88
88 runcommand --config hooks.pre-identify=python:test-commandserver.hook id
89 runcommand --config hooks.pre-identify=python:test-commandserver.hook id
89 hook talking
90 hook talking
90 now try to read something: 'some input'
91 now try to read something: 'some input'
91 eff892de26ec tip
92 eff892de26ec tip
92
93
93 testing outsidechanges:
94 testing outsidechanges:
94
95
95 runcommand tip
96 runcommand tip
96 changeset: 1:d3a0a68be6de
97 changeset: 1:d3a0a68be6de
97 tag: tip
98 tag: tip
98 user: test
99 user: test
99 date: Thu Jan 01 00:00:00 1970 +0000
100 date: Thu Jan 01 00:00:00 1970 +0000
100 summary: 2
101 summary: 2
101
102
102
103
103 testing bookmarks:
104 testing bookmarks:
104
105
105 runcommand bookmarks
106 runcommand bookmarks
106 no bookmarks set
107 no bookmarks set
107 runcommand bookmarks
108 runcommand bookmarks
108 bm1 1:d3a0a68be6de
109 bm1 1:d3a0a68be6de
109 bm2 1:d3a0a68be6de
110 bm2 1:d3a0a68be6de
110 runcommand bookmarks
111 runcommand bookmarks
111 * bm1 1:d3a0a68be6de
112 * bm1 1:d3a0a68be6de
112 bm2 1:d3a0a68be6de
113 bm2 1:d3a0a68be6de
113
114
114 testing tagscache:
115 testing tagscache:
115
116
116 runcommand id -t -r 0
117 runcommand id -t -r 0
117
118
118 runcommand id -t -r 0
119 runcommand id -t -r 0
119 foo
120 foo
@@ -1,270 +1,272
1 Show all commands except debug commands
1 Show all commands except debug commands
2 $ hg debugcomplete
2 $ hg debugcomplete
3 add
3 add
4 addremove
4 addremove
5 annotate
5 annotate
6 archive
6 archive
7 backout
7 backout
8 bisect
8 bisect
9 bookmarks
9 bookmarks
10 branch
10 branch
11 branches
11 branches
12 bundle
12 bundle
13 cat
13 cat
14 clone
14 clone
15 commit
15 commit
16 copy
16 copy
17 diff
17 diff
18 export
18 export
19 forget
19 forget
20 graft
20 graft
21 grep
21 grep
22 heads
22 heads
23 help
23 help
24 identify
24 identify
25 import
25 import
26 incoming
26 incoming
27 init
27 init
28 locate
28 locate
29 log
29 log
30 manifest
30 manifest
31 merge
31 merge
32 outgoing
32 outgoing
33 parents
33 parents
34 paths
34 paths
35 phase
35 pull
36 pull
36 push
37 push
37 recover
38 recover
38 remove
39 remove
39 rename
40 rename
40 resolve
41 resolve
41 revert
42 revert
42 rollback
43 rollback
43 root
44 root
44 serve
45 serve
45 showconfig
46 showconfig
46 status
47 status
47 summary
48 summary
48 tag
49 tag
49 tags
50 tags
50 tip
51 tip
51 unbundle
52 unbundle
52 update
53 update
53 verify
54 verify
54 version
55 version
55
56
56 Show all commands that start with "a"
57 Show all commands that start with "a"
57 $ hg debugcomplete a
58 $ hg debugcomplete a
58 add
59 add
59 addremove
60 addremove
60 annotate
61 annotate
61 archive
62 archive
62
63
63 Do not show debug commands if there are other candidates
64 Do not show debug commands if there are other candidates
64 $ hg debugcomplete d
65 $ hg debugcomplete d
65 diff
66 diff
66
67
67 Show debug commands if there are no other candidates
68 Show debug commands if there are no other candidates
68 $ hg debugcomplete debug
69 $ hg debugcomplete debug
69 debugancestor
70 debugancestor
70 debugbuilddag
71 debugbuilddag
71 debugbundle
72 debugbundle
72 debugcheckstate
73 debugcheckstate
73 debugcommands
74 debugcommands
74 debugcomplete
75 debugcomplete
75 debugconfig
76 debugconfig
76 debugdag
77 debugdag
77 debugdata
78 debugdata
78 debugdate
79 debugdate
79 debugdiscovery
80 debugdiscovery
80 debugfileset
81 debugfileset
81 debugfsinfo
82 debugfsinfo
82 debuggetbundle
83 debuggetbundle
83 debugignore
84 debugignore
84 debugindex
85 debugindex
85 debugindexdot
86 debugindexdot
86 debuginstall
87 debuginstall
87 debugknown
88 debugknown
88 debugpushkey
89 debugpushkey
89 debugrebuildstate
90 debugrebuildstate
90 debugrename
91 debugrename
91 debugrevlog
92 debugrevlog
92 debugrevspec
93 debugrevspec
93 debugsetparents
94 debugsetparents
94 debugstate
95 debugstate
95 debugsub
96 debugsub
96 debugwalk
97 debugwalk
97 debugwireargs
98 debugwireargs
98
99
99 Do not show the alias of a debug command if there are other candidates
100 Do not show the alias of a debug command if there are other candidates
100 (this should hide rawcommit)
101 (this should hide rawcommit)
101 $ hg debugcomplete r
102 $ hg debugcomplete r
102 recover
103 recover
103 remove
104 remove
104 rename
105 rename
105 resolve
106 resolve
106 revert
107 revert
107 rollback
108 rollback
108 root
109 root
109 Show the alias of a debug command if there are no other candidates
110 Show the alias of a debug command if there are no other candidates
110 $ hg debugcomplete rawc
111 $ hg debugcomplete rawc
111
112
112
113
113 Show the global options
114 Show the global options
114 $ hg debugcomplete --options | sort
115 $ hg debugcomplete --options | sort
115 --config
116 --config
116 --cwd
117 --cwd
117 --debug
118 --debug
118 --debugger
119 --debugger
119 --encoding
120 --encoding
120 --encodingmode
121 --encodingmode
121 --help
122 --help
122 --noninteractive
123 --noninteractive
123 --profile
124 --profile
124 --quiet
125 --quiet
125 --repository
126 --repository
126 --time
127 --time
127 --traceback
128 --traceback
128 --verbose
129 --verbose
129 --version
130 --version
130 -R
131 -R
131 -h
132 -h
132 -q
133 -q
133 -v
134 -v
134 -y
135 -y
135
136
136 Show the options for the "serve" command
137 Show the options for the "serve" command
137 $ hg debugcomplete --options serve | sort
138 $ hg debugcomplete --options serve | sort
138 --accesslog
139 --accesslog
139 --address
140 --address
140 --certificate
141 --certificate
141 --cmdserver
142 --cmdserver
142 --config
143 --config
143 --cwd
144 --cwd
144 --daemon
145 --daemon
145 --daemon-pipefds
146 --daemon-pipefds
146 --debug
147 --debug
147 --debugger
148 --debugger
148 --encoding
149 --encoding
149 --encodingmode
150 --encodingmode
150 --errorlog
151 --errorlog
151 --help
152 --help
152 --ipv6
153 --ipv6
153 --name
154 --name
154 --noninteractive
155 --noninteractive
155 --pid-file
156 --pid-file
156 --port
157 --port
157 --prefix
158 --prefix
158 --profile
159 --profile
159 --quiet
160 --quiet
160 --repository
161 --repository
161 --stdio
162 --stdio
162 --style
163 --style
163 --templates
164 --templates
164 --time
165 --time
165 --traceback
166 --traceback
166 --verbose
167 --verbose
167 --version
168 --version
168 --web-conf
169 --web-conf
169 -6
170 -6
170 -A
171 -A
171 -E
172 -E
172 -R
173 -R
173 -a
174 -a
174 -d
175 -d
175 -h
176 -h
176 -n
177 -n
177 -p
178 -p
178 -q
179 -q
179 -t
180 -t
180 -v
181 -v
181 -y
182 -y
182
183
183 Show an error if we use --options with an ambiguous abbreviation
184 Show an error if we use --options with an ambiguous abbreviation
184 $ hg debugcomplete --options s
185 $ hg debugcomplete --options s
185 hg: command 's' is ambiguous:
186 hg: command 's' is ambiguous:
186 serve showconfig status summary
187 serve showconfig status summary
187 [255]
188 [255]
188
189
189 Show all commands + options
190 Show all commands + options
190 $ hg debugcommands
191 $ hg debugcommands
191 add: include, exclude, subrepos, dry-run
192 add: include, exclude, subrepos, dry-run
192 annotate: rev, follow, no-follow, text, user, file, date, number, changeset, line-number, ignore-all-space, ignore-space-change, ignore-blank-lines, include, exclude
193 annotate: rev, follow, no-follow, text, user, file, date, number, changeset, line-number, ignore-all-space, ignore-space-change, ignore-blank-lines, include, exclude
193 clone: noupdate, updaterev, rev, branch, pull, uncompressed, ssh, remotecmd, insecure
194 clone: noupdate, updaterev, rev, branch, pull, uncompressed, ssh, remotecmd, insecure
194 commit: addremove, close-branch, include, exclude, message, logfile, date, user, subrepos
195 commit: addremove, close-branch, include, exclude, message, logfile, date, user, subrepos
195 diff: rev, change, text, git, nodates, show-function, reverse, ignore-all-space, ignore-space-change, ignore-blank-lines, unified, stat, include, exclude, subrepos
196 diff: rev, change, text, git, nodates, show-function, reverse, ignore-all-space, ignore-space-change, ignore-blank-lines, unified, stat, include, exclude, subrepos
196 export: output, switch-parent, rev, text, git, nodates
197 export: output, switch-parent, rev, text, git, nodates
197 forget: include, exclude
198 forget: include, exclude
198 init: ssh, remotecmd, insecure
199 init: ssh, remotecmd, insecure
199 log: follow, follow-first, date, copies, keyword, rev, removed, only-merges, user, only-branch, branch, prune, hidden, patch, git, limit, no-merges, stat, style, template, include, exclude
200 log: follow, follow-first, date, copies, keyword, rev, removed, only-merges, user, only-branch, branch, prune, hidden, patch, git, limit, no-merges, stat, style, template, include, exclude
200 merge: force, rev, preview, tool
201 merge: force, rev, preview, tool
202 phase: public, draft, secret, force, rev
201 pull: update, force, rev, bookmark, branch, ssh, remotecmd, insecure
203 pull: update, force, rev, bookmark, branch, ssh, remotecmd, insecure
202 push: force, rev, bookmark, branch, new-branch, ssh, remotecmd, insecure
204 push: force, rev, bookmark, branch, new-branch, ssh, remotecmd, insecure
203 remove: after, force, include, exclude
205 remove: after, force, include, exclude
204 serve: accesslog, daemon, daemon-pipefds, errorlog, port, address, prefix, name, web-conf, webdir-conf, pid-file, stdio, cmdserver, templates, style, ipv6, certificate
206 serve: accesslog, daemon, daemon-pipefds, errorlog, port, address, prefix, name, web-conf, webdir-conf, pid-file, stdio, cmdserver, templates, style, ipv6, certificate
205 status: all, modified, added, removed, deleted, clean, unknown, ignored, no-status, copies, print0, rev, change, include, exclude, subrepos
207 status: all, modified, added, removed, deleted, clean, unknown, ignored, no-status, copies, print0, rev, change, include, exclude, subrepos
206 summary: remote
208 summary: remote
207 update: clean, check, date, rev
209 update: clean, check, date, rev
208 addremove: similarity, include, exclude, dry-run
210 addremove: similarity, include, exclude, dry-run
209 archive: no-decode, prefix, rev, type, subrepos, include, exclude
211 archive: no-decode, prefix, rev, type, subrepos, include, exclude
210 backout: merge, parent, rev, tool, include, exclude, message, logfile, date, user
212 backout: merge, parent, rev, tool, include, exclude, message, logfile, date, user
211 bisect: reset, good, bad, skip, extend, command, noupdate
213 bisect: reset, good, bad, skip, extend, command, noupdate
212 bookmarks: force, rev, delete, rename, inactive
214 bookmarks: force, rev, delete, rename, inactive
213 branch: force, clean
215 branch: force, clean
214 branches: active, closed
216 branches: active, closed
215 bundle: force, rev, branch, base, all, type, ssh, remotecmd, insecure
217 bundle: force, rev, branch, base, all, type, ssh, remotecmd, insecure
216 cat: output, rev, decode, include, exclude
218 cat: output, rev, decode, include, exclude
217 copy: after, force, include, exclude, dry-run
219 copy: after, force, include, exclude, dry-run
218 debugancestor:
220 debugancestor:
219 debugbuilddag: mergeable-file, overwritten-file, new-file
221 debugbuilddag: mergeable-file, overwritten-file, new-file
220 debugbundle: all
222 debugbundle: all
221 debugcheckstate:
223 debugcheckstate:
222 debugcommands:
224 debugcommands:
223 debugcomplete: options
225 debugcomplete: options
224 debugdag: tags, branches, dots, spaces
226 debugdag: tags, branches, dots, spaces
225 debugdata: changelog, manifest
227 debugdata: changelog, manifest
226 debugdate: extended
228 debugdate: extended
227 debugdiscovery: old, nonheads, ssh, remotecmd, insecure
229 debugdiscovery: old, nonheads, ssh, remotecmd, insecure
228 debugfileset:
230 debugfileset:
229 debugfsinfo:
231 debugfsinfo:
230 debuggetbundle: head, common, type
232 debuggetbundle: head, common, type
231 debugignore:
233 debugignore:
232 debugindex: changelog, manifest, format
234 debugindex: changelog, manifest, format
233 debugindexdot:
235 debugindexdot:
234 debuginstall:
236 debuginstall:
235 debugknown:
237 debugknown:
236 debugpushkey:
238 debugpushkey:
237 debugrebuildstate: rev
239 debugrebuildstate: rev
238 debugrename: rev
240 debugrename: rev
239 debugrevlog: changelog, manifest, dump
241 debugrevlog: changelog, manifest, dump
240 debugrevspec:
242 debugrevspec:
241 debugsetparents:
243 debugsetparents:
242 debugstate: nodates, datesort
244 debugstate: nodates, datesort
243 debugsub: rev
245 debugsub: rev
244 debugwalk: include, exclude
246 debugwalk: include, exclude
245 debugwireargs: three, four, five, ssh, remotecmd, insecure
247 debugwireargs: three, four, five, ssh, remotecmd, insecure
246 graft: continue, edit, currentdate, currentuser, date, user, tool
248 graft: continue, edit, currentdate, currentuser, date, user, tool
247 grep: print0, all, text, follow, ignore-case, files-with-matches, line-number, rev, user, date, include, exclude
249 grep: print0, all, text, follow, ignore-case, files-with-matches, line-number, rev, user, date, include, exclude
248 heads: rev, topo, active, closed, style, template
250 heads: rev, topo, active, closed, style, template
249 help: extension, command
251 help: extension, command
250 identify: rev, num, id, branch, tags, bookmarks, ssh, remotecmd, insecure
252 identify: rev, num, id, branch, tags, bookmarks, ssh, remotecmd, insecure
251 import: strip, base, edit, force, no-commit, bypass, exact, import-branch, message, logfile, date, user, similarity
253 import: strip, base, edit, force, no-commit, bypass, exact, import-branch, message, logfile, date, user, similarity
252 incoming: force, newest-first, bundle, rev, bookmarks, branch, patch, git, limit, no-merges, stat, style, template, ssh, remotecmd, insecure, subrepos
254 incoming: force, newest-first, bundle, rev, bookmarks, branch, patch, git, limit, no-merges, stat, style, template, ssh, remotecmd, insecure, subrepos
253 locate: rev, print0, fullpath, include, exclude
255 locate: rev, print0, fullpath, include, exclude
254 manifest: rev, all
256 manifest: rev, all
255 outgoing: force, rev, newest-first, bookmarks, branch, patch, git, limit, no-merges, stat, style, template, ssh, remotecmd, insecure, subrepos
257 outgoing: force, rev, newest-first, bookmarks, branch, patch, git, limit, no-merges, stat, style, template, ssh, remotecmd, insecure, subrepos
256 parents: rev, style, template
258 parents: rev, style, template
257 paths:
259 paths:
258 recover:
260 recover:
259 rename: after, force, include, exclude, dry-run
261 rename: after, force, include, exclude, dry-run
260 resolve: all, list, mark, unmark, no-status, tool, include, exclude
262 resolve: all, list, mark, unmark, no-status, tool, include, exclude
261 revert: all, date, rev, no-backup, include, exclude, dry-run
263 revert: all, date, rev, no-backup, include, exclude, dry-run
262 rollback: dry-run, force
264 rollback: dry-run, force
263 root:
265 root:
264 showconfig: untrusted
266 showconfig: untrusted
265 tag: force, local, rev, remove, edit, message, date, user
267 tag: force, local, rev, remove, edit, message, date, user
266 tags:
268 tags:
267 tip: patch, git, style, template
269 tip: patch, git, style, template
268 unbundle: update
270 unbundle: update
269 verify:
271 verify:
270 version:
272 version:
@@ -1,440 +1,442
1 $ "$TESTDIR/hghave" no-outer-repo || exit 80
1 $ "$TESTDIR/hghave" no-outer-repo || exit 80
2
2
3 $ hg init a
3 $ hg init a
4 $ cd a
4 $ cd a
5 $ echo a > a
5 $ echo a > a
6 $ hg ci -A -d'1 0' -m a
6 $ hg ci -A -d'1 0' -m a
7 adding a
7 adding a
8
8
9 $ cd ..
9 $ cd ..
10
10
11 $ hg init b
11 $ hg init b
12 $ cd b
12 $ cd b
13 $ echo b > b
13 $ echo b > b
14 $ hg ci -A -d'1 0' -m b
14 $ hg ci -A -d'1 0' -m b
15 adding b
15 adding b
16
16
17 $ cd ..
17 $ cd ..
18
18
19 $ hg clone a c
19 $ hg clone a c
20 updating to branch default
20 updating to branch default
21 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
21 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
22 $ cd c
22 $ cd c
23 $ cat >> .hg/hgrc <<EOF
23 $ cat >> .hg/hgrc <<EOF
24 > [paths]
24 > [paths]
25 > relative = ../a
25 > relative = ../a
26 > EOF
26 > EOF
27 $ hg pull -f ../b
27 $ hg pull -f ../b
28 pulling from ../b
28 pulling from ../b
29 searching for changes
29 searching for changes
30 warning: repository is unrelated
30 warning: repository is unrelated
31 requesting all changes
31 requesting all changes
32 adding changesets
32 adding changesets
33 adding manifests
33 adding manifests
34 adding file changes
34 adding file changes
35 added 1 changesets with 1 changes to 1 files (+1 heads)
35 added 1 changesets with 1 changes to 1 files (+1 heads)
36 (run 'hg heads' to see heads, 'hg merge' to merge)
36 (run 'hg heads' to see heads, 'hg merge' to merge)
37 $ hg merge
37 $ hg merge
38 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
38 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
39 (branch merge, don't forget to commit)
39 (branch merge, don't forget to commit)
40
40
41 $ cd ..
41 $ cd ..
42
42
43 Testing -R/--repository:
43 Testing -R/--repository:
44
44
45 $ hg -R a tip
45 $ hg -R a tip
46 changeset: 0:8580ff50825a
46 changeset: 0:8580ff50825a
47 tag: tip
47 tag: tip
48 user: test
48 user: test
49 date: Thu Jan 01 00:00:01 1970 +0000
49 date: Thu Jan 01 00:00:01 1970 +0000
50 summary: a
50 summary: a
51
51
52 $ hg --repository b tip
52 $ hg --repository b tip
53 changeset: 0:b6c483daf290
53 changeset: 0:b6c483daf290
54 tag: tip
54 tag: tip
55 user: test
55 user: test
56 date: Thu Jan 01 00:00:01 1970 +0000
56 date: Thu Jan 01 00:00:01 1970 +0000
57 summary: b
57 summary: b
58
58
59
59
60 -R with a URL:
60 -R with a URL:
61
61
62 $ hg -R file:a identify
62 $ hg -R file:a identify
63 8580ff50825a tip
63 8580ff50825a tip
64 $ hg -R file://localhost/`pwd`/a/ identify
64 $ hg -R file://localhost/`pwd`/a/ identify
65 8580ff50825a tip
65 8580ff50825a tip
66
66
67 -R with path aliases:
67 -R with path aliases:
68
68
69 $ cd c
69 $ cd c
70 $ hg -R default identify
70 $ hg -R default identify
71 8580ff50825a tip
71 8580ff50825a tip
72 $ hg -R relative identify
72 $ hg -R relative identify
73 8580ff50825a tip
73 8580ff50825a tip
74 $ echo '[paths]' >> $HGRCPATH
74 $ echo '[paths]' >> $HGRCPATH
75 $ echo 'relativetohome = a' >> $HGRCPATH
75 $ echo 'relativetohome = a' >> $HGRCPATH
76 $ HOME=`pwd`/../ hg -R relativetohome identify
76 $ HOME=`pwd`/../ hg -R relativetohome identify
77 8580ff50825a tip
77 8580ff50825a tip
78 $ cd ..
78 $ cd ..
79
79
80 Implicit -R:
80 Implicit -R:
81
81
82 $ hg ann a/a
82 $ hg ann a/a
83 0: a
83 0: a
84 $ hg ann a/a a/a
84 $ hg ann a/a a/a
85 0: a
85 0: a
86 $ hg ann a/a b/b
86 $ hg ann a/a b/b
87 abort: no repository found in '$TESTTMP' (.hg not found)!
87 abort: no repository found in '$TESTTMP' (.hg not found)!
88 [255]
88 [255]
89 $ hg -R b ann a/a
89 $ hg -R b ann a/a
90 abort: a/a not under root
90 abort: a/a not under root
91 [255]
91 [255]
92 $ hg log
92 $ hg log
93 abort: no repository found in '$TESTTMP' (.hg not found)!
93 abort: no repository found in '$TESTTMP' (.hg not found)!
94 [255]
94 [255]
95
95
96 Abbreviation of long option:
96 Abbreviation of long option:
97
97
98 $ hg --repo c tip
98 $ hg --repo c tip
99 changeset: 1:b6c483daf290
99 changeset: 1:b6c483daf290
100 tag: tip
100 tag: tip
101 parent: -1:000000000000
101 parent: -1:000000000000
102 user: test
102 user: test
103 date: Thu Jan 01 00:00:01 1970 +0000
103 date: Thu Jan 01 00:00:01 1970 +0000
104 summary: b
104 summary: b
105
105
106
106
107 earlygetopt with duplicate options (36d23de02da1):
107 earlygetopt with duplicate options (36d23de02da1):
108
108
109 $ hg --cwd a --cwd b --cwd c tip
109 $ hg --cwd a --cwd b --cwd c tip
110 changeset: 1:b6c483daf290
110 changeset: 1:b6c483daf290
111 tag: tip
111 tag: tip
112 parent: -1:000000000000
112 parent: -1:000000000000
113 user: test
113 user: test
114 date: Thu Jan 01 00:00:01 1970 +0000
114 date: Thu Jan 01 00:00:01 1970 +0000
115 summary: b
115 summary: b
116
116
117 $ hg --repo c --repository b -R a tip
117 $ hg --repo c --repository b -R a tip
118 changeset: 0:8580ff50825a
118 changeset: 0:8580ff50825a
119 tag: tip
119 tag: tip
120 user: test
120 user: test
121 date: Thu Jan 01 00:00:01 1970 +0000
121 date: Thu Jan 01 00:00:01 1970 +0000
122 summary: a
122 summary: a
123
123
124
124
125 earlygetopt short option without following space:
125 earlygetopt short option without following space:
126
126
127 $ hg -q -Rb tip
127 $ hg -q -Rb tip
128 0:b6c483daf290
128 0:b6c483daf290
129
129
130 earlygetopt with illegal abbreviations:
130 earlygetopt with illegal abbreviations:
131
131
132 $ hg --confi "foo.bar=baz"
132 $ hg --confi "foo.bar=baz"
133 abort: option --config may not be abbreviated!
133 abort: option --config may not be abbreviated!
134 [255]
134 [255]
135 $ hg --cw a tip
135 $ hg --cw a tip
136 abort: option --cwd may not be abbreviated!
136 abort: option --cwd may not be abbreviated!
137 [255]
137 [255]
138 $ hg --rep a tip
138 $ hg --rep a tip
139 abort: option -R has to be separated from other options (e.g. not -qR) and --repository may only be abbreviated as --repo!
139 abort: option -R has to be separated from other options (e.g. not -qR) and --repository may only be abbreviated as --repo!
140 [255]
140 [255]
141 $ hg --repositor a tip
141 $ hg --repositor a tip
142 abort: option -R has to be separated from other options (e.g. not -qR) and --repository may only be abbreviated as --repo!
142 abort: option -R has to be separated from other options (e.g. not -qR) and --repository may only be abbreviated as --repo!
143 [255]
143 [255]
144 $ hg -qR a tip
144 $ hg -qR a tip
145 abort: option -R has to be separated from other options (e.g. not -qR) and --repository may only be abbreviated as --repo!
145 abort: option -R has to be separated from other options (e.g. not -qR) and --repository may only be abbreviated as --repo!
146 [255]
146 [255]
147 $ hg -qRa tip
147 $ hg -qRa tip
148 abort: option -R has to be separated from other options (e.g. not -qR) and --repository may only be abbreviated as --repo!
148 abort: option -R has to be separated from other options (e.g. not -qR) and --repository may only be abbreviated as --repo!
149 [255]
149 [255]
150
150
151 Testing --cwd:
151 Testing --cwd:
152
152
153 $ hg --cwd a parents
153 $ hg --cwd a parents
154 changeset: 0:8580ff50825a
154 changeset: 0:8580ff50825a
155 tag: tip
155 tag: tip
156 user: test
156 user: test
157 date: Thu Jan 01 00:00:01 1970 +0000
157 date: Thu Jan 01 00:00:01 1970 +0000
158 summary: a
158 summary: a
159
159
160
160
161 Testing -y/--noninteractive - just be sure it is parsed:
161 Testing -y/--noninteractive - just be sure it is parsed:
162
162
163 $ hg --cwd a tip -q --noninteractive
163 $ hg --cwd a tip -q --noninteractive
164 0:8580ff50825a
164 0:8580ff50825a
165 $ hg --cwd a tip -q -y
165 $ hg --cwd a tip -q -y
166 0:8580ff50825a
166 0:8580ff50825a
167
167
168 Testing -q/--quiet:
168 Testing -q/--quiet:
169
169
170 $ hg -R a -q tip
170 $ hg -R a -q tip
171 0:8580ff50825a
171 0:8580ff50825a
172 $ hg -R b -q tip
172 $ hg -R b -q tip
173 0:b6c483daf290
173 0:b6c483daf290
174 $ hg -R c --quiet parents
174 $ hg -R c --quiet parents
175 0:8580ff50825a
175 0:8580ff50825a
176 1:b6c483daf290
176 1:b6c483daf290
177
177
178 Testing -v/--verbose:
178 Testing -v/--verbose:
179
179
180 $ hg --cwd c head -v
180 $ hg --cwd c head -v
181 changeset: 1:b6c483daf290
181 changeset: 1:b6c483daf290
182 tag: tip
182 tag: tip
183 parent: -1:000000000000
183 parent: -1:000000000000
184 user: test
184 user: test
185 date: Thu Jan 01 00:00:01 1970 +0000
185 date: Thu Jan 01 00:00:01 1970 +0000
186 files: b
186 files: b
187 description:
187 description:
188 b
188 b
189
189
190
190
191 changeset: 0:8580ff50825a
191 changeset: 0:8580ff50825a
192 user: test
192 user: test
193 date: Thu Jan 01 00:00:01 1970 +0000
193 date: Thu Jan 01 00:00:01 1970 +0000
194 files: a
194 files: a
195 description:
195 description:
196 a
196 a
197
197
198
198
199 $ hg --cwd b tip --verbose
199 $ hg --cwd b tip --verbose
200 changeset: 0:b6c483daf290
200 changeset: 0:b6c483daf290
201 tag: tip
201 tag: tip
202 user: test
202 user: test
203 date: Thu Jan 01 00:00:01 1970 +0000
203 date: Thu Jan 01 00:00:01 1970 +0000
204 files: b
204 files: b
205 description:
205 description:
206 b
206 b
207
207
208
208
209
209
210 Testing --config:
210 Testing --config:
211
211
212 $ hg --cwd c --config paths.quuxfoo=bar paths | grep quuxfoo > /dev/null && echo quuxfoo
212 $ hg --cwd c --config paths.quuxfoo=bar paths | grep quuxfoo > /dev/null && echo quuxfoo
213 quuxfoo
213 quuxfoo
214 $ hg --cwd c --config '' tip -q
214 $ hg --cwd c --config '' tip -q
215 abort: malformed --config option: '' (use --config section.name=value)
215 abort: malformed --config option: '' (use --config section.name=value)
216 [255]
216 [255]
217 $ hg --cwd c --config a.b tip -q
217 $ hg --cwd c --config a.b tip -q
218 abort: malformed --config option: 'a.b' (use --config section.name=value)
218 abort: malformed --config option: 'a.b' (use --config section.name=value)
219 [255]
219 [255]
220 $ hg --cwd c --config a tip -q
220 $ hg --cwd c --config a tip -q
221 abort: malformed --config option: 'a' (use --config section.name=value)
221 abort: malformed --config option: 'a' (use --config section.name=value)
222 [255]
222 [255]
223 $ hg --cwd c --config a.= tip -q
223 $ hg --cwd c --config a.= tip -q
224 abort: malformed --config option: 'a.=' (use --config section.name=value)
224 abort: malformed --config option: 'a.=' (use --config section.name=value)
225 [255]
225 [255]
226 $ hg --cwd c --config .b= tip -q
226 $ hg --cwd c --config .b= tip -q
227 abort: malformed --config option: '.b=' (use --config section.name=value)
227 abort: malformed --config option: '.b=' (use --config section.name=value)
228 [255]
228 [255]
229
229
230 Testing --debug:
230 Testing --debug:
231
231
232 $ hg --cwd c log --debug
232 $ hg --cwd c log --debug
233 changeset: 1:b6c483daf2907ce5825c0bb50f5716226281cc1a
233 changeset: 1:b6c483daf2907ce5825c0bb50f5716226281cc1a
234 tag: tip
234 tag: tip
235 parent: -1:0000000000000000000000000000000000000000
235 parent: -1:0000000000000000000000000000000000000000
236 parent: -1:0000000000000000000000000000000000000000
236 parent: -1:0000000000000000000000000000000000000000
237 manifest: 1:23226e7a252cacdc2d99e4fbdc3653441056de49
237 manifest: 1:23226e7a252cacdc2d99e4fbdc3653441056de49
238 user: test
238 user: test
239 date: Thu Jan 01 00:00:01 1970 +0000
239 date: Thu Jan 01 00:00:01 1970 +0000
240 files+: b
240 files+: b
241 extra: branch=default
241 extra: branch=default
242 description:
242 description:
243 b
243 b
244
244
245
245
246 changeset: 0:8580ff50825a50c8f716709acdf8de0deddcd6ab
246 changeset: 0:8580ff50825a50c8f716709acdf8de0deddcd6ab
247 parent: -1:0000000000000000000000000000000000000000
247 parent: -1:0000000000000000000000000000000000000000
248 parent: -1:0000000000000000000000000000000000000000
248 parent: -1:0000000000000000000000000000000000000000
249 manifest: 0:a0c8bcbbb45c63b90b70ad007bf38961f64f2af0
249 manifest: 0:a0c8bcbbb45c63b90b70ad007bf38961f64f2af0
250 user: test
250 user: test
251 date: Thu Jan 01 00:00:01 1970 +0000
251 date: Thu Jan 01 00:00:01 1970 +0000
252 files+: a
252 files+: a
253 extra: branch=default
253 extra: branch=default
254 description:
254 description:
255 a
255 a
256
256
257
257
258
258
259 Testing --traceback:
259 Testing --traceback:
260
260
261 $ hg --cwd c --config x --traceback id 2>&1 | grep -i 'traceback'
261 $ hg --cwd c --config x --traceback id 2>&1 | grep -i 'traceback'
262 Traceback (most recent call last):
262 Traceback (most recent call last):
263
263
264 Testing --time:
264 Testing --time:
265
265
266 $ hg --cwd a --time id
266 $ hg --cwd a --time id
267 8580ff50825a tip
267 8580ff50825a tip
268 Time: real * (glob)
268 Time: real * (glob)
269
269
270 Testing --version:
270 Testing --version:
271
271
272 $ hg --version -q
272 $ hg --version -q
273 Mercurial Distributed SCM * (glob)
273 Mercurial Distributed SCM * (glob)
274
274
275 Testing -h/--help:
275 Testing -h/--help:
276
276
277 $ hg -h
277 $ hg -h
278 Mercurial Distributed SCM
278 Mercurial Distributed SCM
279
279
280 list of commands:
280 list of commands:
281
281
282 add add the specified files on the next commit
282 add add the specified files on the next commit
283 addremove add all new files, delete all missing files
283 addremove add all new files, delete all missing files
284 annotate show changeset information by line for each file
284 annotate show changeset information by line for each file
285 archive create an unversioned archive of a repository revision
285 archive create an unversioned archive of a repository revision
286 backout reverse effect of earlier changeset
286 backout reverse effect of earlier changeset
287 bisect subdivision search of changesets
287 bisect subdivision search of changesets
288 bookmarks track a line of development with movable markers
288 bookmarks track a line of development with movable markers
289 branch set or show the current branch name
289 branch set or show the current branch name
290 branches list repository named branches
290 branches list repository named branches
291 bundle create a changegroup file
291 bundle create a changegroup file
292 cat output the current or given revision of files
292 cat output the current or given revision of files
293 clone make a copy of an existing repository
293 clone make a copy of an existing repository
294 commit commit the specified files or all outstanding changes
294 commit commit the specified files or all outstanding changes
295 copy mark files as copied for the next commit
295 copy mark files as copied for the next commit
296 diff diff repository (or selected files)
296 diff diff repository (or selected files)
297 export dump the header and diffs for one or more changesets
297 export dump the header and diffs for one or more changesets
298 forget forget the specified files on the next commit
298 forget forget the specified files on the next commit
299 graft copy changes from other branches onto the current branch
299 graft copy changes from other branches onto the current branch
300 grep search for a pattern in specified files and revisions
300 grep search for a pattern in specified files and revisions
301 heads show current repository heads or show branch heads
301 heads show current repository heads or show branch heads
302 help show help for a given topic or a help overview
302 help show help for a given topic or a help overview
303 identify identify the working copy or specified revision
303 identify identify the working copy or specified revision
304 import import an ordered set of patches
304 import import an ordered set of patches
305 incoming show new changesets found in source
305 incoming show new changesets found in source
306 init create a new repository in the given directory
306 init create a new repository in the given directory
307 locate locate files matching specific patterns
307 locate locate files matching specific patterns
308 log show revision history of entire repository or files
308 log show revision history of entire repository or files
309 manifest output the current or given revision of the project manifest
309 manifest output the current or given revision of the project manifest
310 merge merge working directory with another revision
310 merge merge working directory with another revision
311 outgoing show changesets not found in the destination
311 outgoing show changesets not found in the destination
312 parents show the parents of the working directory or revision
312 parents show the parents of the working directory or revision
313 paths show aliases for remote repositories
313 paths show aliases for remote repositories
314 phase set or show the current phase name
314 pull pull changes from the specified source
315 pull pull changes from the specified source
315 push push changes to the specified destination
316 push push changes to the specified destination
316 recover roll back an interrupted transaction
317 recover roll back an interrupted transaction
317 remove remove the specified files on the next commit
318 remove remove the specified files on the next commit
318 rename rename files; equivalent of copy + remove
319 rename rename files; equivalent of copy + remove
319 resolve redo merges or set/view the merge status of files
320 resolve redo merges or set/view the merge status of files
320 revert restore files to their checkout state
321 revert restore files to their checkout state
321 rollback roll back the last transaction (dangerous)
322 rollback roll back the last transaction (dangerous)
322 root print the root (top) of the current working directory
323 root print the root (top) of the current working directory
323 serve start stand-alone webserver
324 serve start stand-alone webserver
324 showconfig show combined config settings from all hgrc files
325 showconfig show combined config settings from all hgrc files
325 status show changed files in the working directory
326 status show changed files in the working directory
326 summary summarize working directory state
327 summary summarize working directory state
327 tag add one or more tags for the current or given revision
328 tag add one or more tags for the current or given revision
328 tags list repository tags
329 tags list repository tags
329 tip show the tip revision
330 tip show the tip revision
330 unbundle apply one or more changegroup files
331 unbundle apply one or more changegroup files
331 update update working directory (or switch revisions)
332 update update working directory (or switch revisions)
332 verify verify the integrity of the repository
333 verify verify the integrity of the repository
333 version output version and copyright information
334 version output version and copyright information
334
335
335 additional help topics:
336 additional help topics:
336
337
337 config Configuration Files
338 config Configuration Files
338 dates Date Formats
339 dates Date Formats
339 diffs Diff Formats
340 diffs Diff Formats
340 environment Environment Variables
341 environment Environment Variables
341 extensions Using additional features
342 extensions Using additional features
342 filesets Specifying File Sets
343 filesets Specifying File Sets
343 glossary Glossary
344 glossary Glossary
344 hgignore syntax for Mercurial ignore files
345 hgignore syntax for Mercurial ignore files
345 hgweb Configuring hgweb
346 hgweb Configuring hgweb
346 merge-tools Merge Tools
347 merge-tools Merge Tools
347 multirevs Specifying Multiple Revisions
348 multirevs Specifying Multiple Revisions
348 patterns File Name Patterns
349 patterns File Name Patterns
349 revisions Specifying Single Revisions
350 revisions Specifying Single Revisions
350 revsets Specifying Revision Sets
351 revsets Specifying Revision Sets
351 subrepos Subrepositories
352 subrepos Subrepositories
352 templating Template Usage
353 templating Template Usage
353 urls URL Paths
354 urls URL Paths
354
355
355 use "hg -v help" to show builtin aliases and global options
356 use "hg -v help" to show builtin aliases and global options
356
357
357
358
358
359
359 $ hg --help
360 $ hg --help
360 Mercurial Distributed SCM
361 Mercurial Distributed SCM
361
362
362 list of commands:
363 list of commands:
363
364
364 add add the specified files on the next commit
365 add add the specified files on the next commit
365 addremove add all new files, delete all missing files
366 addremove add all new files, delete all missing files
366 annotate show changeset information by line for each file
367 annotate show changeset information by line for each file
367 archive create an unversioned archive of a repository revision
368 archive create an unversioned archive of a repository revision
368 backout reverse effect of earlier changeset
369 backout reverse effect of earlier changeset
369 bisect subdivision search of changesets
370 bisect subdivision search of changesets
370 bookmarks track a line of development with movable markers
371 bookmarks track a line of development with movable markers
371 branch set or show the current branch name
372 branch set or show the current branch name
372 branches list repository named branches
373 branches list repository named branches
373 bundle create a changegroup file
374 bundle create a changegroup file
374 cat output the current or given revision of files
375 cat output the current or given revision of files
375 clone make a copy of an existing repository
376 clone make a copy of an existing repository
376 commit commit the specified files or all outstanding changes
377 commit commit the specified files or all outstanding changes
377 copy mark files as copied for the next commit
378 copy mark files as copied for the next commit
378 diff diff repository (or selected files)
379 diff diff repository (or selected files)
379 export dump the header and diffs for one or more changesets
380 export dump the header and diffs for one or more changesets
380 forget forget the specified files on the next commit
381 forget forget the specified files on the next commit
381 graft copy changes from other branches onto the current branch
382 graft copy changes from other branches onto the current branch
382 grep search for a pattern in specified files and revisions
383 grep search for a pattern in specified files and revisions
383 heads show current repository heads or show branch heads
384 heads show current repository heads or show branch heads
384 help show help for a given topic or a help overview
385 help show help for a given topic or a help overview
385 identify identify the working copy or specified revision
386 identify identify the working copy or specified revision
386 import import an ordered set of patches
387 import import an ordered set of patches
387 incoming show new changesets found in source
388 incoming show new changesets found in source
388 init create a new repository in the given directory
389 init create a new repository in the given directory
389 locate locate files matching specific patterns
390 locate locate files matching specific patterns
390 log show revision history of entire repository or files
391 log show revision history of entire repository or files
391 manifest output the current or given revision of the project manifest
392 manifest output the current or given revision of the project manifest
392 merge merge working directory with another revision
393 merge merge working directory with another revision
393 outgoing show changesets not found in the destination
394 outgoing show changesets not found in the destination
394 parents show the parents of the working directory or revision
395 parents show the parents of the working directory or revision
395 paths show aliases for remote repositories
396 paths show aliases for remote repositories
397 phase set or show the current phase name
396 pull pull changes from the specified source
398 pull pull changes from the specified source
397 push push changes to the specified destination
399 push push changes to the specified destination
398 recover roll back an interrupted transaction
400 recover roll back an interrupted transaction
399 remove remove the specified files on the next commit
401 remove remove the specified files on the next commit
400 rename rename files; equivalent of copy + remove
402 rename rename files; equivalent of copy + remove
401 resolve redo merges or set/view the merge status of files
403 resolve redo merges or set/view the merge status of files
402 revert restore files to their checkout state
404 revert restore files to their checkout state
403 rollback roll back the last transaction (dangerous)
405 rollback roll back the last transaction (dangerous)
404 root print the root (top) of the current working directory
406 root print the root (top) of the current working directory
405 serve start stand-alone webserver
407 serve start stand-alone webserver
406 showconfig show combined config settings from all hgrc files
408 showconfig show combined config settings from all hgrc files
407 status show changed files in the working directory
409 status show changed files in the working directory
408 summary summarize working directory state
410 summary summarize working directory state
409 tag add one or more tags for the current or given revision
411 tag add one or more tags for the current or given revision
410 tags list repository tags
412 tags list repository tags
411 tip show the tip revision
413 tip show the tip revision
412 unbundle apply one or more changegroup files
414 unbundle apply one or more changegroup files
413 update update working directory (or switch revisions)
415 update update working directory (or switch revisions)
414 verify verify the integrity of the repository
416 verify verify the integrity of the repository
415 version output version and copyright information
417 version output version and copyright information
416
418
417 additional help topics:
419 additional help topics:
418
420
419 config Configuration Files
421 config Configuration Files
420 dates Date Formats
422 dates Date Formats
421 diffs Diff Formats
423 diffs Diff Formats
422 environment Environment Variables
424 environment Environment Variables
423 extensions Using additional features
425 extensions Using additional features
424 filesets Specifying File Sets
426 filesets Specifying File Sets
425 glossary Glossary
427 glossary Glossary
426 hgignore syntax for Mercurial ignore files
428 hgignore syntax for Mercurial ignore files
427 hgweb Configuring hgweb
429 hgweb Configuring hgweb
428 merge-tools Merge Tools
430 merge-tools Merge Tools
429 multirevs Specifying Multiple Revisions
431 multirevs Specifying Multiple Revisions
430 patterns File Name Patterns
432 patterns File Name Patterns
431 revisions Specifying Single Revisions
433 revisions Specifying Single Revisions
432 revsets Specifying Revision Sets
434 revsets Specifying Revision Sets
433 subrepos Subrepositories
435 subrepos Subrepositories
434 templating Template Usage
436 templating Template Usage
435 urls URL Paths
437 urls URL Paths
436
438
437 use "hg -v help" to show builtin aliases and global options
439 use "hg -v help" to show builtin aliases and global options
438
440
439 Not tested: --debugger
441 Not tested: --debugger
440
442
@@ -1,772 +1,781
1 Short help:
1 Short help:
2
2
3 $ hg
3 $ hg
4 Mercurial Distributed SCM
4 Mercurial Distributed SCM
5
5
6 basic commands:
6 basic commands:
7
7
8 add add the specified files on the next commit
8 add add the specified files on the next commit
9 annotate show changeset information by line for each file
9 annotate show changeset information by line for each file
10 clone make a copy of an existing repository
10 clone make a copy of an existing repository
11 commit commit the specified files or all outstanding changes
11 commit commit the specified files or all outstanding changes
12 diff diff repository (or selected files)
12 diff diff repository (or selected files)
13 export dump the header and diffs for one or more changesets
13 export dump the header and diffs for one or more changesets
14 forget forget the specified files on the next commit
14 forget forget the specified files on the next commit
15 init create a new repository in the given directory
15 init create a new repository in the given directory
16 log show revision history of entire repository or files
16 log show revision history of entire repository or files
17 merge merge working directory with another revision
17 merge merge working directory with another revision
18 phase set or show the current phase name
18 pull pull changes from the specified source
19 pull pull changes from the specified source
19 push push changes to the specified destination
20 push push changes to the specified destination
20 remove remove the specified files on the next commit
21 remove remove the specified files on the next commit
21 serve start stand-alone webserver
22 serve start stand-alone webserver
22 status show changed files in the working directory
23 status show changed files in the working directory
23 summary summarize working directory state
24 summary summarize working directory state
24 update update working directory (or switch revisions)
25 update update working directory (or switch revisions)
25
26
26 use "hg help" for the full list of commands or "hg -v" for details
27 use "hg help" for the full list of commands or "hg -v" for details
27
28
28 $ hg -q
29 $ hg -q
29 add add the specified files on the next commit
30 add add the specified files on the next commit
30 annotate show changeset information by line for each file
31 annotate show changeset information by line for each file
31 clone make a copy of an existing repository
32 clone make a copy of an existing repository
32 commit commit the specified files or all outstanding changes
33 commit commit the specified files or all outstanding changes
33 diff diff repository (or selected files)
34 diff diff repository (or selected files)
34 export dump the header and diffs for one or more changesets
35 export dump the header and diffs for one or more changesets
35 forget forget the specified files on the next commit
36 forget forget the specified files on the next commit
36 init create a new repository in the given directory
37 init create a new repository in the given directory
37 log show revision history of entire repository or files
38 log show revision history of entire repository or files
38 merge merge working directory with another revision
39 merge merge working directory with another revision
40 phase set or show the current phase name
39 pull pull changes from the specified source
41 pull pull changes from the specified source
40 push push changes to the specified destination
42 push push changes to the specified destination
41 remove remove the specified files on the next commit
43 remove remove the specified files on the next commit
42 serve start stand-alone webserver
44 serve start stand-alone webserver
43 status show changed files in the working directory
45 status show changed files in the working directory
44 summary summarize working directory state
46 summary summarize working directory state
45 update update working directory (or switch revisions)
47 update update working directory (or switch revisions)
46
48
47 $ hg help
49 $ hg help
48 Mercurial Distributed SCM
50 Mercurial Distributed SCM
49
51
50 list of commands:
52 list of commands:
51
53
52 add add the specified files on the next commit
54 add add the specified files on the next commit
53 addremove add all new files, delete all missing files
55 addremove add all new files, delete all missing files
54 annotate show changeset information by line for each file
56 annotate show changeset information by line for each file
55 archive create an unversioned archive of a repository revision
57 archive create an unversioned archive of a repository revision
56 backout reverse effect of earlier changeset
58 backout reverse effect of earlier changeset
57 bisect subdivision search of changesets
59 bisect subdivision search of changesets
58 bookmarks track a line of development with movable markers
60 bookmarks track a line of development with movable markers
59 branch set or show the current branch name
61 branch set or show the current branch name
60 branches list repository named branches
62 branches list repository named branches
61 bundle create a changegroup file
63 bundle create a changegroup file
62 cat output the current or given revision of files
64 cat output the current or given revision of files
63 clone make a copy of an existing repository
65 clone make a copy of an existing repository
64 commit commit the specified files or all outstanding changes
66 commit commit the specified files or all outstanding changes
65 copy mark files as copied for the next commit
67 copy mark files as copied for the next commit
66 diff diff repository (or selected files)
68 diff diff repository (or selected files)
67 export dump the header and diffs for one or more changesets
69 export dump the header and diffs for one or more changesets
68 forget forget the specified files on the next commit
70 forget forget the specified files on the next commit
69 graft copy changes from other branches onto the current branch
71 graft copy changes from other branches onto the current branch
70 grep search for a pattern in specified files and revisions
72 grep search for a pattern in specified files and revisions
71 heads show current repository heads or show branch heads
73 heads show current repository heads or show branch heads
72 help show help for a given topic or a help overview
74 help show help for a given topic or a help overview
73 identify identify the working copy or specified revision
75 identify identify the working copy or specified revision
74 import import an ordered set of patches
76 import import an ordered set of patches
75 incoming show new changesets found in source
77 incoming show new changesets found in source
76 init create a new repository in the given directory
78 init create a new repository in the given directory
77 locate locate files matching specific patterns
79 locate locate files matching specific patterns
78 log show revision history of entire repository or files
80 log show revision history of entire repository or files
79 manifest output the current or given revision of the project manifest
81 manifest output the current or given revision of the project manifest
80 merge merge working directory with another revision
82 merge merge working directory with another revision
81 outgoing show changesets not found in the destination
83 outgoing show changesets not found in the destination
82 parents show the parents of the working directory or revision
84 parents show the parents of the working directory or revision
83 paths show aliases for remote repositories
85 paths show aliases for remote repositories
86 phase set or show the current phase name
84 pull pull changes from the specified source
87 pull pull changes from the specified source
85 push push changes to the specified destination
88 push push changes to the specified destination
86 recover roll back an interrupted transaction
89 recover roll back an interrupted transaction
87 remove remove the specified files on the next commit
90 remove remove the specified files on the next commit
88 rename rename files; equivalent of copy + remove
91 rename rename files; equivalent of copy + remove
89 resolve redo merges or set/view the merge status of files
92 resolve redo merges or set/view the merge status of files
90 revert restore files to their checkout state
93 revert restore files to their checkout state
91 rollback roll back the last transaction (dangerous)
94 rollback roll back the last transaction (dangerous)
92 root print the root (top) of the current working directory
95 root print the root (top) of the current working directory
93 serve start stand-alone webserver
96 serve start stand-alone webserver
94 showconfig show combined config settings from all hgrc files
97 showconfig show combined config settings from all hgrc files
95 status show changed files in the working directory
98 status show changed files in the working directory
96 summary summarize working directory state
99 summary summarize working directory state
97 tag add one or more tags for the current or given revision
100 tag add one or more tags for the current or given revision
98 tags list repository tags
101 tags list repository tags
99 tip show the tip revision
102 tip show the tip revision
100 unbundle apply one or more changegroup files
103 unbundle apply one or more changegroup files
101 update update working directory (or switch revisions)
104 update update working directory (or switch revisions)
102 verify verify the integrity of the repository
105 verify verify the integrity of the repository
103 version output version and copyright information
106 version output version and copyright information
104
107
105 additional help topics:
108 additional help topics:
106
109
107 config Configuration Files
110 config Configuration Files
108 dates Date Formats
111 dates Date Formats
109 diffs Diff Formats
112 diffs Diff Formats
110 environment Environment Variables
113 environment Environment Variables
111 extensions Using additional features
114 extensions Using additional features
112 filesets Specifying File Sets
115 filesets Specifying File Sets
113 glossary Glossary
116 glossary Glossary
114 hgignore syntax for Mercurial ignore files
117 hgignore syntax for Mercurial ignore files
115 hgweb Configuring hgweb
118 hgweb Configuring hgweb
116 merge-tools Merge Tools
119 merge-tools Merge Tools
117 multirevs Specifying Multiple Revisions
120 multirevs Specifying Multiple Revisions
118 patterns File Name Patterns
121 patterns File Name Patterns
119 revisions Specifying Single Revisions
122 revisions Specifying Single Revisions
120 revsets Specifying Revision Sets
123 revsets Specifying Revision Sets
121 subrepos Subrepositories
124 subrepos Subrepositories
122 templating Template Usage
125 templating Template Usage
123 urls URL Paths
126 urls URL Paths
124
127
125 use "hg -v help" to show builtin aliases and global options
128 use "hg -v help" to show builtin aliases and global options
126
129
127 $ hg -q help
130 $ hg -q help
128 add add the specified files on the next commit
131 add add the specified files on the next commit
129 addremove add all new files, delete all missing files
132 addremove add all new files, delete all missing files
130 annotate show changeset information by line for each file
133 annotate show changeset information by line for each file
131 archive create an unversioned archive of a repository revision
134 archive create an unversioned archive of a repository revision
132 backout reverse effect of earlier changeset
135 backout reverse effect of earlier changeset
133 bisect subdivision search of changesets
136 bisect subdivision search of changesets
134 bookmarks track a line of development with movable markers
137 bookmarks track a line of development with movable markers
135 branch set or show the current branch name
138 branch set or show the current branch name
136 branches list repository named branches
139 branches list repository named branches
137 bundle create a changegroup file
140 bundle create a changegroup file
138 cat output the current or given revision of files
141 cat output the current or given revision of files
139 clone make a copy of an existing repository
142 clone make a copy of an existing repository
140 commit commit the specified files or all outstanding changes
143 commit commit the specified files or all outstanding changes
141 copy mark files as copied for the next commit
144 copy mark files as copied for the next commit
142 diff diff repository (or selected files)
145 diff diff repository (or selected files)
143 export dump the header and diffs for one or more changesets
146 export dump the header and diffs for one or more changesets
144 forget forget the specified files on the next commit
147 forget forget the specified files on the next commit
145 graft copy changes from other branches onto the current branch
148 graft copy changes from other branches onto the current branch
146 grep search for a pattern in specified files and revisions
149 grep search for a pattern in specified files and revisions
147 heads show current repository heads or show branch heads
150 heads show current repository heads or show branch heads
148 help show help for a given topic or a help overview
151 help show help for a given topic or a help overview
149 identify identify the working copy or specified revision
152 identify identify the working copy or specified revision
150 import import an ordered set of patches
153 import import an ordered set of patches
151 incoming show new changesets found in source
154 incoming show new changesets found in source
152 init create a new repository in the given directory
155 init create a new repository in the given directory
153 locate locate files matching specific patterns
156 locate locate files matching specific patterns
154 log show revision history of entire repository or files
157 log show revision history of entire repository or files
155 manifest output the current or given revision of the project manifest
158 manifest output the current or given revision of the project manifest
156 merge merge working directory with another revision
159 merge merge working directory with another revision
157 outgoing show changesets not found in the destination
160 outgoing show changesets not found in the destination
158 parents show the parents of the working directory or revision
161 parents show the parents of the working directory or revision
159 paths show aliases for remote repositories
162 paths show aliases for remote repositories
163 phase set or show the current phase name
160 pull pull changes from the specified source
164 pull pull changes from the specified source
161 push push changes to the specified destination
165 push push changes to the specified destination
162 recover roll back an interrupted transaction
166 recover roll back an interrupted transaction
163 remove remove the specified files on the next commit
167 remove remove the specified files on the next commit
164 rename rename files; equivalent of copy + remove
168 rename rename files; equivalent of copy + remove
165 resolve redo merges or set/view the merge status of files
169 resolve redo merges or set/view the merge status of files
166 revert restore files to their checkout state
170 revert restore files to their checkout state
167 rollback roll back the last transaction (dangerous)
171 rollback roll back the last transaction (dangerous)
168 root print the root (top) of the current working directory
172 root print the root (top) of the current working directory
169 serve start stand-alone webserver
173 serve start stand-alone webserver
170 showconfig show combined config settings from all hgrc files
174 showconfig show combined config settings from all hgrc files
171 status show changed files in the working directory
175 status show changed files in the working directory
172 summary summarize working directory state
176 summary summarize working directory state
173 tag add one or more tags for the current or given revision
177 tag add one or more tags for the current or given revision
174 tags list repository tags
178 tags list repository tags
175 tip show the tip revision
179 tip show the tip revision
176 unbundle apply one or more changegroup files
180 unbundle apply one or more changegroup files
177 update update working directory (or switch revisions)
181 update update working directory (or switch revisions)
178 verify verify the integrity of the repository
182 verify verify the integrity of the repository
179 version output version and copyright information
183 version output version and copyright information
180
184
181 additional help topics:
185 additional help topics:
182
186
183 config Configuration Files
187 config Configuration Files
184 dates Date Formats
188 dates Date Formats
185 diffs Diff Formats
189 diffs Diff Formats
186 environment Environment Variables
190 environment Environment Variables
187 extensions Using additional features
191 extensions Using additional features
188 filesets Specifying File Sets
192 filesets Specifying File Sets
189 glossary Glossary
193 glossary Glossary
190 hgignore syntax for Mercurial ignore files
194 hgignore syntax for Mercurial ignore files
191 hgweb Configuring hgweb
195 hgweb Configuring hgweb
192 merge-tools Merge Tools
196 merge-tools Merge Tools
193 multirevs Specifying Multiple Revisions
197 multirevs Specifying Multiple Revisions
194 patterns File Name Patterns
198 patterns File Name Patterns
195 revisions Specifying Single Revisions
199 revisions Specifying Single Revisions
196 revsets Specifying Revision Sets
200 revsets Specifying Revision Sets
197 subrepos Subrepositories
201 subrepos Subrepositories
198 templating Template Usage
202 templating Template Usage
199 urls URL Paths
203 urls URL Paths
200
204
201 Test short command list with verbose option
205 Test short command list with verbose option
202
206
203 $ hg -v help shortlist
207 $ hg -v help shortlist
204 Mercurial Distributed SCM
208 Mercurial Distributed SCM
205
209
206 basic commands:
210 basic commands:
207
211
208 add:
212 add:
209 add the specified files on the next commit
213 add the specified files on the next commit
210 annotate, blame:
214 annotate, blame:
211 show changeset information by line for each file
215 show changeset information by line for each file
212 clone:
216 clone:
213 make a copy of an existing repository
217 make a copy of an existing repository
214 commit, ci:
218 commit, ci:
215 commit the specified files or all outstanding changes
219 commit the specified files or all outstanding changes
216 diff:
220 diff:
217 diff repository (or selected files)
221 diff repository (or selected files)
218 export:
222 export:
219 dump the header and diffs for one or more changesets
223 dump the header and diffs for one or more changesets
220 forget:
224 forget:
221 forget the specified files on the next commit
225 forget the specified files on the next commit
222 init:
226 init:
223 create a new repository in the given directory
227 create a new repository in the given directory
224 log, history:
228 log, history:
225 show revision history of entire repository or files
229 show revision history of entire repository or files
226 merge:
230 merge:
227 merge working directory with another revision
231 merge working directory with another revision
232 phase:
233 set or show the current phase name
228 pull:
234 pull:
229 pull changes from the specified source
235 pull changes from the specified source
230 push:
236 push:
231 push changes to the specified destination
237 push changes to the specified destination
232 remove, rm:
238 remove, rm:
233 remove the specified files on the next commit
239 remove the specified files on the next commit
234 serve:
240 serve:
235 start stand-alone webserver
241 start stand-alone webserver
236 status, st:
242 status, st:
237 show changed files in the working directory
243 show changed files in the working directory
238 summary, sum:
244 summary, sum:
239 summarize working directory state
245 summarize working directory state
240 update, up, checkout, co:
246 update, up, checkout, co:
241 update working directory (or switch revisions)
247 update working directory (or switch revisions)
242
248
243 global options:
249 global options:
244
250
245 -R --repository REPO repository root directory or name of overlay bundle
251 -R --repository REPO repository root directory or name of overlay bundle
246 file
252 file
247 --cwd DIR change working directory
253 --cwd DIR change working directory
248 -y --noninteractive do not prompt, automatically pick the first choice for
254 -y --noninteractive do not prompt, automatically pick the first choice for
249 all prompts
255 all prompts
250 -q --quiet suppress output
256 -q --quiet suppress output
251 -v --verbose enable additional output
257 -v --verbose enable additional output
252 --config CONFIG [+] set/override config option (use 'section.name=value')
258 --config CONFIG [+] set/override config option (use 'section.name=value')
253 --debug enable debugging output
259 --debug enable debugging output
254 --debugger start debugger
260 --debugger start debugger
255 --encoding ENCODE set the charset encoding (default: ascii)
261 --encoding ENCODE set the charset encoding (default: ascii)
256 --encodingmode MODE set the charset encoding mode (default: strict)
262 --encodingmode MODE set the charset encoding mode (default: strict)
257 --traceback always print a traceback on exception
263 --traceback always print a traceback on exception
258 --time time how long the command takes
264 --time time how long the command takes
259 --profile print command execution profile
265 --profile print command execution profile
260 --version output version information and exit
266 --version output version information and exit
261 -h --help display help and exit
267 -h --help display help and exit
262
268
263 [+] marked option can be specified multiple times
269 [+] marked option can be specified multiple times
264
270
265 use "hg help" for the full list of commands
271 use "hg help" for the full list of commands
266
272
267 $ hg add -h
273 $ hg add -h
268 hg add [OPTION]... [FILE]...
274 hg add [OPTION]... [FILE]...
269
275
270 add the specified files on the next commit
276 add the specified files on the next commit
271
277
272 Schedule files to be version controlled and added to the repository.
278 Schedule files to be version controlled and added to the repository.
273
279
274 The files will be added to the repository at the next commit. To undo an
280 The files will be added to the repository at the next commit. To undo an
275 add before that, see "hg forget".
281 add before that, see "hg forget".
276
282
277 If no names are given, add all files to the repository.
283 If no names are given, add all files to the repository.
278
284
279 Returns 0 if all files are successfully added.
285 Returns 0 if all files are successfully added.
280
286
281 options:
287 options:
282
288
283 -I --include PATTERN [+] include names matching the given patterns
289 -I --include PATTERN [+] include names matching the given patterns
284 -X --exclude PATTERN [+] exclude names matching the given patterns
290 -X --exclude PATTERN [+] exclude names matching the given patterns
285 -S --subrepos recurse into subrepositories
291 -S --subrepos recurse into subrepositories
286 -n --dry-run do not perform actions, just print output
292 -n --dry-run do not perform actions, just print output
287
293
288 [+] marked option can be specified multiple times
294 [+] marked option can be specified multiple times
289
295
290 use "hg -v help add" to show more info
296 use "hg -v help add" to show more info
291
297
292 Verbose help for add
298 Verbose help for add
293
299
294 $ hg add -hv
300 $ hg add -hv
295 hg add [OPTION]... [FILE]...
301 hg add [OPTION]... [FILE]...
296
302
297 add the specified files on the next commit
303 add the specified files on the next commit
298
304
299 Schedule files to be version controlled and added to the repository.
305 Schedule files to be version controlled and added to the repository.
300
306
301 The files will be added to the repository at the next commit. To undo an
307 The files will be added to the repository at the next commit. To undo an
302 add before that, see "hg forget".
308 add before that, see "hg forget".
303
309
304 If no names are given, add all files to the repository.
310 If no names are given, add all files to the repository.
305
311
306 An example showing how new (unknown) files are added automatically by "hg
312 An example showing how new (unknown) files are added automatically by "hg
307 add":
313 add":
308
314
309 $ ls
315 $ ls
310 foo.c
316 foo.c
311 $ hg status
317 $ hg status
312 ? foo.c
318 ? foo.c
313 $ hg add
319 $ hg add
314 adding foo.c
320 adding foo.c
315 $ hg status
321 $ hg status
316 A foo.c
322 A foo.c
317
323
318 Returns 0 if all files are successfully added.
324 Returns 0 if all files are successfully added.
319
325
320 options:
326 options:
321
327
322 -I --include PATTERN [+] include names matching the given patterns
328 -I --include PATTERN [+] include names matching the given patterns
323 -X --exclude PATTERN [+] exclude names matching the given patterns
329 -X --exclude PATTERN [+] exclude names matching the given patterns
324 -S --subrepos recurse into subrepositories
330 -S --subrepos recurse into subrepositories
325 -n --dry-run do not perform actions, just print output
331 -n --dry-run do not perform actions, just print output
326
332
327 [+] marked option can be specified multiple times
333 [+] marked option can be specified multiple times
328
334
329 global options:
335 global options:
330
336
331 -R --repository REPO repository root directory or name of overlay bundle
337 -R --repository REPO repository root directory or name of overlay bundle
332 file
338 file
333 --cwd DIR change working directory
339 --cwd DIR change working directory
334 -y --noninteractive do not prompt, automatically pick the first choice for
340 -y --noninteractive do not prompt, automatically pick the first choice for
335 all prompts
341 all prompts
336 -q --quiet suppress output
342 -q --quiet suppress output
337 -v --verbose enable additional output
343 -v --verbose enable additional output
338 --config CONFIG [+] set/override config option (use 'section.name=value')
344 --config CONFIG [+] set/override config option (use 'section.name=value')
339 --debug enable debugging output
345 --debug enable debugging output
340 --debugger start debugger
346 --debugger start debugger
341 --encoding ENCODE set the charset encoding (default: ascii)
347 --encoding ENCODE set the charset encoding (default: ascii)
342 --encodingmode MODE set the charset encoding mode (default: strict)
348 --encodingmode MODE set the charset encoding mode (default: strict)
343 --traceback always print a traceback on exception
349 --traceback always print a traceback on exception
344 --time time how long the command takes
350 --time time how long the command takes
345 --profile print command execution profile
351 --profile print command execution profile
346 --version output version information and exit
352 --version output version information and exit
347 -h --help display help and exit
353 -h --help display help and exit
348
354
349 [+] marked option can be specified multiple times
355 [+] marked option can be specified multiple times
350
356
351 Test help option with version option
357 Test help option with version option
352
358
353 $ hg add -h --version
359 $ hg add -h --version
354 Mercurial Distributed SCM (version *) (glob)
360 Mercurial Distributed SCM (version *) (glob)
355 (see http://mercurial.selenic.com for more information)
361 (see http://mercurial.selenic.com for more information)
356
362
357 Copyright (C) 2005-2011 Matt Mackall and others
363 Copyright (C) 2005-2011 Matt Mackall and others
358 This is free software; see the source for copying conditions. There is NO
364 This is free software; see the source for copying conditions. There is NO
359 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
365 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
360
366
361 $ hg add --skjdfks
367 $ hg add --skjdfks
362 hg add: option --skjdfks not recognized
368 hg add: option --skjdfks not recognized
363 hg add [OPTION]... [FILE]...
369 hg add [OPTION]... [FILE]...
364
370
365 add the specified files on the next commit
371 add the specified files on the next commit
366
372
367 options:
373 options:
368
374
369 -I --include PATTERN [+] include names matching the given patterns
375 -I --include PATTERN [+] include names matching the given patterns
370 -X --exclude PATTERN [+] exclude names matching the given patterns
376 -X --exclude PATTERN [+] exclude names matching the given patterns
371 -S --subrepos recurse into subrepositories
377 -S --subrepos recurse into subrepositories
372 -n --dry-run do not perform actions, just print output
378 -n --dry-run do not perform actions, just print output
373
379
374 [+] marked option can be specified multiple times
380 [+] marked option can be specified multiple times
375
381
376 use "hg help add" to show the full help text
382 use "hg help add" to show the full help text
377 [255]
383 [255]
378
384
379 Test ambiguous command help
385 Test ambiguous command help
380
386
381 $ hg help ad
387 $ hg help ad
382 list of commands:
388 list of commands:
383
389
384 add add the specified files on the next commit
390 add add the specified files on the next commit
385 addremove add all new files, delete all missing files
391 addremove add all new files, delete all missing files
386
392
387 use "hg -v help ad" to show builtin aliases and global options
393 use "hg -v help ad" to show builtin aliases and global options
388
394
389 Test command without options
395 Test command without options
390
396
391 $ hg help verify
397 $ hg help verify
392 hg verify
398 hg verify
393
399
394 verify the integrity of the repository
400 verify the integrity of the repository
395
401
396 Verify the integrity of the current repository.
402 Verify the integrity of the current repository.
397
403
398 This will perform an extensive check of the repository's integrity,
404 This will perform an extensive check of the repository's integrity,
399 validating the hashes and checksums of each entry in the changelog,
405 validating the hashes and checksums of each entry in the changelog,
400 manifest, and tracked files, as well as the integrity of their crosslinks
406 manifest, and tracked files, as well as the integrity of their crosslinks
401 and indices.
407 and indices.
402
408
403 Returns 0 on success, 1 if errors are encountered.
409 Returns 0 on success, 1 if errors are encountered.
404
410
405 use "hg -v help verify" to show more info
411 use "hg -v help verify" to show more info
406
412
407 $ hg help diff
413 $ hg help diff
408 hg diff [OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...
414 hg diff [OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...
409
415
410 diff repository (or selected files)
416 diff repository (or selected files)
411
417
412 Show differences between revisions for the specified files.
418 Show differences between revisions for the specified files.
413
419
414 Differences between files are shown using the unified diff format.
420 Differences between files are shown using the unified diff format.
415
421
416 Note:
422 Note:
417 diff may generate unexpected results for merges, as it will default to
423 diff may generate unexpected results for merges, as it will default to
418 comparing against the working directory's first parent changeset if no
424 comparing against the working directory's first parent changeset if no
419 revisions are specified.
425 revisions are specified.
420
426
421 When two revision arguments are given, then changes are shown between
427 When two revision arguments are given, then changes are shown between
422 those revisions. If only one revision is specified then that revision is
428 those revisions. If only one revision is specified then that revision is
423 compared to the working directory, and, when no revisions are specified,
429 compared to the working directory, and, when no revisions are specified,
424 the working directory files are compared to its parent.
430 the working directory files are compared to its parent.
425
431
426 Alternatively you can specify -c/--change with a revision to see the
432 Alternatively you can specify -c/--change with a revision to see the
427 changes in that changeset relative to its first parent.
433 changes in that changeset relative to its first parent.
428
434
429 Without the -a/--text option, diff will avoid generating diffs of files it
435 Without the -a/--text option, diff will avoid generating diffs of files it
430 detects as binary. With -a, diff will generate a diff anyway, probably
436 detects as binary. With -a, diff will generate a diff anyway, probably
431 with undesirable results.
437 with undesirable results.
432
438
433 Use the -g/--git option to generate diffs in the git extended diff format.
439 Use the -g/--git option to generate diffs in the git extended diff format.
434 For more information, read "hg help diffs".
440 For more information, read "hg help diffs".
435
441
436 Returns 0 on success.
442 Returns 0 on success.
437
443
438 options:
444 options:
439
445
440 -r --rev REV [+] revision
446 -r --rev REV [+] revision
441 -c --change REV change made by revision
447 -c --change REV change made by revision
442 -a --text treat all files as text
448 -a --text treat all files as text
443 -g --git use git extended diff format
449 -g --git use git extended diff format
444 --nodates omit dates from diff headers
450 --nodates omit dates from diff headers
445 -p --show-function show which function each change is in
451 -p --show-function show which function each change is in
446 --reverse produce a diff that undoes the changes
452 --reverse produce a diff that undoes the changes
447 -w --ignore-all-space ignore white space when comparing lines
453 -w --ignore-all-space ignore white space when comparing lines
448 -b --ignore-space-change ignore changes in the amount of white space
454 -b --ignore-space-change ignore changes in the amount of white space
449 -B --ignore-blank-lines ignore changes whose lines are all blank
455 -B --ignore-blank-lines ignore changes whose lines are all blank
450 -U --unified NUM number of lines of context to show
456 -U --unified NUM number of lines of context to show
451 --stat output diffstat-style summary of changes
457 --stat output diffstat-style summary of changes
452 -I --include PATTERN [+] include names matching the given patterns
458 -I --include PATTERN [+] include names matching the given patterns
453 -X --exclude PATTERN [+] exclude names matching the given patterns
459 -X --exclude PATTERN [+] exclude names matching the given patterns
454 -S --subrepos recurse into subrepositories
460 -S --subrepos recurse into subrepositories
455
461
456 [+] marked option can be specified multiple times
462 [+] marked option can be specified multiple times
457
463
458 use "hg -v help diff" to show more info
464 use "hg -v help diff" to show more info
459
465
460 $ hg help status
466 $ hg help status
461 hg status [OPTION]... [FILE]...
467 hg status [OPTION]... [FILE]...
462
468
463 aliases: st
469 aliases: st
464
470
465 show changed files in the working directory
471 show changed files in the working directory
466
472
467 Show status of files in the repository. If names are given, only files
473 Show status of files in the repository. If names are given, only files
468 that match are shown. Files that are clean or ignored or the source of a
474 that match are shown. Files that are clean or ignored or the source of a
469 copy/move operation, are not listed unless -c/--clean, -i/--ignored,
475 copy/move operation, are not listed unless -c/--clean, -i/--ignored,
470 -C/--copies or -A/--all are given. Unless options described with "show
476 -C/--copies or -A/--all are given. Unless options described with "show
471 only ..." are given, the options -mardu are used.
477 only ..." are given, the options -mardu are used.
472
478
473 Option -q/--quiet hides untracked (unknown and ignored) files unless
479 Option -q/--quiet hides untracked (unknown and ignored) files unless
474 explicitly requested with -u/--unknown or -i/--ignored.
480 explicitly requested with -u/--unknown or -i/--ignored.
475
481
476 Note:
482 Note:
477 status may appear to disagree with diff if permissions have changed or
483 status may appear to disagree with diff if permissions have changed or
478 a merge has occurred. The standard diff format does not report
484 a merge has occurred. The standard diff format does not report
479 permission changes and diff only reports changes relative to one merge
485 permission changes and diff only reports changes relative to one merge
480 parent.
486 parent.
481
487
482 If one revision is given, it is used as the base revision. If two
488 If one revision is given, it is used as the base revision. If two
483 revisions are given, the differences between them are shown. The --change
489 revisions are given, the differences between them are shown. The --change
484 option can also be used as a shortcut to list the changed files of a
490 option can also be used as a shortcut to list the changed files of a
485 revision from its first parent.
491 revision from its first parent.
486
492
487 The codes used to show the status of files are:
493 The codes used to show the status of files are:
488
494
489 M = modified
495 M = modified
490 A = added
496 A = added
491 R = removed
497 R = removed
492 C = clean
498 C = clean
493 ! = missing (deleted by non-hg command, but still tracked)
499 ! = missing (deleted by non-hg command, but still tracked)
494 ? = not tracked
500 ? = not tracked
495 I = ignored
501 I = ignored
496 = origin of the previous file listed as A (added)
502 = origin of the previous file listed as A (added)
497
503
498 Returns 0 on success.
504 Returns 0 on success.
499
505
500 options:
506 options:
501
507
502 -A --all show status of all files
508 -A --all show status of all files
503 -m --modified show only modified files
509 -m --modified show only modified files
504 -a --added show only added files
510 -a --added show only added files
505 -r --removed show only removed files
511 -r --removed show only removed files
506 -d --deleted show only deleted (but tracked) files
512 -d --deleted show only deleted (but tracked) files
507 -c --clean show only files without changes
513 -c --clean show only files without changes
508 -u --unknown show only unknown (not tracked) files
514 -u --unknown show only unknown (not tracked) files
509 -i --ignored show only ignored files
515 -i --ignored show only ignored files
510 -n --no-status hide status prefix
516 -n --no-status hide status prefix
511 -C --copies show source of copied files
517 -C --copies show source of copied files
512 -0 --print0 end filenames with NUL, for use with xargs
518 -0 --print0 end filenames with NUL, for use with xargs
513 --rev REV [+] show difference from revision
519 --rev REV [+] show difference from revision
514 --change REV list the changed files of a revision
520 --change REV list the changed files of a revision
515 -I --include PATTERN [+] include names matching the given patterns
521 -I --include PATTERN [+] include names matching the given patterns
516 -X --exclude PATTERN [+] exclude names matching the given patterns
522 -X --exclude PATTERN [+] exclude names matching the given patterns
517 -S --subrepos recurse into subrepositories
523 -S --subrepos recurse into subrepositories
518
524
519 [+] marked option can be specified multiple times
525 [+] marked option can be specified multiple times
520
526
521 use "hg -v help status" to show more info
527 use "hg -v help status" to show more info
522
528
523 $ hg -q help status
529 $ hg -q help status
524 hg status [OPTION]... [FILE]...
530 hg status [OPTION]... [FILE]...
525
531
526 show changed files in the working directory
532 show changed files in the working directory
527
533
528 $ hg help foo
534 $ hg help foo
529 hg: unknown command 'foo'
535 hg: unknown command 'foo'
530 Mercurial Distributed SCM
536 Mercurial Distributed SCM
531
537
532 basic commands:
538 basic commands:
533
539
534 add add the specified files on the next commit
540 add add the specified files on the next commit
535 annotate show changeset information by line for each file
541 annotate show changeset information by line for each file
536 clone make a copy of an existing repository
542 clone make a copy of an existing repository
537 commit commit the specified files or all outstanding changes
543 commit commit the specified files or all outstanding changes
538 diff diff repository (or selected files)
544 diff diff repository (or selected files)
539 export dump the header and diffs for one or more changesets
545 export dump the header and diffs for one or more changesets
540 forget forget the specified files on the next commit
546 forget forget the specified files on the next commit
541 init create a new repository in the given directory
547 init create a new repository in the given directory
542 log show revision history of entire repository or files
548 log show revision history of entire repository or files
543 merge merge working directory with another revision
549 merge merge working directory with another revision
550 phase set or show the current phase name
544 pull pull changes from the specified source
551 pull pull changes from the specified source
545 push push changes to the specified destination
552 push push changes to the specified destination
546 remove remove the specified files on the next commit
553 remove remove the specified files on the next commit
547 serve start stand-alone webserver
554 serve start stand-alone webserver
548 status show changed files in the working directory
555 status show changed files in the working directory
549 summary summarize working directory state
556 summary summarize working directory state
550 update update working directory (or switch revisions)
557 update update working directory (or switch revisions)
551
558
552 use "hg help" for the full list of commands or "hg -v" for details
559 use "hg help" for the full list of commands or "hg -v" for details
553 [255]
560 [255]
554
561
555 $ hg skjdfks
562 $ hg skjdfks
556 hg: unknown command 'skjdfks'
563 hg: unknown command 'skjdfks'
557 Mercurial Distributed SCM
564 Mercurial Distributed SCM
558
565
559 basic commands:
566 basic commands:
560
567
561 add add the specified files on the next commit
568 add add the specified files on the next commit
562 annotate show changeset information by line for each file
569 annotate show changeset information by line for each file
563 clone make a copy of an existing repository
570 clone make a copy of an existing repository
564 commit commit the specified files or all outstanding changes
571 commit commit the specified files or all outstanding changes
565 diff diff repository (or selected files)
572 diff diff repository (or selected files)
566 export dump the header and diffs for one or more changesets
573 export dump the header and diffs for one or more changesets
567 forget forget the specified files on the next commit
574 forget forget the specified files on the next commit
568 init create a new repository in the given directory
575 init create a new repository in the given directory
569 log show revision history of entire repository or files
576 log show revision history of entire repository or files
570 merge merge working directory with another revision
577 merge merge working directory with another revision
578 phase set or show the current phase name
571 pull pull changes from the specified source
579 pull pull changes from the specified source
572 push push changes to the specified destination
580 push push changes to the specified destination
573 remove remove the specified files on the next commit
581 remove remove the specified files on the next commit
574 serve start stand-alone webserver
582 serve start stand-alone webserver
575 status show changed files in the working directory
583 status show changed files in the working directory
576 summary summarize working directory state
584 summary summarize working directory state
577 update update working directory (or switch revisions)
585 update update working directory (or switch revisions)
578
586
579 use "hg help" for the full list of commands or "hg -v" for details
587 use "hg help" for the full list of commands or "hg -v" for details
580 [255]
588 [255]
581
589
582 $ cat > helpext.py <<EOF
590 $ cat > helpext.py <<EOF
583 > import os
591 > import os
584 > from mercurial import commands
592 > from mercurial import commands
585 >
593 >
586 > def nohelp(ui, *args, **kwargs):
594 > def nohelp(ui, *args, **kwargs):
587 > pass
595 > pass
588 >
596 >
589 > cmdtable = {
597 > cmdtable = {
590 > "nohelp": (nohelp, [], "hg nohelp"),
598 > "nohelp": (nohelp, [], "hg nohelp"),
591 > }
599 > }
592 >
600 >
593 > commands.norepo += ' nohelp'
601 > commands.norepo += ' nohelp'
594 > EOF
602 > EOF
595 $ echo '[extensions]' >> $HGRCPATH
603 $ echo '[extensions]' >> $HGRCPATH
596 $ echo "helpext = `pwd`/helpext.py" >> $HGRCPATH
604 $ echo "helpext = `pwd`/helpext.py" >> $HGRCPATH
597
605
598 Test command with no help text
606 Test command with no help text
599
607
600 $ hg help nohelp
608 $ hg help nohelp
601 hg nohelp
609 hg nohelp
602
610
603 (no help text available)
611 (no help text available)
604
612
605 use "hg -v help nohelp" to show more info
613 use "hg -v help nohelp" to show more info
606
614
607 Test that default list of commands omits extension commands
615 Test that default list of commands omits extension commands
608
616
609 $ hg help
617 $ hg help
610 Mercurial Distributed SCM
618 Mercurial Distributed SCM
611
619
612 list of commands:
620 list of commands:
613
621
614 add add the specified files on the next commit
622 add add the specified files on the next commit
615 addremove add all new files, delete all missing files
623 addremove add all new files, delete all missing files
616 annotate show changeset information by line for each file
624 annotate show changeset information by line for each file
617 archive create an unversioned archive of a repository revision
625 archive create an unversioned archive of a repository revision
618 backout reverse effect of earlier changeset
626 backout reverse effect of earlier changeset
619 bisect subdivision search of changesets
627 bisect subdivision search of changesets
620 bookmarks track a line of development with movable markers
628 bookmarks track a line of development with movable markers
621 branch set or show the current branch name
629 branch set or show the current branch name
622 branches list repository named branches
630 branches list repository named branches
623 bundle create a changegroup file
631 bundle create a changegroup file
624 cat output the current or given revision of files
632 cat output the current or given revision of files
625 clone make a copy of an existing repository
633 clone make a copy of an existing repository
626 commit commit the specified files or all outstanding changes
634 commit commit the specified files or all outstanding changes
627 copy mark files as copied for the next commit
635 copy mark files as copied for the next commit
628 diff diff repository (or selected files)
636 diff diff repository (or selected files)
629 export dump the header and diffs for one or more changesets
637 export dump the header and diffs for one or more changesets
630 forget forget the specified files on the next commit
638 forget forget the specified files on the next commit
631 graft copy changes from other branches onto the current branch
639 graft copy changes from other branches onto the current branch
632 grep search for a pattern in specified files and revisions
640 grep search for a pattern in specified files and revisions
633 heads show current repository heads or show branch heads
641 heads show current repository heads or show branch heads
634 help show help for a given topic or a help overview
642 help show help for a given topic or a help overview
635 identify identify the working copy or specified revision
643 identify identify the working copy or specified revision
636 import import an ordered set of patches
644 import import an ordered set of patches
637 incoming show new changesets found in source
645 incoming show new changesets found in source
638 init create a new repository in the given directory
646 init create a new repository in the given directory
639 locate locate files matching specific patterns
647 locate locate files matching specific patterns
640 log show revision history of entire repository or files
648 log show revision history of entire repository or files
641 manifest output the current or given revision of the project manifest
649 manifest output the current or given revision of the project manifest
642 merge merge working directory with another revision
650 merge merge working directory with another revision
643 outgoing show changesets not found in the destination
651 outgoing show changesets not found in the destination
644 parents show the parents of the working directory or revision
652 parents show the parents of the working directory or revision
645 paths show aliases for remote repositories
653 paths show aliases for remote repositories
654 phase set or show the current phase name
646 pull pull changes from the specified source
655 pull pull changes from the specified source
647 push push changes to the specified destination
656 push push changes to the specified destination
648 recover roll back an interrupted transaction
657 recover roll back an interrupted transaction
649 remove remove the specified files on the next commit
658 remove remove the specified files on the next commit
650 rename rename files; equivalent of copy + remove
659 rename rename files; equivalent of copy + remove
651 resolve redo merges or set/view the merge status of files
660 resolve redo merges or set/view the merge status of files
652 revert restore files to their checkout state
661 revert restore files to their checkout state
653 rollback roll back the last transaction (dangerous)
662 rollback roll back the last transaction (dangerous)
654 root print the root (top) of the current working directory
663 root print the root (top) of the current working directory
655 serve start stand-alone webserver
664 serve start stand-alone webserver
656 showconfig show combined config settings from all hgrc files
665 showconfig show combined config settings from all hgrc files
657 status show changed files in the working directory
666 status show changed files in the working directory
658 summary summarize working directory state
667 summary summarize working directory state
659 tag add one or more tags for the current or given revision
668 tag add one or more tags for the current or given revision
660 tags list repository tags
669 tags list repository tags
661 tip show the tip revision
670 tip show the tip revision
662 unbundle apply one or more changegroup files
671 unbundle apply one or more changegroup files
663 update update working directory (or switch revisions)
672 update update working directory (or switch revisions)
664 verify verify the integrity of the repository
673 verify verify the integrity of the repository
665 version output version and copyright information
674 version output version and copyright information
666
675
667 enabled extensions:
676 enabled extensions:
668
677
669 helpext (no help text available)
678 helpext (no help text available)
670
679
671 additional help topics:
680 additional help topics:
672
681
673 config Configuration Files
682 config Configuration Files
674 dates Date Formats
683 dates Date Formats
675 diffs Diff Formats
684 diffs Diff Formats
676 environment Environment Variables
685 environment Environment Variables
677 extensions Using additional features
686 extensions Using additional features
678 filesets Specifying File Sets
687 filesets Specifying File Sets
679 glossary Glossary
688 glossary Glossary
680 hgignore syntax for Mercurial ignore files
689 hgignore syntax for Mercurial ignore files
681 hgweb Configuring hgweb
690 hgweb Configuring hgweb
682 merge-tools Merge Tools
691 merge-tools Merge Tools
683 multirevs Specifying Multiple Revisions
692 multirevs Specifying Multiple Revisions
684 patterns File Name Patterns
693 patterns File Name Patterns
685 revisions Specifying Single Revisions
694 revisions Specifying Single Revisions
686 revsets Specifying Revision Sets
695 revsets Specifying Revision Sets
687 subrepos Subrepositories
696 subrepos Subrepositories
688 templating Template Usage
697 templating Template Usage
689 urls URL Paths
698 urls URL Paths
690
699
691 use "hg -v help" to show builtin aliases and global options
700 use "hg -v help" to show builtin aliases and global options
692
701
693
702
694
703
695 Test list of commands with command with no help text
704 Test list of commands with command with no help text
696
705
697 $ hg help helpext
706 $ hg help helpext
698 helpext extension - no help text available
707 helpext extension - no help text available
699
708
700 list of commands:
709 list of commands:
701
710
702 nohelp (no help text available)
711 nohelp (no help text available)
703
712
704 use "hg -v help helpext" to show builtin aliases and global options
713 use "hg -v help helpext" to show builtin aliases and global options
705
714
706 Test a help topic
715 Test a help topic
707
716
708 $ hg help revs
717 $ hg help revs
709 Specifying Single Revisions
718 Specifying Single Revisions
710
719
711 Mercurial supports several ways to specify individual revisions.
720 Mercurial supports several ways to specify individual revisions.
712
721
713 A plain integer is treated as a revision number. Negative integers are
722 A plain integer is treated as a revision number. Negative integers are
714 treated as sequential offsets from the tip, with -1 denoting the tip, -2
723 treated as sequential offsets from the tip, with -1 denoting the tip, -2
715 denoting the revision prior to the tip, and so forth.
724 denoting the revision prior to the tip, and so forth.
716
725
717 A 40-digit hexadecimal string is treated as a unique revision identifier.
726 A 40-digit hexadecimal string is treated as a unique revision identifier.
718
727
719 A hexadecimal string less than 40 characters long is treated as a unique
728 A hexadecimal string less than 40 characters long is treated as a unique
720 revision identifier and is referred to as a short-form identifier. A
729 revision identifier and is referred to as a short-form identifier. A
721 short-form identifier is only valid if it is the prefix of exactly one
730 short-form identifier is only valid if it is the prefix of exactly one
722 full-length identifier.
731 full-length identifier.
723
732
724 Any other string is treated as a tag or branch name. A tag name is a
733 Any other string is treated as a tag or branch name. A tag name is a
725 symbolic name associated with a revision identifier. A branch name denotes
734 symbolic name associated with a revision identifier. A branch name denotes
726 the tipmost revision of that branch. Tag and branch names must not contain
735 the tipmost revision of that branch. Tag and branch names must not contain
727 the ":" character.
736 the ":" character.
728
737
729 The reserved name "tip" is a special tag that always identifies the most
738 The reserved name "tip" is a special tag that always identifies the most
730 recent revision.
739 recent revision.
731
740
732 The reserved name "null" indicates the null revision. This is the revision
741 The reserved name "null" indicates the null revision. This is the revision
733 of an empty repository, and the parent of revision 0.
742 of an empty repository, and the parent of revision 0.
734
743
735 The reserved name "." indicates the working directory parent. If no
744 The reserved name "." indicates the working directory parent. If no
736 working directory is checked out, it is equivalent to null. If an
745 working directory is checked out, it is equivalent to null. If an
737 uncommitted merge is in progress, "." is the revision of the first parent.
746 uncommitted merge is in progress, "." is the revision of the first parent.
738
747
739 Test templating help
748 Test templating help
740
749
741 $ hg help templating | egrep '(desc|diffstat|firstline|nonempty) '
750 $ hg help templating | egrep '(desc|diffstat|firstline|nonempty) '
742 desc String. The text of the changeset description.
751 desc String. The text of the changeset description.
743 diffstat String. Statistics of changes with the following format:
752 diffstat String. Statistics of changes with the following format:
744 firstline Any text. Returns the first line of text.
753 firstline Any text. Returns the first line of text.
745 nonempty Any text. Returns '(none)' if the string is empty.
754 nonempty Any text. Returns '(none)' if the string is empty.
746
755
747 Test help hooks
756 Test help hooks
748
757
749 $ cat > helphook1.py <<EOF
758 $ cat > helphook1.py <<EOF
750 > from mercurial import help
759 > from mercurial import help
751 >
760 >
752 > def rewrite(topic, doc):
761 > def rewrite(topic, doc):
753 > return doc + '\nhelphook1\n'
762 > return doc + '\nhelphook1\n'
754 >
763 >
755 > def extsetup(ui):
764 > def extsetup(ui):
756 > help.addtopichook('revsets', rewrite)
765 > help.addtopichook('revsets', rewrite)
757 > EOF
766 > EOF
758 $ cat > helphook2.py <<EOF
767 $ cat > helphook2.py <<EOF
759 > from mercurial import help
768 > from mercurial import help
760 >
769 >
761 > def rewrite(topic, doc):
770 > def rewrite(topic, doc):
762 > return doc + '\nhelphook2\n'
771 > return doc + '\nhelphook2\n'
763 >
772 >
764 > def extsetup(ui):
773 > def extsetup(ui):
765 > help.addtopichook('revsets', rewrite)
774 > help.addtopichook('revsets', rewrite)
766 > EOF
775 > EOF
767 $ echo '[extensions]' >> $HGRCPATH
776 $ echo '[extensions]' >> $HGRCPATH
768 $ echo "helphook1 = `pwd`/helphook1.py" >> $HGRCPATH
777 $ echo "helphook1 = `pwd`/helphook1.py" >> $HGRCPATH
769 $ echo "helphook2 = `pwd`/helphook2.py" >> $HGRCPATH
778 $ echo "helphook2 = `pwd`/helphook2.py" >> $HGRCPATH
770 $ hg help revsets | grep helphook
779 $ hg help revsets | grep helphook
771 helphook1
780 helphook1
772 helphook2
781 helphook2
@@ -1,156 +1,262
1 $ alias hglog='hg log --template "{rev} {phaseidx} {desc}\n"'
1 $ alias hglog='hg log --template "{rev} {phaseidx} {desc}\n"'
2 $ mkcommit() {
2 $ mkcommit() {
3 > echo "$1" > "$1"
3 > echo "$1" > "$1"
4 > hg add "$1"
4 > hg add "$1"
5 > message="$1"
5 > message="$1"
6 > shift
6 > shift
7 > hg ci -m "$message" $*
7 > hg ci -m "$message" $*
8 > }
8 > }
9
9
10 $ hg init initialrepo
10 $ hg init initialrepo
11 $ cd initialrepo
11 $ cd initialrepo
12 $ mkcommit A
12 $ mkcommit A
13
13
14 New commit are draft by default
14 New commit are draft by default
15
15
16 $ hglog
16 $ hglog
17 0 1 A
17 0 1 A
18
18
19 Following commit are draft too
19 Following commit are draft too
20
20
21 $ mkcommit B
21 $ mkcommit B
22
22
23 $ hglog
23 $ hglog
24 1 1 B
24 1 1 B
25 0 1 A
25 0 1 A
26
26
27 Draft commit are properly created over public one:
27 Draft commit are properly created over public one:
28
28
29 $ hg pull -q . # XXX use the dedicated phase command once available
29 $ hg phase --public .
30 $ hglog
30 $ hglog
31 1 0 B
31 1 0 B
32 0 0 A
32 0 0 A
33
33
34 $ mkcommit C
34 $ mkcommit C
35 $ mkcommit D
35 $ mkcommit D
36
36
37 $ hglog
37 $ hglog
38 3 1 D
38 3 1 D
39 2 1 C
39 2 1 C
40 1 0 B
40 1 0 B
41 0 0 A
41 0 0 A
42
42
43 Test creating changeset as secret
43 Test creating changeset as secret
44
44
45 $ mkcommit E --config phases.new-commit=2
45 $ mkcommit E --config phases.new-commit=2
46 $ hglog
46 $ hglog
47 4 2 E
47 4 2 E
48 3 1 D
48 3 1 D
49 2 1 C
49 2 1 C
50 1 0 B
50 1 0 B
51 0 0 A
51 0 0 A
52
52
53 Test the secret property is inherited
53 Test the secret property is inherited
54
54
55 $ mkcommit H
55 $ mkcommit H
56 $ hglog
56 $ hglog
57 5 2 H
57 5 2 H
58 4 2 E
58 4 2 E
59 3 1 D
59 3 1 D
60 2 1 C
60 2 1 C
61 1 0 B
61 1 0 B
62 0 0 A
62 0 0 A
63
63
64 Even on merge
64 Even on merge
65
65
66 $ hg up -q 1
66 $ hg up -q 1
67 $ mkcommit "B'"
67 $ mkcommit "B'"
68 created new head
68 created new head
69 $ hglog
69 $ hglog
70 6 1 B'
70 6 1 B'
71 5 2 H
71 5 2 H
72 4 2 E
72 4 2 E
73 3 1 D
73 3 1 D
74 2 1 C
74 2 1 C
75 1 0 B
75 1 0 B
76 0 0 A
76 0 0 A
77 $ hg merge 4 # E
77 $ hg merge 4 # E
78 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
78 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
79 (branch merge, don't forget to commit)
79 (branch merge, don't forget to commit)
80 $ hg ci -m "merge B' and E"
80 $ hg ci -m "merge B' and E"
81 $ hglog
81 $ hglog
82 7 2 merge B' and E
82 7 2 merge B' and E
83 6 1 B'
83 6 1 B'
84 5 2 H
84 5 2 H
85 4 2 E
85 4 2 E
86 3 1 D
86 3 1 D
87 2 1 C
87 2 1 C
88 1 0 B
88 1 0 B
89 0 0 A
89 0 0 A
90
90
91 Test secret changeset are not pushed
91 Test secret changeset are not pushed
92
92
93 $ hg init ../push-dest
93 $ hg init ../push-dest
94 $ cat > ../push-dest/.hg/hgrc << EOF
94 $ cat > ../push-dest/.hg/hgrc << EOF
95 > [phases]
95 > [phases]
96 > publish=False
96 > publish=False
97 > EOF
97 > EOF
98 $ hg push ../push-dest -f # force because we push multiple heads
98 $ hg push ../push-dest -f # force because we push multiple heads
99 pushing to ../push-dest
99 pushing to ../push-dest
100 searching for changes
100 searching for changes
101 adding changesets
101 adding changesets
102 adding manifests
102 adding manifests
103 adding file changes
103 adding file changes
104 added 5 changesets with 5 changes to 5 files (+1 heads)
104 added 5 changesets with 5 changes to 5 files (+1 heads)
105 $ hglog
105 $ hglog
106 7 2 merge B' and E
106 7 2 merge B' and E
107 6 1 B'
107 6 1 B'
108 5 2 H
108 5 2 H
109 4 2 E
109 4 2 E
110 3 1 D
110 3 1 D
111 2 1 C
111 2 1 C
112 1 0 B
112 1 0 B
113 0 0 A
113 0 0 A
114 $ cd ../push-dest
114 $ cd ../push-dest
115 $ hglog
115 $ hglog
116 4 1 B'
116 4 1 B'
117 3 1 D
117 3 1 D
118 2 1 C
118 2 1 C
119 1 0 B
119 1 0 B
120 0 0 A
120 0 0 A
121 $ cd ..
121 $ cd ..
122
122
123 Test secret changeset are not pull
123 Test secret changeset are not pull
124
124
125 $ hg init pull-dest
125 $ hg init pull-dest
126 $ cd pull-dest
126 $ cd pull-dest
127 $ hg pull ../initialrepo
127 $ hg pull ../initialrepo
128 pulling from ../initialrepo
128 pulling from ../initialrepo
129 requesting all changes
129 requesting all changes
130 adding changesets
130 adding changesets
131 adding manifests
131 adding manifests
132 adding file changes
132 adding file changes
133 added 5 changesets with 5 changes to 5 files (+1 heads)
133 added 5 changesets with 5 changes to 5 files (+1 heads)
134 (run 'hg heads' to see heads, 'hg merge' to merge)
134 (run 'hg heads' to see heads, 'hg merge' to merge)
135 $ hglog
135 $ hglog
136 4 0 B'
136 4 0 B'
137 3 0 D
137 3 0 D
138 2 0 C
138 2 0 C
139 1 0 B
139 1 0 B
140 0 0 A
140 0 0 A
141 $ cd ..
141 $ cd ..
142
142
143 Test revset
143 Test revset
144
144
145 $ cd initialrepo
145 $ cd initialrepo
146 $ hglog -r 'public()'
146 $ hglog -r 'public()'
147 0 0 A
147 0 0 A
148 1 0 B
148 1 0 B
149 $ hglog -r 'draft()'
149 $ hglog -r 'draft()'
150 2 1 C
150 2 1 C
151 3 1 D
151 3 1 D
152 6 1 B'
152 6 1 B'
153 $ hglog -r 'secret()'
153 $ hglog -r 'secret()'
154 4 2 E
154 4 2 E
155 5 2 H
155 5 2 H
156 7 2 merge B' and E
156 7 2 merge B' and E
157
158 Test phase command
159 ===================
160
161 initial picture
162
163 $ cat >> $HGRCPATH << EOF
164 > [extensions]
165 > hgext.graphlog=
166 > EOF
167 $ hg log -G --template "{rev} {phase} {desc}\n"
168 @ 7 secret merge B' and E
169 |\
170 | o 6 draft B'
171 | |
172 +---o 5 secret H
173 | |
174 o | 4 secret E
175 | |
176 o | 3 draft D
177 | |
178 o | 2 draft C
179 |/
180 o 1 public B
181 |
182 o 0 public A
183
184
185 display changesets phase
186
187 (mixing -r and plain rev specification)
188
189 $ hg phase 1::4 -r 7
190 1: public
191 2: draft
192 3: draft
193 4: secret
194 7: secret
195
196
197 move changeset forward
198
199 (with -r option)
200
201 $ hg phase --public -r 2
202 $ hg log -G --template "{rev} {phase} {desc}\n"
203 @ 7 secret merge B' and E
204 |\
205 | o 6 draft B'
206 | |
207 +---o 5 secret H
208 | |
209 o | 4 secret E
210 | |
211 o | 3 draft D
212 | |
213 o | 2 public C
214 |/
215 o 1 public B
216 |
217 o 0 public A
218
219
220 move changeset backward
221
222 (without -r option)
223
224 $ hg phase --draft --force 2
225 $ hg log -G --template "{rev} {phase} {desc}\n"
226 @ 7 secret merge B' and E
227 |\
228 | o 6 draft B'
229 | |
230 +---o 5 secret H
231 | |
232 o | 4 secret E
233 | |
234 o | 3 draft D
235 | |
236 o | 2 draft C
237 |/
238 o 1 public B
239 |
240 o 0 public A
241
242
243 move changeset forward and backward
244
245 $ hg phase --draft --force 1::4
246 $ hg log -G --template "{rev} {phase} {desc}\n"
247 @ 7 secret merge B' and E
248 |\
249 | o 6 draft B'
250 | |
251 +---o 5 secret H
252 | |
253 o | 4 draft E
254 | |
255 o | 3 draft D
256 | |
257 o | 2 draft C
258 |/
259 o 1 draft B
260 |
261 o 0 public A
262
@@ -1,45 +1,46
1 $ hg init
1 $ hg init
2
2
3 $ echo a > a
3 $ echo a > a
4 $ hg ci -Ama
4 $ hg ci -Ama
5 adding a
5 adding a
6
6
7 $ hg an a
7 $ hg an a
8 0: a
8 0: a
9
9
10 $ echo "[ui]" >> $HGRCPATH
10 $ echo "[ui]" >> $HGRCPATH
11 $ echo "strict=True" >> $HGRCPATH
11 $ echo "strict=True" >> $HGRCPATH
12
12
13 $ hg an a
13 $ hg an a
14 hg: unknown command 'an'
14 hg: unknown command 'an'
15 Mercurial Distributed SCM
15 Mercurial Distributed SCM
16
16
17 basic commands:
17 basic commands:
18
18
19 add add the specified files on the next commit
19 add add the specified files on the next commit
20 annotate show changeset information by line for each file
20 annotate show changeset information by line for each file
21 clone make a copy of an existing repository
21 clone make a copy of an existing repository
22 commit commit the specified files or all outstanding changes
22 commit commit the specified files or all outstanding changes
23 diff diff repository (or selected files)
23 diff diff repository (or selected files)
24 export dump the header and diffs for one or more changesets
24 export dump the header and diffs for one or more changesets
25 forget forget the specified files on the next commit
25 forget forget the specified files on the next commit
26 init create a new repository in the given directory
26 init create a new repository in the given directory
27 log show revision history of entire repository or files
27 log show revision history of entire repository or files
28 merge merge working directory with another revision
28 merge merge working directory with another revision
29 phase set or show the current phase name
29 pull pull changes from the specified source
30 pull pull changes from the specified source
30 push push changes to the specified destination
31 push push changes to the specified destination
31 remove remove the specified files on the next commit
32 remove remove the specified files on the next commit
32 serve start stand-alone webserver
33 serve start stand-alone webserver
33 status show changed files in the working directory
34 status show changed files in the working directory
34 summary summarize working directory state
35 summary summarize working directory state
35 update update working directory (or switch revisions)
36 update update working directory (or switch revisions)
36
37
37 use "hg help" for the full list of commands or "hg -v" for details
38 use "hg help" for the full list of commands or "hg -v" for details
38 [255]
39 [255]
39 $ hg annotate a
40 $ hg annotate a
40 0: a
41 0: a
41
42
42 should succeed - up is an alias, not an abbreviation
43 should succeed - up is an alias, not an abbreviation
43
44
44 $ hg up
45 $ hg up
45 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
46 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
General Comments 0
You need to be logged in to leave comments. Login now