##// END OF EJS Templates
status: improve explanation of ' ' status...
Matt Mackall -
r20660:19e9478c default
parent child Browse files
Show More
@@ -1,5882 +1,5882 b''
1 # commands.py - command processing for mercurial
1 # commands.py - command processing for mercurial
2 #
2 #
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 from node import hex, 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 _
10 from i18n import _
11 import os, re, difflib, time, tempfile, errno
11 import os, re, difflib, time, tempfile, errno
12 import hg, scmutil, util, revlog, copies, error, bookmarks
12 import hg, scmutil, util, revlog, copies, error, bookmarks
13 import patch, help, encoding, templatekw, discovery
13 import patch, help, encoding, templatekw, discovery
14 import archival, changegroup, cmdutil, hbisect
14 import archival, changegroup, cmdutil, hbisect
15 import sshserver, hgweb, commandserver
15 import sshserver, hgweb, commandserver
16 from hgweb import server as hgweb_server
16 from hgweb import server as hgweb_server
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, graphmod
19 import dagparser, context, simplemerge, graphmod
20 import random
20 import random
21 import setdiscovery, treediscovery, dagutil, pvec, localrepo
21 import setdiscovery, treediscovery, dagutil, pvec, localrepo
22 import phases, obsolete
22 import phases, obsolete
23
23
24 table = {}
24 table = {}
25
25
26 command = cmdutil.command(table)
26 command = cmdutil.command(table)
27
27
28 # common command options
28 # common command options
29
29
30 globalopts = [
30 globalopts = [
31 ('R', 'repository', '',
31 ('R', 'repository', '',
32 _('repository root directory or name of overlay bundle file'),
32 _('repository root directory or name of overlay bundle file'),
33 _('REPO')),
33 _('REPO')),
34 ('', 'cwd', '',
34 ('', 'cwd', '',
35 _('change working directory'), _('DIR')),
35 _('change working directory'), _('DIR')),
36 ('y', 'noninteractive', None,
36 ('y', 'noninteractive', None,
37 _('do not prompt, automatically pick the first choice for all prompts')),
37 _('do not prompt, automatically pick the first choice for all prompts')),
38 ('q', 'quiet', None, _('suppress output')),
38 ('q', 'quiet', None, _('suppress output')),
39 ('v', 'verbose', None, _('enable additional output')),
39 ('v', 'verbose', None, _('enable additional output')),
40 ('', 'config', [],
40 ('', 'config', [],
41 _('set/override config option (use \'section.name=value\')'),
41 _('set/override config option (use \'section.name=value\')'),
42 _('CONFIG')),
42 _('CONFIG')),
43 ('', 'debug', None, _('enable debugging output')),
43 ('', 'debug', None, _('enable debugging output')),
44 ('', 'debugger', None, _('start debugger')),
44 ('', 'debugger', None, _('start debugger')),
45 ('', 'encoding', encoding.encoding, _('set the charset encoding'),
45 ('', 'encoding', encoding.encoding, _('set the charset encoding'),
46 _('ENCODE')),
46 _('ENCODE')),
47 ('', 'encodingmode', encoding.encodingmode,
47 ('', 'encodingmode', encoding.encodingmode,
48 _('set the charset encoding mode'), _('MODE')),
48 _('set the charset encoding mode'), _('MODE')),
49 ('', 'traceback', None, _('always print a traceback on exception')),
49 ('', 'traceback', None, _('always print a traceback on exception')),
50 ('', 'time', None, _('time how long the command takes')),
50 ('', 'time', None, _('time how long the command takes')),
51 ('', 'profile', None, _('print command execution profile')),
51 ('', 'profile', None, _('print command execution profile')),
52 ('', 'version', None, _('output version information and exit')),
52 ('', 'version', None, _('output version information and exit')),
53 ('h', 'help', None, _('display help and exit')),
53 ('h', 'help', None, _('display help and exit')),
54 ('', 'hidden', False, _('consider hidden changesets')),
54 ('', 'hidden', False, _('consider hidden changesets')),
55 ]
55 ]
56
56
57 dryrunopts = [('n', 'dry-run', None,
57 dryrunopts = [('n', 'dry-run', None,
58 _('do not perform actions, just print output'))]
58 _('do not perform actions, just print output'))]
59
59
60 remoteopts = [
60 remoteopts = [
61 ('e', 'ssh', '',
61 ('e', 'ssh', '',
62 _('specify ssh command to use'), _('CMD')),
62 _('specify ssh command to use'), _('CMD')),
63 ('', 'remotecmd', '',
63 ('', 'remotecmd', '',
64 _('specify hg command to run on the remote side'), _('CMD')),
64 _('specify hg command to run on the remote side'), _('CMD')),
65 ('', 'insecure', None,
65 ('', 'insecure', None,
66 _('do not verify server certificate (ignoring web.cacerts config)')),
66 _('do not verify server certificate (ignoring web.cacerts config)')),
67 ]
67 ]
68
68
69 walkopts = [
69 walkopts = [
70 ('I', 'include', [],
70 ('I', 'include', [],
71 _('include names matching the given patterns'), _('PATTERN')),
71 _('include names matching the given patterns'), _('PATTERN')),
72 ('X', 'exclude', [],
72 ('X', 'exclude', [],
73 _('exclude names matching the given patterns'), _('PATTERN')),
73 _('exclude names matching the given patterns'), _('PATTERN')),
74 ]
74 ]
75
75
76 commitopts = [
76 commitopts = [
77 ('m', 'message', '',
77 ('m', 'message', '',
78 _('use text as commit message'), _('TEXT')),
78 _('use text as commit message'), _('TEXT')),
79 ('l', 'logfile', '',
79 ('l', 'logfile', '',
80 _('read commit message from file'), _('FILE')),
80 _('read commit message from file'), _('FILE')),
81 ]
81 ]
82
82
83 commitopts2 = [
83 commitopts2 = [
84 ('d', 'date', '',
84 ('d', 'date', '',
85 _('record the specified date as commit date'), _('DATE')),
85 _('record the specified date as commit date'), _('DATE')),
86 ('u', 'user', '',
86 ('u', 'user', '',
87 _('record the specified user as committer'), _('USER')),
87 _('record the specified user as committer'), _('USER')),
88 ]
88 ]
89
89
90 templateopts = [
90 templateopts = [
91 ('', 'style', '',
91 ('', 'style', '',
92 _('display using template map file'), _('STYLE')),
92 _('display using template map file'), _('STYLE')),
93 ('', 'template', '',
93 ('', 'template', '',
94 _('display with template'), _('TEMPLATE')),
94 _('display with template'), _('TEMPLATE')),
95 ]
95 ]
96
96
97 logopts = [
97 logopts = [
98 ('p', 'patch', None, _('show patch')),
98 ('p', 'patch', None, _('show patch')),
99 ('g', 'git', None, _('use git extended diff format')),
99 ('g', 'git', None, _('use git extended diff format')),
100 ('l', 'limit', '',
100 ('l', 'limit', '',
101 _('limit number of changes displayed'), _('NUM')),
101 _('limit number of changes displayed'), _('NUM')),
102 ('M', 'no-merges', None, _('do not show merges')),
102 ('M', 'no-merges', None, _('do not show merges')),
103 ('', 'stat', None, _('output diffstat-style summary of changes')),
103 ('', 'stat', None, _('output diffstat-style summary of changes')),
104 ('G', 'graph', None, _("show the revision DAG")),
104 ('G', 'graph', None, _("show the revision DAG")),
105 ] + templateopts
105 ] + templateopts
106
106
107 diffopts = [
107 diffopts = [
108 ('a', 'text', None, _('treat all files as text')),
108 ('a', 'text', None, _('treat all files as text')),
109 ('g', 'git', None, _('use git extended diff format')),
109 ('g', 'git', None, _('use git extended diff format')),
110 ('', 'nodates', None, _('omit dates from diff headers'))
110 ('', 'nodates', None, _('omit dates from diff headers'))
111 ]
111 ]
112
112
113 diffwsopts = [
113 diffwsopts = [
114 ('w', 'ignore-all-space', None,
114 ('w', 'ignore-all-space', None,
115 _('ignore white space when comparing lines')),
115 _('ignore white space when comparing lines')),
116 ('b', 'ignore-space-change', None,
116 ('b', 'ignore-space-change', None,
117 _('ignore changes in the amount of white space')),
117 _('ignore changes in the amount of white space')),
118 ('B', 'ignore-blank-lines', None,
118 ('B', 'ignore-blank-lines', None,
119 _('ignore changes whose lines are all blank')),
119 _('ignore changes whose lines are all blank')),
120 ]
120 ]
121
121
122 diffopts2 = [
122 diffopts2 = [
123 ('p', 'show-function', None, _('show which function each change is in')),
123 ('p', 'show-function', None, _('show which function each change is in')),
124 ('', 'reverse', None, _('produce a diff that undoes the changes')),
124 ('', 'reverse', None, _('produce a diff that undoes the changes')),
125 ] + diffwsopts + [
125 ] + diffwsopts + [
126 ('U', 'unified', '',
126 ('U', 'unified', '',
127 _('number of lines of context to show'), _('NUM')),
127 _('number of lines of context to show'), _('NUM')),
128 ('', 'stat', None, _('output diffstat-style summary of changes')),
128 ('', 'stat', None, _('output diffstat-style summary of changes')),
129 ]
129 ]
130
130
131 mergetoolopts = [
131 mergetoolopts = [
132 ('t', 'tool', '', _('specify merge tool')),
132 ('t', 'tool', '', _('specify merge tool')),
133 ]
133 ]
134
134
135 similarityopts = [
135 similarityopts = [
136 ('s', 'similarity', '',
136 ('s', 'similarity', '',
137 _('guess renamed files by similarity (0<=s<=100)'), _('SIMILARITY'))
137 _('guess renamed files by similarity (0<=s<=100)'), _('SIMILARITY'))
138 ]
138 ]
139
139
140 subrepoopts = [
140 subrepoopts = [
141 ('S', 'subrepos', None,
141 ('S', 'subrepos', None,
142 _('recurse into subrepositories'))
142 _('recurse into subrepositories'))
143 ]
143 ]
144
144
145 # Commands start here, listed alphabetically
145 # Commands start here, listed alphabetically
146
146
147 @command('^add',
147 @command('^add',
148 walkopts + subrepoopts + dryrunopts,
148 walkopts + subrepoopts + dryrunopts,
149 _('[OPTION]... [FILE]...'))
149 _('[OPTION]... [FILE]...'))
150 def add(ui, repo, *pats, **opts):
150 def add(ui, repo, *pats, **opts):
151 """add the specified files on the next commit
151 """add the specified files on the next commit
152
152
153 Schedule files to be version controlled and added to the
153 Schedule files to be version controlled and added to the
154 repository.
154 repository.
155
155
156 The files will be added to the repository at the next commit. To
156 The files will be added to the repository at the next commit. To
157 undo an add before that, see :hg:`forget`.
157 undo an add before that, see :hg:`forget`.
158
158
159 If no names are given, add all files to the repository.
159 If no names are given, add all files to the repository.
160
160
161 .. container:: verbose
161 .. container:: verbose
162
162
163 An example showing how new (unknown) files are added
163 An example showing how new (unknown) files are added
164 automatically by :hg:`add`::
164 automatically by :hg:`add`::
165
165
166 $ ls
166 $ ls
167 foo.c
167 foo.c
168 $ hg status
168 $ hg status
169 ? foo.c
169 ? foo.c
170 $ hg add
170 $ hg add
171 adding foo.c
171 adding foo.c
172 $ hg status
172 $ hg status
173 A foo.c
173 A foo.c
174
174
175 Returns 0 if all files are successfully added.
175 Returns 0 if all files are successfully added.
176 """
176 """
177
177
178 m = scmutil.match(repo[None], pats, opts)
178 m = scmutil.match(repo[None], pats, opts)
179 rejected = cmdutil.add(ui, repo, m, opts.get('dry_run'),
179 rejected = cmdutil.add(ui, repo, m, opts.get('dry_run'),
180 opts.get('subrepos'), prefix="", explicitonly=False)
180 opts.get('subrepos'), prefix="", explicitonly=False)
181 return rejected and 1 or 0
181 return rejected and 1 or 0
182
182
183 @command('addremove',
183 @command('addremove',
184 similarityopts + walkopts + dryrunopts,
184 similarityopts + walkopts + dryrunopts,
185 _('[OPTION]... [FILE]...'))
185 _('[OPTION]... [FILE]...'))
186 def addremove(ui, repo, *pats, **opts):
186 def addremove(ui, repo, *pats, **opts):
187 """add all new files, delete all missing files
187 """add all new files, delete all missing files
188
188
189 Add all new files and remove all missing files from the
189 Add all new files and remove all missing files from the
190 repository.
190 repository.
191
191
192 New files are ignored if they match any of the patterns in
192 New files are ignored if they match any of the patterns in
193 ``.hgignore``. As with add, these changes take effect at the next
193 ``.hgignore``. As with add, these changes take effect at the next
194 commit.
194 commit.
195
195
196 Use the -s/--similarity option to detect renamed files. This
196 Use the -s/--similarity option to detect renamed files. This
197 option takes a percentage between 0 (disabled) and 100 (files must
197 option takes a percentage between 0 (disabled) and 100 (files must
198 be identical) as its parameter. With a parameter greater than 0,
198 be identical) as its parameter. With a parameter greater than 0,
199 this compares every removed file with every added file and records
199 this compares every removed file with every added file and records
200 those similar enough as renames. Detecting renamed files this way
200 those similar enough as renames. Detecting renamed files this way
201 can be expensive. After using this option, :hg:`status -C` can be
201 can be expensive. After using this option, :hg:`status -C` can be
202 used to check which files were identified as moved or renamed. If
202 used to check which files were identified as moved or renamed. If
203 not specified, -s/--similarity defaults to 100 and only renames of
203 not specified, -s/--similarity defaults to 100 and only renames of
204 identical files are detected.
204 identical files are detected.
205
205
206 Returns 0 if all files are successfully added.
206 Returns 0 if all files are successfully added.
207 """
207 """
208 try:
208 try:
209 sim = float(opts.get('similarity') or 100)
209 sim = float(opts.get('similarity') or 100)
210 except ValueError:
210 except ValueError:
211 raise util.Abort(_('similarity must be a number'))
211 raise util.Abort(_('similarity must be a number'))
212 if sim < 0 or sim > 100:
212 if sim < 0 or sim > 100:
213 raise util.Abort(_('similarity must be between 0 and 100'))
213 raise util.Abort(_('similarity must be between 0 and 100'))
214 return scmutil.addremove(repo, pats, opts, similarity=sim / 100.0)
214 return scmutil.addremove(repo, pats, opts, similarity=sim / 100.0)
215
215
216 @command('^annotate|blame',
216 @command('^annotate|blame',
217 [('r', 'rev', '', _('annotate the specified revision'), _('REV')),
217 [('r', 'rev', '', _('annotate the specified revision'), _('REV')),
218 ('', 'follow', None,
218 ('', 'follow', None,
219 _('follow copies/renames and list the filename (DEPRECATED)')),
219 _('follow copies/renames and list the filename (DEPRECATED)')),
220 ('', 'no-follow', None, _("don't follow copies and renames")),
220 ('', 'no-follow', None, _("don't follow copies and renames")),
221 ('a', 'text', None, _('treat all files as text')),
221 ('a', 'text', None, _('treat all files as text')),
222 ('u', 'user', None, _('list the author (long with -v)')),
222 ('u', 'user', None, _('list the author (long with -v)')),
223 ('f', 'file', None, _('list the filename')),
223 ('f', 'file', None, _('list the filename')),
224 ('d', 'date', None, _('list the date (short with -q)')),
224 ('d', 'date', None, _('list the date (short with -q)')),
225 ('n', 'number', None, _('list the revision number (default)')),
225 ('n', 'number', None, _('list the revision number (default)')),
226 ('c', 'changeset', None, _('list the changeset')),
226 ('c', 'changeset', None, _('list the changeset')),
227 ('l', 'line-number', None, _('show line number at the first appearance'))
227 ('l', 'line-number', None, _('show line number at the first appearance'))
228 ] + diffwsopts + walkopts,
228 ] + diffwsopts + walkopts,
229 _('[-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE...'))
229 _('[-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE...'))
230 def annotate(ui, repo, *pats, **opts):
230 def annotate(ui, repo, *pats, **opts):
231 """show changeset information by line for each file
231 """show changeset information by line for each file
232
232
233 List changes in files, showing the revision id responsible for
233 List changes in files, showing the revision id responsible for
234 each line
234 each line
235
235
236 This command is useful for discovering when a change was made and
236 This command is useful for discovering when a change was made and
237 by whom.
237 by whom.
238
238
239 Without the -a/--text option, annotate will avoid processing files
239 Without the -a/--text option, annotate will avoid processing files
240 it detects as binary. With -a, annotate will annotate the file
240 it detects as binary. With -a, annotate will annotate the file
241 anyway, although the results will probably be neither useful
241 anyway, although the results will probably be neither useful
242 nor desirable.
242 nor desirable.
243
243
244 Returns 0 on success.
244 Returns 0 on success.
245 """
245 """
246 if opts.get('follow'):
246 if opts.get('follow'):
247 # --follow is deprecated and now just an alias for -f/--file
247 # --follow is deprecated and now just an alias for -f/--file
248 # to mimic the behavior of Mercurial before version 1.5
248 # to mimic the behavior of Mercurial before version 1.5
249 opts['file'] = True
249 opts['file'] = True
250
250
251 datefunc = ui.quiet and util.shortdate or util.datestr
251 datefunc = ui.quiet and util.shortdate or util.datestr
252 getdate = util.cachefunc(lambda x: datefunc(x[0].date()))
252 getdate = util.cachefunc(lambda x: datefunc(x[0].date()))
253
253
254 if not pats:
254 if not pats:
255 raise util.Abort(_('at least one filename or pattern is required'))
255 raise util.Abort(_('at least one filename or pattern is required'))
256
256
257 hexfn = ui.debugflag and hex or short
257 hexfn = ui.debugflag and hex or short
258
258
259 opmap = [('user', ' ', lambda x: ui.shortuser(x[0].user())),
259 opmap = [('user', ' ', lambda x: ui.shortuser(x[0].user())),
260 ('number', ' ', lambda x: str(x[0].rev())),
260 ('number', ' ', lambda x: str(x[0].rev())),
261 ('changeset', ' ', lambda x: hexfn(x[0].node())),
261 ('changeset', ' ', lambda x: hexfn(x[0].node())),
262 ('date', ' ', getdate),
262 ('date', ' ', getdate),
263 ('file', ' ', lambda x: x[0].path()),
263 ('file', ' ', lambda x: x[0].path()),
264 ('line_number', ':', lambda x: str(x[1])),
264 ('line_number', ':', lambda x: str(x[1])),
265 ]
265 ]
266
266
267 if (not opts.get('user') and not opts.get('changeset')
267 if (not opts.get('user') and not opts.get('changeset')
268 and not opts.get('date') and not opts.get('file')):
268 and not opts.get('date') and not opts.get('file')):
269 opts['number'] = True
269 opts['number'] = True
270
270
271 linenumber = opts.get('line_number') is not None
271 linenumber = opts.get('line_number') is not None
272 if linenumber and (not opts.get('changeset')) and (not opts.get('number')):
272 if linenumber and (not opts.get('changeset')) and (not opts.get('number')):
273 raise util.Abort(_('at least one of -n/-c is required for -l'))
273 raise util.Abort(_('at least one of -n/-c is required for -l'))
274
274
275 funcmap = [(func, sep) for op, sep, func in opmap if opts.get(op)]
275 funcmap = [(func, sep) for op, sep, func in opmap if opts.get(op)]
276 funcmap[0] = (funcmap[0][0], '') # no separator in front of first column
276 funcmap[0] = (funcmap[0][0], '') # no separator in front of first column
277
277
278 def bad(x, y):
278 def bad(x, y):
279 raise util.Abort("%s: %s" % (x, y))
279 raise util.Abort("%s: %s" % (x, y))
280
280
281 ctx = scmutil.revsingle(repo, opts.get('rev'))
281 ctx = scmutil.revsingle(repo, opts.get('rev'))
282 m = scmutil.match(ctx, pats, opts)
282 m = scmutil.match(ctx, pats, opts)
283 m.bad = bad
283 m.bad = bad
284 follow = not opts.get('no_follow')
284 follow = not opts.get('no_follow')
285 diffopts = patch.diffopts(ui, opts, section='annotate')
285 diffopts = patch.diffopts(ui, opts, section='annotate')
286 for abs in ctx.walk(m):
286 for abs in ctx.walk(m):
287 fctx = ctx[abs]
287 fctx = ctx[abs]
288 if not opts.get('text') and util.binary(fctx.data()):
288 if not opts.get('text') and util.binary(fctx.data()):
289 ui.write(_("%s: binary file\n") % ((pats and m.rel(abs)) or abs))
289 ui.write(_("%s: binary file\n") % ((pats and m.rel(abs)) or abs))
290 continue
290 continue
291
291
292 lines = fctx.annotate(follow=follow, linenumber=linenumber,
292 lines = fctx.annotate(follow=follow, linenumber=linenumber,
293 diffopts=diffopts)
293 diffopts=diffopts)
294 pieces = []
294 pieces = []
295
295
296 for f, sep in funcmap:
296 for f, sep in funcmap:
297 l = [f(n) for n, dummy in lines]
297 l = [f(n) for n, dummy in lines]
298 if l:
298 if l:
299 sized = [(x, encoding.colwidth(x)) for x in l]
299 sized = [(x, encoding.colwidth(x)) for x in l]
300 ml = max([w for x, w in sized])
300 ml = max([w for x, w in sized])
301 pieces.append(["%s%s%s" % (sep, ' ' * (ml - w), x)
301 pieces.append(["%s%s%s" % (sep, ' ' * (ml - w), x)
302 for x, w in sized])
302 for x, w in sized])
303
303
304 if pieces:
304 if pieces:
305 for p, l in zip(zip(*pieces), lines):
305 for p, l in zip(zip(*pieces), lines):
306 ui.write("%s: %s" % ("".join(p), l[1]))
306 ui.write("%s: %s" % ("".join(p), l[1]))
307
307
308 if lines and not lines[-1][1].endswith('\n'):
308 if lines and not lines[-1][1].endswith('\n'):
309 ui.write('\n')
309 ui.write('\n')
310
310
311 @command('archive',
311 @command('archive',
312 [('', 'no-decode', None, _('do not pass files through decoders')),
312 [('', 'no-decode', None, _('do not pass files through decoders')),
313 ('p', 'prefix', '', _('directory prefix for files in archive'),
313 ('p', 'prefix', '', _('directory prefix for files in archive'),
314 _('PREFIX')),
314 _('PREFIX')),
315 ('r', 'rev', '', _('revision to distribute'), _('REV')),
315 ('r', 'rev', '', _('revision to distribute'), _('REV')),
316 ('t', 'type', '', _('type of distribution to create'), _('TYPE')),
316 ('t', 'type', '', _('type of distribution to create'), _('TYPE')),
317 ] + subrepoopts + walkopts,
317 ] + subrepoopts + walkopts,
318 _('[OPTION]... DEST'))
318 _('[OPTION]... DEST'))
319 def archive(ui, repo, dest, **opts):
319 def archive(ui, repo, dest, **opts):
320 '''create an unversioned archive of a repository revision
320 '''create an unversioned archive of a repository revision
321
321
322 By default, the revision used is the parent of the working
322 By default, the revision used is the parent of the working
323 directory; use -r/--rev to specify a different revision.
323 directory; use -r/--rev to specify a different revision.
324
324
325 The archive type is automatically detected based on file
325 The archive type is automatically detected based on file
326 extension (or override using -t/--type).
326 extension (or override using -t/--type).
327
327
328 .. container:: verbose
328 .. container:: verbose
329
329
330 Examples:
330 Examples:
331
331
332 - create a zip file containing the 1.0 release::
332 - create a zip file containing the 1.0 release::
333
333
334 hg archive -r 1.0 project-1.0.zip
334 hg archive -r 1.0 project-1.0.zip
335
335
336 - create a tarball excluding .hg files::
336 - create a tarball excluding .hg files::
337
337
338 hg archive project.tar.gz -X ".hg*"
338 hg archive project.tar.gz -X ".hg*"
339
339
340 Valid types are:
340 Valid types are:
341
341
342 :``files``: a directory full of files (default)
342 :``files``: a directory full of files (default)
343 :``tar``: tar archive, uncompressed
343 :``tar``: tar archive, uncompressed
344 :``tbz2``: tar archive, compressed using bzip2
344 :``tbz2``: tar archive, compressed using bzip2
345 :``tgz``: tar archive, compressed using gzip
345 :``tgz``: tar archive, compressed using gzip
346 :``uzip``: zip archive, uncompressed
346 :``uzip``: zip archive, uncompressed
347 :``zip``: zip archive, compressed using deflate
347 :``zip``: zip archive, compressed using deflate
348
348
349 The exact name of the destination archive or directory is given
349 The exact name of the destination archive or directory is given
350 using a format string; see :hg:`help export` for details.
350 using a format string; see :hg:`help export` for details.
351
351
352 Each member added to an archive file has a directory prefix
352 Each member added to an archive file has a directory prefix
353 prepended. Use -p/--prefix to specify a format string for the
353 prepended. Use -p/--prefix to specify a format string for the
354 prefix. The default is the basename of the archive, with suffixes
354 prefix. The default is the basename of the archive, with suffixes
355 removed.
355 removed.
356
356
357 Returns 0 on success.
357 Returns 0 on success.
358 '''
358 '''
359
359
360 ctx = scmutil.revsingle(repo, opts.get('rev'))
360 ctx = scmutil.revsingle(repo, opts.get('rev'))
361 if not ctx:
361 if not ctx:
362 raise util.Abort(_('no working directory: please specify a revision'))
362 raise util.Abort(_('no working directory: please specify a revision'))
363 node = ctx.node()
363 node = ctx.node()
364 dest = cmdutil.makefilename(repo, dest, node)
364 dest = cmdutil.makefilename(repo, dest, node)
365 if os.path.realpath(dest) == repo.root:
365 if os.path.realpath(dest) == repo.root:
366 raise util.Abort(_('repository root cannot be destination'))
366 raise util.Abort(_('repository root cannot be destination'))
367
367
368 kind = opts.get('type') or archival.guesskind(dest) or 'files'
368 kind = opts.get('type') or archival.guesskind(dest) or 'files'
369 prefix = opts.get('prefix')
369 prefix = opts.get('prefix')
370
370
371 if dest == '-':
371 if dest == '-':
372 if kind == 'files':
372 if kind == 'files':
373 raise util.Abort(_('cannot archive plain files to stdout'))
373 raise util.Abort(_('cannot archive plain files to stdout'))
374 dest = cmdutil.makefileobj(repo, dest)
374 dest = cmdutil.makefileobj(repo, dest)
375 if not prefix:
375 if not prefix:
376 prefix = os.path.basename(repo.root) + '-%h'
376 prefix = os.path.basename(repo.root) + '-%h'
377
377
378 prefix = cmdutil.makefilename(repo, prefix, node)
378 prefix = cmdutil.makefilename(repo, prefix, node)
379 matchfn = scmutil.match(ctx, [], opts)
379 matchfn = scmutil.match(ctx, [], opts)
380 archival.archive(repo, dest, node, kind, not opts.get('no_decode'),
380 archival.archive(repo, dest, node, kind, not opts.get('no_decode'),
381 matchfn, prefix, subrepos=opts.get('subrepos'))
381 matchfn, prefix, subrepos=opts.get('subrepos'))
382
382
383 @command('backout',
383 @command('backout',
384 [('', 'merge', None, _('merge with old dirstate parent after backout')),
384 [('', 'merge', None, _('merge with old dirstate parent after backout')),
385 ('', 'parent', '',
385 ('', 'parent', '',
386 _('parent to choose when backing out merge (DEPRECATED)'), _('REV')),
386 _('parent to choose when backing out merge (DEPRECATED)'), _('REV')),
387 ('r', 'rev', '', _('revision to backout'), _('REV')),
387 ('r', 'rev', '', _('revision to backout'), _('REV')),
388 ] + mergetoolopts + walkopts + commitopts + commitopts2,
388 ] + mergetoolopts + walkopts + commitopts + commitopts2,
389 _('[OPTION]... [-r] REV'))
389 _('[OPTION]... [-r] REV'))
390 def backout(ui, repo, node=None, rev=None, **opts):
390 def backout(ui, repo, node=None, rev=None, **opts):
391 '''reverse effect of earlier changeset
391 '''reverse effect of earlier changeset
392
392
393 Prepare a new changeset with the effect of REV undone in the
393 Prepare a new changeset with the effect of REV undone in the
394 current working directory.
394 current working directory.
395
395
396 If REV is the parent of the working directory, then this new changeset
396 If REV is the parent of the working directory, then this new changeset
397 is committed automatically. Otherwise, hg needs to merge the
397 is committed automatically. Otherwise, hg needs to merge the
398 changes and the merged result is left uncommitted.
398 changes and the merged result is left uncommitted.
399
399
400 .. note::
400 .. note::
401
401
402 backout cannot be used to fix either an unwanted or
402 backout cannot be used to fix either an unwanted or
403 incorrect merge.
403 incorrect merge.
404
404
405 .. container:: verbose
405 .. container:: verbose
406
406
407 By default, the pending changeset will have one parent,
407 By default, the pending changeset will have one parent,
408 maintaining a linear history. With --merge, the pending
408 maintaining a linear history. With --merge, the pending
409 changeset will instead have two parents: the old parent of the
409 changeset will instead have two parents: the old parent of the
410 working directory and a new child of REV that simply undoes REV.
410 working directory and a new child of REV that simply undoes REV.
411
411
412 Before version 1.7, the behavior without --merge was equivalent
412 Before version 1.7, the behavior without --merge was equivalent
413 to specifying --merge followed by :hg:`update --clean .` to
413 to specifying --merge followed by :hg:`update --clean .` to
414 cancel the merge and leave the child of REV as a head to be
414 cancel the merge and leave the child of REV as a head to be
415 merged separately.
415 merged separately.
416
416
417 See :hg:`help dates` for a list of formats valid for -d/--date.
417 See :hg:`help dates` for a list of formats valid for -d/--date.
418
418
419 Returns 0 on success.
419 Returns 0 on success.
420 '''
420 '''
421 if rev and node:
421 if rev and node:
422 raise util.Abort(_("please specify just one revision"))
422 raise util.Abort(_("please specify just one revision"))
423
423
424 if not rev:
424 if not rev:
425 rev = node
425 rev = node
426
426
427 if not rev:
427 if not rev:
428 raise util.Abort(_("please specify a revision to backout"))
428 raise util.Abort(_("please specify a revision to backout"))
429
429
430 date = opts.get('date')
430 date = opts.get('date')
431 if date:
431 if date:
432 opts['date'] = util.parsedate(date)
432 opts['date'] = util.parsedate(date)
433
433
434 cmdutil.checkunfinished(repo)
434 cmdutil.checkunfinished(repo)
435 cmdutil.bailifchanged(repo)
435 cmdutil.bailifchanged(repo)
436 node = scmutil.revsingle(repo, rev).node()
436 node = scmutil.revsingle(repo, rev).node()
437
437
438 op1, op2 = repo.dirstate.parents()
438 op1, op2 = repo.dirstate.parents()
439 a = repo.changelog.ancestor(op1, node)
439 a = repo.changelog.ancestor(op1, node)
440 if a != node:
440 if a != node:
441 raise util.Abort(_('cannot backout change on a different branch'))
441 raise util.Abort(_('cannot backout change on a different branch'))
442
442
443 p1, p2 = repo.changelog.parents(node)
443 p1, p2 = repo.changelog.parents(node)
444 if p1 == nullid:
444 if p1 == nullid:
445 raise util.Abort(_('cannot backout a change with no parents'))
445 raise util.Abort(_('cannot backout a change with no parents'))
446 if p2 != nullid:
446 if p2 != nullid:
447 if not opts.get('parent'):
447 if not opts.get('parent'):
448 raise util.Abort(_('cannot backout a merge changeset'))
448 raise util.Abort(_('cannot backout a merge changeset'))
449 p = repo.lookup(opts['parent'])
449 p = repo.lookup(opts['parent'])
450 if p not in (p1, p2):
450 if p not in (p1, p2):
451 raise util.Abort(_('%s is not a parent of %s') %
451 raise util.Abort(_('%s is not a parent of %s') %
452 (short(p), short(node)))
452 (short(p), short(node)))
453 parent = p
453 parent = p
454 else:
454 else:
455 if opts.get('parent'):
455 if opts.get('parent'):
456 raise util.Abort(_('cannot use --parent on non-merge changeset'))
456 raise util.Abort(_('cannot use --parent on non-merge changeset'))
457 parent = p1
457 parent = p1
458
458
459 # the backout should appear on the same branch
459 # the backout should appear on the same branch
460 wlock = repo.wlock()
460 wlock = repo.wlock()
461 try:
461 try:
462 branch = repo.dirstate.branch()
462 branch = repo.dirstate.branch()
463 bheads = repo.branchheads(branch)
463 bheads = repo.branchheads(branch)
464 rctx = scmutil.revsingle(repo, hex(parent))
464 rctx = scmutil.revsingle(repo, hex(parent))
465 if not opts.get('merge') and op1 != node:
465 if not opts.get('merge') and op1 != node:
466 try:
466 try:
467 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
467 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
468 stats = mergemod.update(repo, parent, True, True, False,
468 stats = mergemod.update(repo, parent, True, True, False,
469 node, False)
469 node, False)
470 repo.setparents(op1, op2)
470 repo.setparents(op1, op2)
471 hg._showstats(repo, stats)
471 hg._showstats(repo, stats)
472 if stats[3]:
472 if stats[3]:
473 repo.ui.status(_("use 'hg resolve' to retry unresolved "
473 repo.ui.status(_("use 'hg resolve' to retry unresolved "
474 "file merges\n"))
474 "file merges\n"))
475 else:
475 else:
476 msg = _("changeset %s backed out, "
476 msg = _("changeset %s backed out, "
477 "don't forget to commit.\n")
477 "don't forget to commit.\n")
478 ui.status(msg % short(node))
478 ui.status(msg % short(node))
479 return stats[3] > 0
479 return stats[3] > 0
480 finally:
480 finally:
481 ui.setconfig('ui', 'forcemerge', '')
481 ui.setconfig('ui', 'forcemerge', '')
482 else:
482 else:
483 hg.clean(repo, node, show_stats=False)
483 hg.clean(repo, node, show_stats=False)
484 repo.dirstate.setbranch(branch)
484 repo.dirstate.setbranch(branch)
485 cmdutil.revert(ui, repo, rctx, repo.dirstate.parents())
485 cmdutil.revert(ui, repo, rctx, repo.dirstate.parents())
486
486
487
487
488 e = cmdutil.commiteditor
488 e = cmdutil.commiteditor
489 if not opts['message'] and not opts['logfile']:
489 if not opts['message'] and not opts['logfile']:
490 # we don't translate commit messages
490 # we don't translate commit messages
491 opts['message'] = "Backed out changeset %s" % short(node)
491 opts['message'] = "Backed out changeset %s" % short(node)
492 e = cmdutil.commitforceeditor
492 e = cmdutil.commitforceeditor
493
493
494 def commitfunc(ui, repo, message, match, opts):
494 def commitfunc(ui, repo, message, match, opts):
495 return repo.commit(message, opts.get('user'), opts.get('date'),
495 return repo.commit(message, opts.get('user'), opts.get('date'),
496 match, editor=e)
496 match, editor=e)
497 newnode = cmdutil.commit(ui, repo, commitfunc, [], opts)
497 newnode = cmdutil.commit(ui, repo, commitfunc, [], opts)
498 cmdutil.commitstatus(repo, newnode, branch, bheads)
498 cmdutil.commitstatus(repo, newnode, branch, bheads)
499
499
500 def nice(node):
500 def nice(node):
501 return '%d:%s' % (repo.changelog.rev(node), short(node))
501 return '%d:%s' % (repo.changelog.rev(node), short(node))
502 ui.status(_('changeset %s backs out changeset %s\n') %
502 ui.status(_('changeset %s backs out changeset %s\n') %
503 (nice(repo.changelog.tip()), nice(node)))
503 (nice(repo.changelog.tip()), nice(node)))
504 if opts.get('merge') and op1 != node:
504 if opts.get('merge') and op1 != node:
505 hg.clean(repo, op1, show_stats=False)
505 hg.clean(repo, op1, show_stats=False)
506 ui.status(_('merging with changeset %s\n')
506 ui.status(_('merging with changeset %s\n')
507 % nice(repo.changelog.tip()))
507 % nice(repo.changelog.tip()))
508 try:
508 try:
509 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
509 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
510 return hg.merge(repo, hex(repo.changelog.tip()))
510 return hg.merge(repo, hex(repo.changelog.tip()))
511 finally:
511 finally:
512 ui.setconfig('ui', 'forcemerge', '')
512 ui.setconfig('ui', 'forcemerge', '')
513 finally:
513 finally:
514 wlock.release()
514 wlock.release()
515 return 0
515 return 0
516
516
517 @command('bisect',
517 @command('bisect',
518 [('r', 'reset', False, _('reset bisect state')),
518 [('r', 'reset', False, _('reset bisect state')),
519 ('g', 'good', False, _('mark changeset good')),
519 ('g', 'good', False, _('mark changeset good')),
520 ('b', 'bad', False, _('mark changeset bad')),
520 ('b', 'bad', False, _('mark changeset bad')),
521 ('s', 'skip', False, _('skip testing changeset')),
521 ('s', 'skip', False, _('skip testing changeset')),
522 ('e', 'extend', False, _('extend the bisect range')),
522 ('e', 'extend', False, _('extend the bisect range')),
523 ('c', 'command', '', _('use command to check changeset state'), _('CMD')),
523 ('c', 'command', '', _('use command to check changeset state'), _('CMD')),
524 ('U', 'noupdate', False, _('do not update to target'))],
524 ('U', 'noupdate', False, _('do not update to target'))],
525 _("[-gbsr] [-U] [-c CMD] [REV]"))
525 _("[-gbsr] [-U] [-c CMD] [REV]"))
526 def bisect(ui, repo, rev=None, extra=None, command=None,
526 def bisect(ui, repo, rev=None, extra=None, command=None,
527 reset=None, good=None, bad=None, skip=None, extend=None,
527 reset=None, good=None, bad=None, skip=None, extend=None,
528 noupdate=None):
528 noupdate=None):
529 """subdivision search of changesets
529 """subdivision search of changesets
530
530
531 This command helps to find changesets which introduce problems. To
531 This command helps to find changesets which introduce problems. To
532 use, mark the earliest changeset you know exhibits the problem as
532 use, mark the earliest changeset you know exhibits the problem as
533 bad, then mark the latest changeset which is free from the problem
533 bad, then mark the latest changeset which is free from the problem
534 as good. Bisect will update your working directory to a revision
534 as good. Bisect will update your working directory to a revision
535 for testing (unless the -U/--noupdate option is specified). Once
535 for testing (unless the -U/--noupdate option is specified). Once
536 you have performed tests, mark the working directory as good or
536 you have performed tests, mark the working directory as good or
537 bad, and bisect will either update to another candidate changeset
537 bad, and bisect will either update to another candidate changeset
538 or announce that it has found the bad revision.
538 or announce that it has found the bad revision.
539
539
540 As a shortcut, you can also use the revision argument to mark a
540 As a shortcut, you can also use the revision argument to mark a
541 revision as good or bad without checking it out first.
541 revision as good or bad without checking it out first.
542
542
543 If you supply a command, it will be used for automatic bisection.
543 If you supply a command, it will be used for automatic bisection.
544 The environment variable HG_NODE will contain the ID of the
544 The environment variable HG_NODE will contain the ID of the
545 changeset being tested. The exit status of the command will be
545 changeset being tested. The exit status of the command will be
546 used to mark revisions as good or bad: status 0 means good, 125
546 used to mark revisions as good or bad: status 0 means good, 125
547 means to skip the revision, 127 (command not found) will abort the
547 means to skip the revision, 127 (command not found) will abort the
548 bisection, and any other non-zero exit status means the revision
548 bisection, and any other non-zero exit status means the revision
549 is bad.
549 is bad.
550
550
551 .. container:: verbose
551 .. container:: verbose
552
552
553 Some examples:
553 Some examples:
554
554
555 - start a bisection with known bad revision 34, and good revision 12::
555 - start a bisection with known bad revision 34, and good revision 12::
556
556
557 hg bisect --bad 34
557 hg bisect --bad 34
558 hg bisect --good 12
558 hg bisect --good 12
559
559
560 - advance the current bisection by marking current revision as good or
560 - advance the current bisection by marking current revision as good or
561 bad::
561 bad::
562
562
563 hg bisect --good
563 hg bisect --good
564 hg bisect --bad
564 hg bisect --bad
565
565
566 - mark the current revision, or a known revision, to be skipped (e.g. if
566 - mark the current revision, or a known revision, to be skipped (e.g. if
567 that revision is not usable because of another issue)::
567 that revision is not usable because of another issue)::
568
568
569 hg bisect --skip
569 hg bisect --skip
570 hg bisect --skip 23
570 hg bisect --skip 23
571
571
572 - skip all revisions that do not touch directories ``foo`` or ``bar``::
572 - skip all revisions that do not touch directories ``foo`` or ``bar``::
573
573
574 hg bisect --skip "!( file('path:foo') & file('path:bar') )"
574 hg bisect --skip "!( file('path:foo') & file('path:bar') )"
575
575
576 - forget the current bisection::
576 - forget the current bisection::
577
577
578 hg bisect --reset
578 hg bisect --reset
579
579
580 - use 'make && make tests' to automatically find the first broken
580 - use 'make && make tests' to automatically find the first broken
581 revision::
581 revision::
582
582
583 hg bisect --reset
583 hg bisect --reset
584 hg bisect --bad 34
584 hg bisect --bad 34
585 hg bisect --good 12
585 hg bisect --good 12
586 hg bisect --command "make && make tests"
586 hg bisect --command "make && make tests"
587
587
588 - see all changesets whose states are already known in the current
588 - see all changesets whose states are already known in the current
589 bisection::
589 bisection::
590
590
591 hg log -r "bisect(pruned)"
591 hg log -r "bisect(pruned)"
592
592
593 - see the changeset currently being bisected (especially useful
593 - see the changeset currently being bisected (especially useful
594 if running with -U/--noupdate)::
594 if running with -U/--noupdate)::
595
595
596 hg log -r "bisect(current)"
596 hg log -r "bisect(current)"
597
597
598 - see all changesets that took part in the current bisection::
598 - see all changesets that took part in the current bisection::
599
599
600 hg log -r "bisect(range)"
600 hg log -r "bisect(range)"
601
601
602 - you can even get a nice graph::
602 - you can even get a nice graph::
603
603
604 hg log --graph -r "bisect(range)"
604 hg log --graph -r "bisect(range)"
605
605
606 See :hg:`help revsets` for more about the `bisect()` keyword.
606 See :hg:`help revsets` for more about the `bisect()` keyword.
607
607
608 Returns 0 on success.
608 Returns 0 on success.
609 """
609 """
610 def extendbisectrange(nodes, good):
610 def extendbisectrange(nodes, good):
611 # bisect is incomplete when it ends on a merge node and
611 # bisect is incomplete when it ends on a merge node and
612 # one of the parent was not checked.
612 # one of the parent was not checked.
613 parents = repo[nodes[0]].parents()
613 parents = repo[nodes[0]].parents()
614 if len(parents) > 1:
614 if len(parents) > 1:
615 side = good and state['bad'] or state['good']
615 side = good and state['bad'] or state['good']
616 num = len(set(i.node() for i in parents) & set(side))
616 num = len(set(i.node() for i in parents) & set(side))
617 if num == 1:
617 if num == 1:
618 return parents[0].ancestor(parents[1])
618 return parents[0].ancestor(parents[1])
619 return None
619 return None
620
620
621 def print_result(nodes, good):
621 def print_result(nodes, good):
622 displayer = cmdutil.show_changeset(ui, repo, {})
622 displayer = cmdutil.show_changeset(ui, repo, {})
623 if len(nodes) == 1:
623 if len(nodes) == 1:
624 # narrowed it down to a single revision
624 # narrowed it down to a single revision
625 if good:
625 if good:
626 ui.write(_("The first good revision is:\n"))
626 ui.write(_("The first good revision is:\n"))
627 else:
627 else:
628 ui.write(_("The first bad revision is:\n"))
628 ui.write(_("The first bad revision is:\n"))
629 displayer.show(repo[nodes[0]])
629 displayer.show(repo[nodes[0]])
630 extendnode = extendbisectrange(nodes, good)
630 extendnode = extendbisectrange(nodes, good)
631 if extendnode is not None:
631 if extendnode is not None:
632 ui.write(_('Not all ancestors of this changeset have been'
632 ui.write(_('Not all ancestors of this changeset have been'
633 ' checked.\nUse bisect --extend to continue the '
633 ' checked.\nUse bisect --extend to continue the '
634 'bisection from\nthe common ancestor, %s.\n')
634 'bisection from\nthe common ancestor, %s.\n')
635 % extendnode)
635 % extendnode)
636 else:
636 else:
637 # multiple possible revisions
637 # multiple possible revisions
638 if good:
638 if good:
639 ui.write(_("Due to skipped revisions, the first "
639 ui.write(_("Due to skipped revisions, the first "
640 "good revision could be any of:\n"))
640 "good revision could be any of:\n"))
641 else:
641 else:
642 ui.write(_("Due to skipped revisions, the first "
642 ui.write(_("Due to skipped revisions, the first "
643 "bad revision could be any of:\n"))
643 "bad revision could be any of:\n"))
644 for n in nodes:
644 for n in nodes:
645 displayer.show(repo[n])
645 displayer.show(repo[n])
646 displayer.close()
646 displayer.close()
647
647
648 def check_state(state, interactive=True):
648 def check_state(state, interactive=True):
649 if not state['good'] or not state['bad']:
649 if not state['good'] or not state['bad']:
650 if (good or bad or skip or reset) and interactive:
650 if (good or bad or skip or reset) and interactive:
651 return
651 return
652 if not state['good']:
652 if not state['good']:
653 raise util.Abort(_('cannot bisect (no known good revisions)'))
653 raise util.Abort(_('cannot bisect (no known good revisions)'))
654 else:
654 else:
655 raise util.Abort(_('cannot bisect (no known bad revisions)'))
655 raise util.Abort(_('cannot bisect (no known bad revisions)'))
656 return True
656 return True
657
657
658 # backward compatibility
658 # backward compatibility
659 if rev in "good bad reset init".split():
659 if rev in "good bad reset init".split():
660 ui.warn(_("(use of 'hg bisect <cmd>' is deprecated)\n"))
660 ui.warn(_("(use of 'hg bisect <cmd>' is deprecated)\n"))
661 cmd, rev, extra = rev, extra, None
661 cmd, rev, extra = rev, extra, None
662 if cmd == "good":
662 if cmd == "good":
663 good = True
663 good = True
664 elif cmd == "bad":
664 elif cmd == "bad":
665 bad = True
665 bad = True
666 else:
666 else:
667 reset = True
667 reset = True
668 elif extra or good + bad + skip + reset + extend + bool(command) > 1:
668 elif extra or good + bad + skip + reset + extend + bool(command) > 1:
669 raise util.Abort(_('incompatible arguments'))
669 raise util.Abort(_('incompatible arguments'))
670
670
671 cmdutil.checkunfinished(repo)
671 cmdutil.checkunfinished(repo)
672
672
673 if reset:
673 if reset:
674 p = repo.join("bisect.state")
674 p = repo.join("bisect.state")
675 if os.path.exists(p):
675 if os.path.exists(p):
676 os.unlink(p)
676 os.unlink(p)
677 return
677 return
678
678
679 state = hbisect.load_state(repo)
679 state = hbisect.load_state(repo)
680
680
681 if command:
681 if command:
682 changesets = 1
682 changesets = 1
683 if noupdate:
683 if noupdate:
684 try:
684 try:
685 node = state['current'][0]
685 node = state['current'][0]
686 except LookupError:
686 except LookupError:
687 raise util.Abort(_('current bisect revision is unknown - '
687 raise util.Abort(_('current bisect revision is unknown - '
688 'start a new bisect to fix'))
688 'start a new bisect to fix'))
689 else:
689 else:
690 node, p2 = repo.dirstate.parents()
690 node, p2 = repo.dirstate.parents()
691 if p2 != nullid:
691 if p2 != nullid:
692 raise util.Abort(_('current bisect revision is a merge'))
692 raise util.Abort(_('current bisect revision is a merge'))
693 try:
693 try:
694 while changesets:
694 while changesets:
695 # update state
695 # update state
696 state['current'] = [node]
696 state['current'] = [node]
697 hbisect.save_state(repo, state)
697 hbisect.save_state(repo, state)
698 status = util.system(command,
698 status = util.system(command,
699 environ={'HG_NODE': hex(node)},
699 environ={'HG_NODE': hex(node)},
700 out=ui.fout)
700 out=ui.fout)
701 if status == 125:
701 if status == 125:
702 transition = "skip"
702 transition = "skip"
703 elif status == 0:
703 elif status == 0:
704 transition = "good"
704 transition = "good"
705 # status < 0 means process was killed
705 # status < 0 means process was killed
706 elif status == 127:
706 elif status == 127:
707 raise util.Abort(_("failed to execute %s") % command)
707 raise util.Abort(_("failed to execute %s") % command)
708 elif status < 0:
708 elif status < 0:
709 raise util.Abort(_("%s killed") % command)
709 raise util.Abort(_("%s killed") % command)
710 else:
710 else:
711 transition = "bad"
711 transition = "bad"
712 ctx = scmutil.revsingle(repo, rev, node)
712 ctx = scmutil.revsingle(repo, rev, node)
713 rev = None # clear for future iterations
713 rev = None # clear for future iterations
714 state[transition].append(ctx.node())
714 state[transition].append(ctx.node())
715 ui.status(_('changeset %d:%s: %s\n') % (ctx, ctx, transition))
715 ui.status(_('changeset %d:%s: %s\n') % (ctx, ctx, transition))
716 check_state(state, interactive=False)
716 check_state(state, interactive=False)
717 # bisect
717 # bisect
718 nodes, changesets, bgood = hbisect.bisect(repo.changelog, state)
718 nodes, changesets, bgood = hbisect.bisect(repo.changelog, state)
719 # update to next check
719 # update to next check
720 node = nodes[0]
720 node = nodes[0]
721 if not noupdate:
721 if not noupdate:
722 cmdutil.bailifchanged(repo)
722 cmdutil.bailifchanged(repo)
723 hg.clean(repo, node, show_stats=False)
723 hg.clean(repo, node, show_stats=False)
724 finally:
724 finally:
725 state['current'] = [node]
725 state['current'] = [node]
726 hbisect.save_state(repo, state)
726 hbisect.save_state(repo, state)
727 print_result(nodes, bgood)
727 print_result(nodes, bgood)
728 return
728 return
729
729
730 # update state
730 # update state
731
731
732 if rev:
732 if rev:
733 nodes = [repo.lookup(i) for i in scmutil.revrange(repo, [rev])]
733 nodes = [repo.lookup(i) for i in scmutil.revrange(repo, [rev])]
734 else:
734 else:
735 nodes = [repo.lookup('.')]
735 nodes = [repo.lookup('.')]
736
736
737 if good or bad or skip:
737 if good or bad or skip:
738 if good:
738 if good:
739 state['good'] += nodes
739 state['good'] += nodes
740 elif bad:
740 elif bad:
741 state['bad'] += nodes
741 state['bad'] += nodes
742 elif skip:
742 elif skip:
743 state['skip'] += nodes
743 state['skip'] += nodes
744 hbisect.save_state(repo, state)
744 hbisect.save_state(repo, state)
745
745
746 if not check_state(state):
746 if not check_state(state):
747 return
747 return
748
748
749 # actually bisect
749 # actually bisect
750 nodes, changesets, good = hbisect.bisect(repo.changelog, state)
750 nodes, changesets, good = hbisect.bisect(repo.changelog, state)
751 if extend:
751 if extend:
752 if not changesets:
752 if not changesets:
753 extendnode = extendbisectrange(nodes, good)
753 extendnode = extendbisectrange(nodes, good)
754 if extendnode is not None:
754 if extendnode is not None:
755 ui.write(_("Extending search to changeset %d:%s\n"
755 ui.write(_("Extending search to changeset %d:%s\n"
756 % (extendnode.rev(), extendnode)))
756 % (extendnode.rev(), extendnode)))
757 state['current'] = [extendnode.node()]
757 state['current'] = [extendnode.node()]
758 hbisect.save_state(repo, state)
758 hbisect.save_state(repo, state)
759 if noupdate:
759 if noupdate:
760 return
760 return
761 cmdutil.bailifchanged(repo)
761 cmdutil.bailifchanged(repo)
762 return hg.clean(repo, extendnode.node())
762 return hg.clean(repo, extendnode.node())
763 raise util.Abort(_("nothing to extend"))
763 raise util.Abort(_("nothing to extend"))
764
764
765 if changesets == 0:
765 if changesets == 0:
766 print_result(nodes, good)
766 print_result(nodes, good)
767 else:
767 else:
768 assert len(nodes) == 1 # only a single node can be tested next
768 assert len(nodes) == 1 # only a single node can be tested next
769 node = nodes[0]
769 node = nodes[0]
770 # compute the approximate number of remaining tests
770 # compute the approximate number of remaining tests
771 tests, size = 0, 2
771 tests, size = 0, 2
772 while size <= changesets:
772 while size <= changesets:
773 tests, size = tests + 1, size * 2
773 tests, size = tests + 1, size * 2
774 rev = repo.changelog.rev(node)
774 rev = repo.changelog.rev(node)
775 ui.write(_("Testing changeset %d:%s "
775 ui.write(_("Testing changeset %d:%s "
776 "(%d changesets remaining, ~%d tests)\n")
776 "(%d changesets remaining, ~%d tests)\n")
777 % (rev, short(node), changesets, tests))
777 % (rev, short(node), changesets, tests))
778 state['current'] = [node]
778 state['current'] = [node]
779 hbisect.save_state(repo, state)
779 hbisect.save_state(repo, state)
780 if not noupdate:
780 if not noupdate:
781 cmdutil.bailifchanged(repo)
781 cmdutil.bailifchanged(repo)
782 return hg.clean(repo, node)
782 return hg.clean(repo, node)
783
783
784 @command('bookmarks|bookmark',
784 @command('bookmarks|bookmark',
785 [('f', 'force', False, _('force')),
785 [('f', 'force', False, _('force')),
786 ('r', 'rev', '', _('revision'), _('REV')),
786 ('r', 'rev', '', _('revision'), _('REV')),
787 ('d', 'delete', False, _('delete a given bookmark')),
787 ('d', 'delete', False, _('delete a given bookmark')),
788 ('m', 'rename', '', _('rename a given bookmark'), _('NAME')),
788 ('m', 'rename', '', _('rename a given bookmark'), _('NAME')),
789 ('i', 'inactive', False, _('mark a bookmark inactive'))],
789 ('i', 'inactive', False, _('mark a bookmark inactive'))],
790 _('hg bookmarks [OPTIONS]... [NAME]...'))
790 _('hg bookmarks [OPTIONS]... [NAME]...'))
791 def bookmark(ui, repo, *names, **opts):
791 def bookmark(ui, repo, *names, **opts):
792 '''track a line of development with movable markers
792 '''track a line of development with movable markers
793
793
794 Bookmarks are pointers to certain commits that move when committing.
794 Bookmarks are pointers to certain commits that move when committing.
795 Bookmarks are local. They can be renamed, copied and deleted. It is
795 Bookmarks are local. They can be renamed, copied and deleted. It is
796 possible to use :hg:`merge NAME` to merge from a given bookmark, and
796 possible to use :hg:`merge NAME` to merge from a given bookmark, and
797 :hg:`update NAME` to update to a given bookmark.
797 :hg:`update NAME` to update to a given bookmark.
798
798
799 You can use :hg:`bookmark NAME` to set a bookmark on the working
799 You can use :hg:`bookmark NAME` to set a bookmark on the working
800 directory's parent revision with the given name. If you specify
800 directory's parent revision with the given name. If you specify
801 a revision using -r REV (where REV may be an existing bookmark),
801 a revision using -r REV (where REV may be an existing bookmark),
802 the bookmark is assigned to that revision.
802 the bookmark is assigned to that revision.
803
803
804 Bookmarks can be pushed and pulled between repositories (see :hg:`help
804 Bookmarks can be pushed and pulled between repositories (see :hg:`help
805 push` and :hg:`help pull`). This requires both the local and remote
805 push` and :hg:`help pull`). This requires both the local and remote
806 repositories to support bookmarks. For versions prior to 1.8, this means
806 repositories to support bookmarks. For versions prior to 1.8, this means
807 the bookmarks extension must be enabled.
807 the bookmarks extension must be enabled.
808
808
809 If you set a bookmark called '@', new clones of the repository will
809 If you set a bookmark called '@', new clones of the repository will
810 have that revision checked out (and the bookmark made active) by
810 have that revision checked out (and the bookmark made active) by
811 default.
811 default.
812
812
813 With -i/--inactive, the new bookmark will not be made the active
813 With -i/--inactive, the new bookmark will not be made the active
814 bookmark. If -r/--rev is given, the new bookmark will not be made
814 bookmark. If -r/--rev is given, the new bookmark will not be made
815 active even if -i/--inactive is not given. If no NAME is given, the
815 active even if -i/--inactive is not given. If no NAME is given, the
816 current active bookmark will be marked inactive.
816 current active bookmark will be marked inactive.
817 '''
817 '''
818 force = opts.get('force')
818 force = opts.get('force')
819 rev = opts.get('rev')
819 rev = opts.get('rev')
820 delete = opts.get('delete')
820 delete = opts.get('delete')
821 rename = opts.get('rename')
821 rename = opts.get('rename')
822 inactive = opts.get('inactive')
822 inactive = opts.get('inactive')
823
823
824 def checkformat(mark):
824 def checkformat(mark):
825 mark = mark.strip()
825 mark = mark.strip()
826 if not mark:
826 if not mark:
827 raise util.Abort(_("bookmark names cannot consist entirely of "
827 raise util.Abort(_("bookmark names cannot consist entirely of "
828 "whitespace"))
828 "whitespace"))
829 scmutil.checknewlabel(repo, mark, 'bookmark')
829 scmutil.checknewlabel(repo, mark, 'bookmark')
830 return mark
830 return mark
831
831
832 def checkconflict(repo, mark, cur, force=False, target=None):
832 def checkconflict(repo, mark, cur, force=False, target=None):
833 if mark in marks and not force:
833 if mark in marks and not force:
834 if target:
834 if target:
835 if marks[mark] == target and target == cur:
835 if marks[mark] == target and target == cur:
836 # re-activating a bookmark
836 # re-activating a bookmark
837 return
837 return
838 anc = repo.changelog.ancestors([repo[target].rev()])
838 anc = repo.changelog.ancestors([repo[target].rev()])
839 bmctx = repo[marks[mark]]
839 bmctx = repo[marks[mark]]
840 divs = [repo[b].node() for b in marks
840 divs = [repo[b].node() for b in marks
841 if b.split('@', 1)[0] == mark.split('@', 1)[0]]
841 if b.split('@', 1)[0] == mark.split('@', 1)[0]]
842
842
843 # allow resolving a single divergent bookmark even if moving
843 # allow resolving a single divergent bookmark even if moving
844 # the bookmark across branches when a revision is specified
844 # the bookmark across branches when a revision is specified
845 # that contains a divergent bookmark
845 # that contains a divergent bookmark
846 if bmctx.rev() not in anc and target in divs:
846 if bmctx.rev() not in anc and target in divs:
847 bookmarks.deletedivergent(repo, [target], mark)
847 bookmarks.deletedivergent(repo, [target], mark)
848 return
848 return
849
849
850 deletefrom = [b for b in divs
850 deletefrom = [b for b in divs
851 if repo[b].rev() in anc or b == target]
851 if repo[b].rev() in anc or b == target]
852 bookmarks.deletedivergent(repo, deletefrom, mark)
852 bookmarks.deletedivergent(repo, deletefrom, mark)
853 if bookmarks.validdest(repo, bmctx, repo[target]):
853 if bookmarks.validdest(repo, bmctx, repo[target]):
854 ui.status(_("moving bookmark '%s' forward from %s\n") %
854 ui.status(_("moving bookmark '%s' forward from %s\n") %
855 (mark, short(bmctx.node())))
855 (mark, short(bmctx.node())))
856 return
856 return
857 raise util.Abort(_("bookmark '%s' already exists "
857 raise util.Abort(_("bookmark '%s' already exists "
858 "(use -f to force)") % mark)
858 "(use -f to force)") % mark)
859 if ((mark in repo.branchmap() or mark == repo.dirstate.branch())
859 if ((mark in repo.branchmap() or mark == repo.dirstate.branch())
860 and not force):
860 and not force):
861 raise util.Abort(
861 raise util.Abort(
862 _("a bookmark cannot have the name of an existing branch"))
862 _("a bookmark cannot have the name of an existing branch"))
863
863
864 if delete and rename:
864 if delete and rename:
865 raise util.Abort(_("--delete and --rename are incompatible"))
865 raise util.Abort(_("--delete and --rename are incompatible"))
866 if delete and rev:
866 if delete and rev:
867 raise util.Abort(_("--rev is incompatible with --delete"))
867 raise util.Abort(_("--rev is incompatible with --delete"))
868 if rename and rev:
868 if rename and rev:
869 raise util.Abort(_("--rev is incompatible with --rename"))
869 raise util.Abort(_("--rev is incompatible with --rename"))
870 if not names and (delete or rev):
870 if not names and (delete or rev):
871 raise util.Abort(_("bookmark name required"))
871 raise util.Abort(_("bookmark name required"))
872
872
873 if delete or rename or names or inactive:
873 if delete or rename or names or inactive:
874 wlock = repo.wlock()
874 wlock = repo.wlock()
875 try:
875 try:
876 cur = repo.changectx('.').node()
876 cur = repo.changectx('.').node()
877 marks = repo._bookmarks
877 marks = repo._bookmarks
878 if delete:
878 if delete:
879 for mark in names:
879 for mark in names:
880 if mark not in marks:
880 if mark not in marks:
881 raise util.Abort(_("bookmark '%s' does not exist") %
881 raise util.Abort(_("bookmark '%s' does not exist") %
882 mark)
882 mark)
883 if mark == repo._bookmarkcurrent:
883 if mark == repo._bookmarkcurrent:
884 bookmarks.unsetcurrent(repo)
884 bookmarks.unsetcurrent(repo)
885 del marks[mark]
885 del marks[mark]
886 marks.write()
886 marks.write()
887
887
888 elif rename:
888 elif rename:
889 if not names:
889 if not names:
890 raise util.Abort(_("new bookmark name required"))
890 raise util.Abort(_("new bookmark name required"))
891 elif len(names) > 1:
891 elif len(names) > 1:
892 raise util.Abort(_("only one new bookmark name allowed"))
892 raise util.Abort(_("only one new bookmark name allowed"))
893 mark = checkformat(names[0])
893 mark = checkformat(names[0])
894 if rename not in marks:
894 if rename not in marks:
895 raise util.Abort(_("bookmark '%s' does not exist") % rename)
895 raise util.Abort(_("bookmark '%s' does not exist") % rename)
896 checkconflict(repo, mark, cur, force)
896 checkconflict(repo, mark, cur, force)
897 marks[mark] = marks[rename]
897 marks[mark] = marks[rename]
898 if repo._bookmarkcurrent == rename and not inactive:
898 if repo._bookmarkcurrent == rename and not inactive:
899 bookmarks.setcurrent(repo, mark)
899 bookmarks.setcurrent(repo, mark)
900 del marks[rename]
900 del marks[rename]
901 marks.write()
901 marks.write()
902
902
903 elif names:
903 elif names:
904 newact = None
904 newact = None
905 for mark in names:
905 for mark in names:
906 mark = checkformat(mark)
906 mark = checkformat(mark)
907 if newact is None:
907 if newact is None:
908 newact = mark
908 newact = mark
909 if inactive and mark == repo._bookmarkcurrent:
909 if inactive and mark == repo._bookmarkcurrent:
910 bookmarks.unsetcurrent(repo)
910 bookmarks.unsetcurrent(repo)
911 return
911 return
912 tgt = cur
912 tgt = cur
913 if rev:
913 if rev:
914 tgt = scmutil.revsingle(repo, rev).node()
914 tgt = scmutil.revsingle(repo, rev).node()
915 checkconflict(repo, mark, cur, force, tgt)
915 checkconflict(repo, mark, cur, force, tgt)
916 marks[mark] = tgt
916 marks[mark] = tgt
917 if not inactive and cur == marks[newact] and not rev:
917 if not inactive and cur == marks[newact] and not rev:
918 bookmarks.setcurrent(repo, newact)
918 bookmarks.setcurrent(repo, newact)
919 elif cur != tgt and newact == repo._bookmarkcurrent:
919 elif cur != tgt and newact == repo._bookmarkcurrent:
920 bookmarks.unsetcurrent(repo)
920 bookmarks.unsetcurrent(repo)
921 marks.write()
921 marks.write()
922
922
923 elif inactive:
923 elif inactive:
924 if len(marks) == 0:
924 if len(marks) == 0:
925 ui.status(_("no bookmarks set\n"))
925 ui.status(_("no bookmarks set\n"))
926 elif not repo._bookmarkcurrent:
926 elif not repo._bookmarkcurrent:
927 ui.status(_("no active bookmark\n"))
927 ui.status(_("no active bookmark\n"))
928 else:
928 else:
929 bookmarks.unsetcurrent(repo)
929 bookmarks.unsetcurrent(repo)
930 finally:
930 finally:
931 wlock.release()
931 wlock.release()
932 else: # show bookmarks
932 else: # show bookmarks
933 hexfn = ui.debugflag and hex or short
933 hexfn = ui.debugflag and hex or short
934 marks = repo._bookmarks
934 marks = repo._bookmarks
935 if len(marks) == 0:
935 if len(marks) == 0:
936 ui.status(_("no bookmarks set\n"))
936 ui.status(_("no bookmarks set\n"))
937 else:
937 else:
938 for bmark, n in sorted(marks.iteritems()):
938 for bmark, n in sorted(marks.iteritems()):
939 current = repo._bookmarkcurrent
939 current = repo._bookmarkcurrent
940 if bmark == current:
940 if bmark == current:
941 prefix, label = '*', 'bookmarks.current'
941 prefix, label = '*', 'bookmarks.current'
942 else:
942 else:
943 prefix, label = ' ', ''
943 prefix, label = ' ', ''
944
944
945 if ui.quiet:
945 if ui.quiet:
946 ui.write("%s\n" % bmark, label=label)
946 ui.write("%s\n" % bmark, label=label)
947 else:
947 else:
948 ui.write(" %s %-25s %d:%s\n" % (
948 ui.write(" %s %-25s %d:%s\n" % (
949 prefix, bmark, repo.changelog.rev(n), hexfn(n)),
949 prefix, bmark, repo.changelog.rev(n), hexfn(n)),
950 label=label)
950 label=label)
951
951
952 @command('branch',
952 @command('branch',
953 [('f', 'force', None,
953 [('f', 'force', None,
954 _('set branch name even if it shadows an existing branch')),
954 _('set branch name even if it shadows an existing branch')),
955 ('C', 'clean', None, _('reset branch name to parent branch name'))],
955 ('C', 'clean', None, _('reset branch name to parent branch name'))],
956 _('[-fC] [NAME]'))
956 _('[-fC] [NAME]'))
957 def branch(ui, repo, label=None, **opts):
957 def branch(ui, repo, label=None, **opts):
958 """set or show the current branch name
958 """set or show the current branch name
959
959
960 .. note::
960 .. note::
961
961
962 Branch names are permanent and global. Use :hg:`bookmark` to create a
962 Branch names are permanent and global. Use :hg:`bookmark` to create a
963 light-weight bookmark instead. See :hg:`help glossary` for more
963 light-weight bookmark instead. See :hg:`help glossary` for more
964 information about named branches and bookmarks.
964 information about named branches and bookmarks.
965
965
966 With no argument, show the current branch name. With one argument,
966 With no argument, show the current branch name. With one argument,
967 set the working directory branch name (the branch will not exist
967 set the working directory branch name (the branch will not exist
968 in the repository until the next commit). Standard practice
968 in the repository until the next commit). Standard practice
969 recommends that primary development take place on the 'default'
969 recommends that primary development take place on the 'default'
970 branch.
970 branch.
971
971
972 Unless -f/--force is specified, branch will not let you set a
972 Unless -f/--force is specified, branch will not let you set a
973 branch name that already exists, even if it's inactive.
973 branch name that already exists, even if it's inactive.
974
974
975 Use -C/--clean to reset the working directory branch to that of
975 Use -C/--clean to reset the working directory branch to that of
976 the parent of the working directory, negating a previous branch
976 the parent of the working directory, negating a previous branch
977 change.
977 change.
978
978
979 Use the command :hg:`update` to switch to an existing branch. Use
979 Use the command :hg:`update` to switch to an existing branch. Use
980 :hg:`commit --close-branch` to mark this branch as closed.
980 :hg:`commit --close-branch` to mark this branch as closed.
981
981
982 Returns 0 on success.
982 Returns 0 on success.
983 """
983 """
984 if label:
984 if label:
985 label = label.strip()
985 label = label.strip()
986
986
987 if not opts.get('clean') and not label:
987 if not opts.get('clean') and not label:
988 ui.write("%s\n" % repo.dirstate.branch())
988 ui.write("%s\n" % repo.dirstate.branch())
989 return
989 return
990
990
991 wlock = repo.wlock()
991 wlock = repo.wlock()
992 try:
992 try:
993 if opts.get('clean'):
993 if opts.get('clean'):
994 label = repo[None].p1().branch()
994 label = repo[None].p1().branch()
995 repo.dirstate.setbranch(label)
995 repo.dirstate.setbranch(label)
996 ui.status(_('reset working directory to branch %s\n') % label)
996 ui.status(_('reset working directory to branch %s\n') % label)
997 elif label:
997 elif label:
998 if not opts.get('force') and label in repo.branchmap():
998 if not opts.get('force') and label in repo.branchmap():
999 if label not in [p.branch() for p in repo.parents()]:
999 if label not in [p.branch() for p in repo.parents()]:
1000 raise util.Abort(_('a branch of the same name already'
1000 raise util.Abort(_('a branch of the same name already'
1001 ' exists'),
1001 ' exists'),
1002 # i18n: "it" refers to an existing branch
1002 # i18n: "it" refers to an existing branch
1003 hint=_("use 'hg update' to switch to it"))
1003 hint=_("use 'hg update' to switch to it"))
1004 scmutil.checknewlabel(repo, label, 'branch')
1004 scmutil.checknewlabel(repo, label, 'branch')
1005 repo.dirstate.setbranch(label)
1005 repo.dirstate.setbranch(label)
1006 ui.status(_('marked working directory as branch %s\n') % label)
1006 ui.status(_('marked working directory as branch %s\n') % label)
1007 ui.status(_('(branches are permanent and global, '
1007 ui.status(_('(branches are permanent and global, '
1008 'did you want a bookmark?)\n'))
1008 'did you want a bookmark?)\n'))
1009 finally:
1009 finally:
1010 wlock.release()
1010 wlock.release()
1011
1011
1012 @command('branches',
1012 @command('branches',
1013 [('a', 'active', False, _('show only branches that have unmerged heads')),
1013 [('a', 'active', False, _('show only branches that have unmerged heads')),
1014 ('c', 'closed', False, _('show normal and closed branches'))],
1014 ('c', 'closed', False, _('show normal and closed branches'))],
1015 _('[-ac]'))
1015 _('[-ac]'))
1016 def branches(ui, repo, active=False, closed=False):
1016 def branches(ui, repo, active=False, closed=False):
1017 """list repository named branches
1017 """list repository named branches
1018
1018
1019 List the repository's named branches, indicating which ones are
1019 List the repository's named branches, indicating which ones are
1020 inactive. If -c/--closed is specified, also list branches which have
1020 inactive. If -c/--closed is specified, also list branches which have
1021 been marked closed (see :hg:`commit --close-branch`).
1021 been marked closed (see :hg:`commit --close-branch`).
1022
1022
1023 If -a/--active is specified, only show active branches. A branch
1023 If -a/--active is specified, only show active branches. A branch
1024 is considered active if it contains repository heads.
1024 is considered active if it contains repository heads.
1025
1025
1026 Use the command :hg:`update` to switch to an existing branch.
1026 Use the command :hg:`update` to switch to an existing branch.
1027
1027
1028 Returns 0.
1028 Returns 0.
1029 """
1029 """
1030
1030
1031 hexfunc = ui.debugflag and hex or short
1031 hexfunc = ui.debugflag and hex or short
1032
1032
1033 allheads = set(repo.heads())
1033 allheads = set(repo.heads())
1034 branches = []
1034 branches = []
1035 for tag, heads, tip, isclosed in repo.branchmap().iterbranches():
1035 for tag, heads, tip, isclosed in repo.branchmap().iterbranches():
1036 isactive = not isclosed and bool(set(heads) & allheads)
1036 isactive = not isclosed and bool(set(heads) & allheads)
1037 branches.append((tag, repo[tip], isactive, not isclosed))
1037 branches.append((tag, repo[tip], isactive, not isclosed))
1038 branches.sort(key=lambda i: (i[2], i[1].rev(), i[0], i[3]),
1038 branches.sort(key=lambda i: (i[2], i[1].rev(), i[0], i[3]),
1039 reverse=True)
1039 reverse=True)
1040
1040
1041 for tag, ctx, isactive, isopen in branches:
1041 for tag, ctx, isactive, isopen in branches:
1042 if (not active) or isactive:
1042 if (not active) or isactive:
1043 if isactive:
1043 if isactive:
1044 label = 'branches.active'
1044 label = 'branches.active'
1045 notice = ''
1045 notice = ''
1046 elif not isopen:
1046 elif not isopen:
1047 if not closed:
1047 if not closed:
1048 continue
1048 continue
1049 label = 'branches.closed'
1049 label = 'branches.closed'
1050 notice = _(' (closed)')
1050 notice = _(' (closed)')
1051 else:
1051 else:
1052 label = 'branches.inactive'
1052 label = 'branches.inactive'
1053 notice = _(' (inactive)')
1053 notice = _(' (inactive)')
1054 if tag == repo.dirstate.branch():
1054 if tag == repo.dirstate.branch():
1055 label = 'branches.current'
1055 label = 'branches.current'
1056 rev = str(ctx.rev()).rjust(31 - encoding.colwidth(tag))
1056 rev = str(ctx.rev()).rjust(31 - encoding.colwidth(tag))
1057 rev = ui.label('%s:%s' % (rev, hexfunc(ctx.node())),
1057 rev = ui.label('%s:%s' % (rev, hexfunc(ctx.node())),
1058 'log.changeset changeset.%s' % ctx.phasestr())
1058 'log.changeset changeset.%s' % ctx.phasestr())
1059 labeledtag = ui.label(tag, label)
1059 labeledtag = ui.label(tag, label)
1060 if ui.quiet:
1060 if ui.quiet:
1061 ui.write("%s\n" % labeledtag)
1061 ui.write("%s\n" % labeledtag)
1062 else:
1062 else:
1063 ui.write("%s %s%s\n" % (labeledtag, rev, notice))
1063 ui.write("%s %s%s\n" % (labeledtag, rev, notice))
1064
1064
1065 @command('bundle',
1065 @command('bundle',
1066 [('f', 'force', None, _('run even when the destination is unrelated')),
1066 [('f', 'force', None, _('run even when the destination is unrelated')),
1067 ('r', 'rev', [], _('a changeset intended to be added to the destination'),
1067 ('r', 'rev', [], _('a changeset intended to be added to the destination'),
1068 _('REV')),
1068 _('REV')),
1069 ('b', 'branch', [], _('a specific branch you would like to bundle'),
1069 ('b', 'branch', [], _('a specific branch you would like to bundle'),
1070 _('BRANCH')),
1070 _('BRANCH')),
1071 ('', 'base', [],
1071 ('', 'base', [],
1072 _('a base changeset assumed to be available at the destination'),
1072 _('a base changeset assumed to be available at the destination'),
1073 _('REV')),
1073 _('REV')),
1074 ('a', 'all', None, _('bundle all changesets in the repository')),
1074 ('a', 'all', None, _('bundle all changesets in the repository')),
1075 ('t', 'type', 'bzip2', _('bundle compression type to use'), _('TYPE')),
1075 ('t', 'type', 'bzip2', _('bundle compression type to use'), _('TYPE')),
1076 ] + remoteopts,
1076 ] + remoteopts,
1077 _('[-f] [-t TYPE] [-a] [-r REV]... [--base REV]... FILE [DEST]'))
1077 _('[-f] [-t TYPE] [-a] [-r REV]... [--base REV]... FILE [DEST]'))
1078 def bundle(ui, repo, fname, dest=None, **opts):
1078 def bundle(ui, repo, fname, dest=None, **opts):
1079 """create a changegroup file
1079 """create a changegroup file
1080
1080
1081 Generate a compressed changegroup file collecting changesets not
1081 Generate a compressed changegroup file collecting changesets not
1082 known to be in another repository.
1082 known to be in another repository.
1083
1083
1084 If you omit the destination repository, then hg assumes the
1084 If you omit the destination repository, then hg assumes the
1085 destination will have all the nodes you specify with --base
1085 destination will have all the nodes you specify with --base
1086 parameters. To create a bundle containing all changesets, use
1086 parameters. To create a bundle containing all changesets, use
1087 -a/--all (or --base null).
1087 -a/--all (or --base null).
1088
1088
1089 You can change compression method with the -t/--type option.
1089 You can change compression method with the -t/--type option.
1090 The available compression methods are: none, bzip2, and
1090 The available compression methods are: none, bzip2, and
1091 gzip (by default, bundles are compressed using bzip2).
1091 gzip (by default, bundles are compressed using bzip2).
1092
1092
1093 The bundle file can then be transferred using conventional means
1093 The bundle file can then be transferred using conventional means
1094 and applied to another repository with the unbundle or pull
1094 and applied to another repository with the unbundle or pull
1095 command. This is useful when direct push and pull are not
1095 command. This is useful when direct push and pull are not
1096 available or when exporting an entire repository is undesirable.
1096 available or when exporting an entire repository is undesirable.
1097
1097
1098 Applying bundles preserves all changeset contents including
1098 Applying bundles preserves all changeset contents including
1099 permissions, copy/rename information, and revision history.
1099 permissions, copy/rename information, and revision history.
1100
1100
1101 Returns 0 on success, 1 if no changes found.
1101 Returns 0 on success, 1 if no changes found.
1102 """
1102 """
1103 revs = None
1103 revs = None
1104 if 'rev' in opts:
1104 if 'rev' in opts:
1105 revs = scmutil.revrange(repo, opts['rev'])
1105 revs = scmutil.revrange(repo, opts['rev'])
1106
1106
1107 bundletype = opts.get('type', 'bzip2').lower()
1107 bundletype = opts.get('type', 'bzip2').lower()
1108 btypes = {'none': 'HG10UN', 'bzip2': 'HG10BZ', 'gzip': 'HG10GZ'}
1108 btypes = {'none': 'HG10UN', 'bzip2': 'HG10BZ', 'gzip': 'HG10GZ'}
1109 bundletype = btypes.get(bundletype)
1109 bundletype = btypes.get(bundletype)
1110 if bundletype not in changegroup.bundletypes:
1110 if bundletype not in changegroup.bundletypes:
1111 raise util.Abort(_('unknown bundle type specified with --type'))
1111 raise util.Abort(_('unknown bundle type specified with --type'))
1112
1112
1113 if opts.get('all'):
1113 if opts.get('all'):
1114 base = ['null']
1114 base = ['null']
1115 else:
1115 else:
1116 base = scmutil.revrange(repo, opts.get('base'))
1116 base = scmutil.revrange(repo, opts.get('base'))
1117 # TODO: get desired bundlecaps from command line.
1117 # TODO: get desired bundlecaps from command line.
1118 bundlecaps = None
1118 bundlecaps = None
1119 if base:
1119 if base:
1120 if dest:
1120 if dest:
1121 raise util.Abort(_("--base is incompatible with specifying "
1121 raise util.Abort(_("--base is incompatible with specifying "
1122 "a destination"))
1122 "a destination"))
1123 common = [repo.lookup(rev) for rev in base]
1123 common = [repo.lookup(rev) for rev in base]
1124 heads = revs and map(repo.lookup, revs) or revs
1124 heads = revs and map(repo.lookup, revs) or revs
1125 cg = repo.getbundle('bundle', heads=heads, common=common,
1125 cg = repo.getbundle('bundle', heads=heads, common=common,
1126 bundlecaps=bundlecaps)
1126 bundlecaps=bundlecaps)
1127 outgoing = None
1127 outgoing = None
1128 else:
1128 else:
1129 dest = ui.expandpath(dest or 'default-push', dest or 'default')
1129 dest = ui.expandpath(dest or 'default-push', dest or 'default')
1130 dest, branches = hg.parseurl(dest, opts.get('branch'))
1130 dest, branches = hg.parseurl(dest, opts.get('branch'))
1131 other = hg.peer(repo, opts, dest)
1131 other = hg.peer(repo, opts, dest)
1132 revs, checkout = hg.addbranchrevs(repo, repo, branches, revs)
1132 revs, checkout = hg.addbranchrevs(repo, repo, branches, revs)
1133 heads = revs and map(repo.lookup, revs) or revs
1133 heads = revs and map(repo.lookup, revs) or revs
1134 outgoing = discovery.findcommonoutgoing(repo, other,
1134 outgoing = discovery.findcommonoutgoing(repo, other,
1135 onlyheads=heads,
1135 onlyheads=heads,
1136 force=opts.get('force'),
1136 force=opts.get('force'),
1137 portable=True)
1137 portable=True)
1138 cg = repo.getlocalbundle('bundle', outgoing, bundlecaps)
1138 cg = repo.getlocalbundle('bundle', outgoing, bundlecaps)
1139 if not cg:
1139 if not cg:
1140 scmutil.nochangesfound(ui, repo, outgoing and outgoing.excluded)
1140 scmutil.nochangesfound(ui, repo, outgoing and outgoing.excluded)
1141 return 1
1141 return 1
1142
1142
1143 changegroup.writebundle(cg, fname, bundletype)
1143 changegroup.writebundle(cg, fname, bundletype)
1144
1144
1145 @command('cat',
1145 @command('cat',
1146 [('o', 'output', '',
1146 [('o', 'output', '',
1147 _('print output to file with formatted name'), _('FORMAT')),
1147 _('print output to file with formatted name'), _('FORMAT')),
1148 ('r', 'rev', '', _('print the given revision'), _('REV')),
1148 ('r', 'rev', '', _('print the given revision'), _('REV')),
1149 ('', 'decode', None, _('apply any matching decode filter')),
1149 ('', 'decode', None, _('apply any matching decode filter')),
1150 ] + walkopts,
1150 ] + walkopts,
1151 _('[OPTION]... FILE...'))
1151 _('[OPTION]... FILE...'))
1152 def cat(ui, repo, file1, *pats, **opts):
1152 def cat(ui, repo, file1, *pats, **opts):
1153 """output the current or given revision of files
1153 """output the current or given revision of files
1154
1154
1155 Print the specified files as they were at the given revision. If
1155 Print the specified files as they were at the given revision. If
1156 no revision is given, the parent of the working directory is used.
1156 no revision is given, the parent of the working directory is used.
1157
1157
1158 Output may be to a file, in which case the name of the file is
1158 Output may be to a file, in which case the name of the file is
1159 given using a format string. The formatting rules are the same as
1159 given using a format string. The formatting rules are the same as
1160 for the export command, with the following additions:
1160 for the export command, with the following additions:
1161
1161
1162 :``%s``: basename of file being printed
1162 :``%s``: basename of file being printed
1163 :``%d``: dirname of file being printed, or '.' if in repository root
1163 :``%d``: dirname of file being printed, or '.' if in repository root
1164 :``%p``: root-relative path name of file being printed
1164 :``%p``: root-relative path name of file being printed
1165
1165
1166 Returns 0 on success.
1166 Returns 0 on success.
1167 """
1167 """
1168 ctx = scmutil.revsingle(repo, opts.get('rev'))
1168 ctx = scmutil.revsingle(repo, opts.get('rev'))
1169 err = 1
1169 err = 1
1170 m = scmutil.match(ctx, (file1,) + pats, opts)
1170 m = scmutil.match(ctx, (file1,) + pats, opts)
1171
1171
1172 def write(path):
1172 def write(path):
1173 fp = cmdutil.makefileobj(repo, opts.get('output'), ctx.node(),
1173 fp = cmdutil.makefileobj(repo, opts.get('output'), ctx.node(),
1174 pathname=path)
1174 pathname=path)
1175 data = ctx[path].data()
1175 data = ctx[path].data()
1176 if opts.get('decode'):
1176 if opts.get('decode'):
1177 data = repo.wwritedata(path, data)
1177 data = repo.wwritedata(path, data)
1178 fp.write(data)
1178 fp.write(data)
1179 fp.close()
1179 fp.close()
1180
1180
1181 # Automation often uses hg cat on single files, so special case it
1181 # Automation often uses hg cat on single files, so special case it
1182 # for performance to avoid the cost of parsing the manifest.
1182 # for performance to avoid the cost of parsing the manifest.
1183 if len(m.files()) == 1 and not m.anypats():
1183 if len(m.files()) == 1 and not m.anypats():
1184 file = m.files()[0]
1184 file = m.files()[0]
1185 mf = repo.manifest
1185 mf = repo.manifest
1186 mfnode = ctx._changeset[0]
1186 mfnode = ctx._changeset[0]
1187 if mf.find(mfnode, file)[0]:
1187 if mf.find(mfnode, file)[0]:
1188 write(file)
1188 write(file)
1189 return 0
1189 return 0
1190
1190
1191 for abs in ctx.walk(m):
1191 for abs in ctx.walk(m):
1192 write(abs)
1192 write(abs)
1193 err = 0
1193 err = 0
1194 return err
1194 return err
1195
1195
1196 @command('^clone',
1196 @command('^clone',
1197 [('U', 'noupdate', None,
1197 [('U', 'noupdate', None,
1198 _('the clone will include an empty working copy (only a repository)')),
1198 _('the clone will include an empty working copy (only a repository)')),
1199 ('u', 'updaterev', '', _('revision, tag or branch to check out'), _('REV')),
1199 ('u', 'updaterev', '', _('revision, tag or branch to check out'), _('REV')),
1200 ('r', 'rev', [], _('include the specified changeset'), _('REV')),
1200 ('r', 'rev', [], _('include the specified changeset'), _('REV')),
1201 ('b', 'branch', [], _('clone only the specified branch'), _('BRANCH')),
1201 ('b', 'branch', [], _('clone only the specified branch'), _('BRANCH')),
1202 ('', 'pull', None, _('use pull protocol to copy metadata')),
1202 ('', 'pull', None, _('use pull protocol to copy metadata')),
1203 ('', 'uncompressed', None, _('use uncompressed transfer (fast over LAN)')),
1203 ('', 'uncompressed', None, _('use uncompressed transfer (fast over LAN)')),
1204 ] + remoteopts,
1204 ] + remoteopts,
1205 _('[OPTION]... SOURCE [DEST]'))
1205 _('[OPTION]... SOURCE [DEST]'))
1206 def clone(ui, source, dest=None, **opts):
1206 def clone(ui, source, dest=None, **opts):
1207 """make a copy of an existing repository
1207 """make a copy of an existing repository
1208
1208
1209 Create a copy of an existing repository in a new directory.
1209 Create a copy of an existing repository in a new directory.
1210
1210
1211 If no destination directory name is specified, it defaults to the
1211 If no destination directory name is specified, it defaults to the
1212 basename of the source.
1212 basename of the source.
1213
1213
1214 The location of the source is added to the new repository's
1214 The location of the source is added to the new repository's
1215 ``.hg/hgrc`` file, as the default to be used for future pulls.
1215 ``.hg/hgrc`` file, as the default to be used for future pulls.
1216
1216
1217 Only local paths and ``ssh://`` URLs are supported as
1217 Only local paths and ``ssh://`` URLs are supported as
1218 destinations. For ``ssh://`` destinations, no working directory or
1218 destinations. For ``ssh://`` destinations, no working directory or
1219 ``.hg/hgrc`` will be created on the remote side.
1219 ``.hg/hgrc`` will be created on the remote side.
1220
1220
1221 To pull only a subset of changesets, specify one or more revisions
1221 To pull only a subset of changesets, specify one or more revisions
1222 identifiers with -r/--rev or branches with -b/--branch. The
1222 identifiers with -r/--rev or branches with -b/--branch. The
1223 resulting clone will contain only the specified changesets and
1223 resulting clone will contain only the specified changesets and
1224 their ancestors. These options (or 'clone src#rev dest') imply
1224 their ancestors. These options (or 'clone src#rev dest') imply
1225 --pull, even for local source repositories. Note that specifying a
1225 --pull, even for local source repositories. Note that specifying a
1226 tag will include the tagged changeset but not the changeset
1226 tag will include the tagged changeset but not the changeset
1227 containing the tag.
1227 containing the tag.
1228
1228
1229 If the source repository has a bookmark called '@' set, that
1229 If the source repository has a bookmark called '@' set, that
1230 revision will be checked out in the new repository by default.
1230 revision will be checked out in the new repository by default.
1231
1231
1232 To check out a particular version, use -u/--update, or
1232 To check out a particular version, use -u/--update, or
1233 -U/--noupdate to create a clone with no working directory.
1233 -U/--noupdate to create a clone with no working directory.
1234
1234
1235 .. container:: verbose
1235 .. container:: verbose
1236
1236
1237 For efficiency, hardlinks are used for cloning whenever the
1237 For efficiency, hardlinks are used for cloning whenever the
1238 source and destination are on the same filesystem (note this
1238 source and destination are on the same filesystem (note this
1239 applies only to the repository data, not to the working
1239 applies only to the repository data, not to the working
1240 directory). Some filesystems, such as AFS, implement hardlinking
1240 directory). Some filesystems, such as AFS, implement hardlinking
1241 incorrectly, but do not report errors. In these cases, use the
1241 incorrectly, but do not report errors. In these cases, use the
1242 --pull option to avoid hardlinking.
1242 --pull option to avoid hardlinking.
1243
1243
1244 In some cases, you can clone repositories and the working
1244 In some cases, you can clone repositories and the working
1245 directory using full hardlinks with ::
1245 directory using full hardlinks with ::
1246
1246
1247 $ cp -al REPO REPOCLONE
1247 $ cp -al REPO REPOCLONE
1248
1248
1249 This is the fastest way to clone, but it is not always safe. The
1249 This is the fastest way to clone, but it is not always safe. The
1250 operation is not atomic (making sure REPO is not modified during
1250 operation is not atomic (making sure REPO is not modified during
1251 the operation is up to you) and you have to make sure your
1251 the operation is up to you) and you have to make sure your
1252 editor breaks hardlinks (Emacs and most Linux Kernel tools do
1252 editor breaks hardlinks (Emacs and most Linux Kernel tools do
1253 so). Also, this is not compatible with certain extensions that
1253 so). Also, this is not compatible with certain extensions that
1254 place their metadata under the .hg directory, such as mq.
1254 place their metadata under the .hg directory, such as mq.
1255
1255
1256 Mercurial will update the working directory to the first applicable
1256 Mercurial will update the working directory to the first applicable
1257 revision from this list:
1257 revision from this list:
1258
1258
1259 a) null if -U or the source repository has no changesets
1259 a) null if -U or the source repository has no changesets
1260 b) if -u . and the source repository is local, the first parent of
1260 b) if -u . and the source repository is local, the first parent of
1261 the source repository's working directory
1261 the source repository's working directory
1262 c) the changeset specified with -u (if a branch name, this means the
1262 c) the changeset specified with -u (if a branch name, this means the
1263 latest head of that branch)
1263 latest head of that branch)
1264 d) the changeset specified with -r
1264 d) the changeset specified with -r
1265 e) the tipmost head specified with -b
1265 e) the tipmost head specified with -b
1266 f) the tipmost head specified with the url#branch source syntax
1266 f) the tipmost head specified with the url#branch source syntax
1267 g) the revision marked with the '@' bookmark, if present
1267 g) the revision marked with the '@' bookmark, if present
1268 h) the tipmost head of the default branch
1268 h) the tipmost head of the default branch
1269 i) tip
1269 i) tip
1270
1270
1271 Examples:
1271 Examples:
1272
1272
1273 - clone a remote repository to a new directory named hg/::
1273 - clone a remote repository to a new directory named hg/::
1274
1274
1275 hg clone http://selenic.com/hg
1275 hg clone http://selenic.com/hg
1276
1276
1277 - create a lightweight local clone::
1277 - create a lightweight local clone::
1278
1278
1279 hg clone project/ project-feature/
1279 hg clone project/ project-feature/
1280
1280
1281 - clone from an absolute path on an ssh server (note double-slash)::
1281 - clone from an absolute path on an ssh server (note double-slash)::
1282
1282
1283 hg clone ssh://user@server//home/projects/alpha/
1283 hg clone ssh://user@server//home/projects/alpha/
1284
1284
1285 - do a high-speed clone over a LAN while checking out a
1285 - do a high-speed clone over a LAN while checking out a
1286 specified version::
1286 specified version::
1287
1287
1288 hg clone --uncompressed http://server/repo -u 1.5
1288 hg clone --uncompressed http://server/repo -u 1.5
1289
1289
1290 - create a repository without changesets after a particular revision::
1290 - create a repository without changesets after a particular revision::
1291
1291
1292 hg clone -r 04e544 experimental/ good/
1292 hg clone -r 04e544 experimental/ good/
1293
1293
1294 - clone (and track) a particular named branch::
1294 - clone (and track) a particular named branch::
1295
1295
1296 hg clone http://selenic.com/hg#stable
1296 hg clone http://selenic.com/hg#stable
1297
1297
1298 See :hg:`help urls` for details on specifying URLs.
1298 See :hg:`help urls` for details on specifying URLs.
1299
1299
1300 Returns 0 on success.
1300 Returns 0 on success.
1301 """
1301 """
1302 if opts.get('noupdate') and opts.get('updaterev'):
1302 if opts.get('noupdate') and opts.get('updaterev'):
1303 raise util.Abort(_("cannot specify both --noupdate and --updaterev"))
1303 raise util.Abort(_("cannot specify both --noupdate and --updaterev"))
1304
1304
1305 r = hg.clone(ui, opts, source, dest,
1305 r = hg.clone(ui, opts, source, dest,
1306 pull=opts.get('pull'),
1306 pull=opts.get('pull'),
1307 stream=opts.get('uncompressed'),
1307 stream=opts.get('uncompressed'),
1308 rev=opts.get('rev'),
1308 rev=opts.get('rev'),
1309 update=opts.get('updaterev') or not opts.get('noupdate'),
1309 update=opts.get('updaterev') or not opts.get('noupdate'),
1310 branch=opts.get('branch'))
1310 branch=opts.get('branch'))
1311
1311
1312 return r is None
1312 return r is None
1313
1313
1314 @command('^commit|ci',
1314 @command('^commit|ci',
1315 [('A', 'addremove', None,
1315 [('A', 'addremove', None,
1316 _('mark new/missing files as added/removed before committing')),
1316 _('mark new/missing files as added/removed before committing')),
1317 ('', 'close-branch', None,
1317 ('', 'close-branch', None,
1318 _('mark a branch as closed, hiding it from the branch list')),
1318 _('mark a branch as closed, hiding it from the branch list')),
1319 ('', 'amend', None, _('amend the parent of the working dir')),
1319 ('', 'amend', None, _('amend the parent of the working dir')),
1320 ('s', 'secret', None, _('use the secret phase for committing')),
1320 ('s', 'secret', None, _('use the secret phase for committing')),
1321 ] + walkopts + commitopts + commitopts2 + subrepoopts,
1321 ] + walkopts + commitopts + commitopts2 + subrepoopts,
1322 _('[OPTION]... [FILE]...'))
1322 _('[OPTION]... [FILE]...'))
1323 def commit(ui, repo, *pats, **opts):
1323 def commit(ui, repo, *pats, **opts):
1324 """commit the specified files or all outstanding changes
1324 """commit the specified files or all outstanding changes
1325
1325
1326 Commit changes to the given files into the repository. Unlike a
1326 Commit changes to the given files into the repository. Unlike a
1327 centralized SCM, this operation is a local operation. See
1327 centralized SCM, this operation is a local operation. See
1328 :hg:`push` for a way to actively distribute your changes.
1328 :hg:`push` for a way to actively distribute your changes.
1329
1329
1330 If a list of files is omitted, all changes reported by :hg:`status`
1330 If a list of files is omitted, all changes reported by :hg:`status`
1331 will be committed.
1331 will be committed.
1332
1332
1333 If you are committing the result of a merge, do not provide any
1333 If you are committing the result of a merge, do not provide any
1334 filenames or -I/-X filters.
1334 filenames or -I/-X filters.
1335
1335
1336 If no commit message is specified, Mercurial starts your
1336 If no commit message is specified, Mercurial starts your
1337 configured editor where you can enter a message. In case your
1337 configured editor where you can enter a message. In case your
1338 commit fails, you will find a backup of your message in
1338 commit fails, you will find a backup of your message in
1339 ``.hg/last-message.txt``.
1339 ``.hg/last-message.txt``.
1340
1340
1341 The --amend flag can be used to amend the parent of the
1341 The --amend flag can be used to amend the parent of the
1342 working directory with a new commit that contains the changes
1342 working directory with a new commit that contains the changes
1343 in the parent in addition to those currently reported by :hg:`status`,
1343 in the parent in addition to those currently reported by :hg:`status`,
1344 if there are any. The old commit is stored in a backup bundle in
1344 if there are any. The old commit is stored in a backup bundle in
1345 ``.hg/strip-backup`` (see :hg:`help bundle` and :hg:`help unbundle`
1345 ``.hg/strip-backup`` (see :hg:`help bundle` and :hg:`help unbundle`
1346 on how to restore it).
1346 on how to restore it).
1347
1347
1348 Message, user and date are taken from the amended commit unless
1348 Message, user and date are taken from the amended commit unless
1349 specified. When a message isn't specified on the command line,
1349 specified. When a message isn't specified on the command line,
1350 the editor will open with the message of the amended commit.
1350 the editor will open with the message of the amended commit.
1351
1351
1352 It is not possible to amend public changesets (see :hg:`help phases`)
1352 It is not possible to amend public changesets (see :hg:`help phases`)
1353 or changesets that have children.
1353 or changesets that have children.
1354
1354
1355 See :hg:`help dates` for a list of formats valid for -d/--date.
1355 See :hg:`help dates` for a list of formats valid for -d/--date.
1356
1356
1357 Returns 0 on success, 1 if nothing changed.
1357 Returns 0 on success, 1 if nothing changed.
1358 """
1358 """
1359 if opts.get('subrepos'):
1359 if opts.get('subrepos'):
1360 if opts.get('amend'):
1360 if opts.get('amend'):
1361 raise util.Abort(_('cannot amend with --subrepos'))
1361 raise util.Abort(_('cannot amend with --subrepos'))
1362 # Let --subrepos on the command line override config setting.
1362 # Let --subrepos on the command line override config setting.
1363 ui.setconfig('ui', 'commitsubrepos', True)
1363 ui.setconfig('ui', 'commitsubrepos', True)
1364
1364
1365 # Save this for restoring it later
1365 # Save this for restoring it later
1366 oldcommitphase = ui.config('phases', 'new-commit')
1366 oldcommitphase = ui.config('phases', 'new-commit')
1367
1367
1368 cmdutil.checkunfinished(repo, commit=True)
1368 cmdutil.checkunfinished(repo, commit=True)
1369
1369
1370 branch = repo[None].branch()
1370 branch = repo[None].branch()
1371 bheads = repo.branchheads(branch)
1371 bheads = repo.branchheads(branch)
1372
1372
1373 extra = {}
1373 extra = {}
1374 if opts.get('close_branch'):
1374 if opts.get('close_branch'):
1375 extra['close'] = 1
1375 extra['close'] = 1
1376
1376
1377 if not bheads:
1377 if not bheads:
1378 raise util.Abort(_('can only close branch heads'))
1378 raise util.Abort(_('can only close branch heads'))
1379 elif opts.get('amend'):
1379 elif opts.get('amend'):
1380 if repo.parents()[0].p1().branch() != branch and \
1380 if repo.parents()[0].p1().branch() != branch and \
1381 repo.parents()[0].p2().branch() != branch:
1381 repo.parents()[0].p2().branch() != branch:
1382 raise util.Abort(_('can only close branch heads'))
1382 raise util.Abort(_('can only close branch heads'))
1383
1383
1384 if opts.get('amend'):
1384 if opts.get('amend'):
1385 if ui.configbool('ui', 'commitsubrepos'):
1385 if ui.configbool('ui', 'commitsubrepos'):
1386 raise util.Abort(_('cannot amend with ui.commitsubrepos enabled'))
1386 raise util.Abort(_('cannot amend with ui.commitsubrepos enabled'))
1387
1387
1388 old = repo['.']
1388 old = repo['.']
1389 if old.phase() == phases.public:
1389 if old.phase() == phases.public:
1390 raise util.Abort(_('cannot amend public changesets'))
1390 raise util.Abort(_('cannot amend public changesets'))
1391 if len(repo[None].parents()) > 1:
1391 if len(repo[None].parents()) > 1:
1392 raise util.Abort(_('cannot amend while merging'))
1392 raise util.Abort(_('cannot amend while merging'))
1393 if (not obsolete._enabled) and old.children():
1393 if (not obsolete._enabled) and old.children():
1394 raise util.Abort(_('cannot amend changeset with children'))
1394 raise util.Abort(_('cannot amend changeset with children'))
1395
1395
1396 e = cmdutil.commiteditor
1396 e = cmdutil.commiteditor
1397 if opts.get('force_editor'):
1397 if opts.get('force_editor'):
1398 e = cmdutil.commitforceeditor
1398 e = cmdutil.commitforceeditor
1399
1399
1400 def commitfunc(ui, repo, message, match, opts):
1400 def commitfunc(ui, repo, message, match, opts):
1401 editor = e
1401 editor = e
1402 # message contains text from -m or -l, if it's empty,
1402 # message contains text from -m or -l, if it's empty,
1403 # open the editor with the old message
1403 # open the editor with the old message
1404 if not message:
1404 if not message:
1405 message = old.description()
1405 message = old.description()
1406 editor = cmdutil.commitforceeditor
1406 editor = cmdutil.commitforceeditor
1407 try:
1407 try:
1408 if opts.get('secret'):
1408 if opts.get('secret'):
1409 ui.setconfig('phases', 'new-commit', 'secret')
1409 ui.setconfig('phases', 'new-commit', 'secret')
1410
1410
1411 return repo.commit(message,
1411 return repo.commit(message,
1412 opts.get('user') or old.user(),
1412 opts.get('user') or old.user(),
1413 opts.get('date') or old.date(),
1413 opts.get('date') or old.date(),
1414 match,
1414 match,
1415 editor=editor,
1415 editor=editor,
1416 extra=extra)
1416 extra=extra)
1417 finally:
1417 finally:
1418 ui.setconfig('phases', 'new-commit', oldcommitphase)
1418 ui.setconfig('phases', 'new-commit', oldcommitphase)
1419
1419
1420 current = repo._bookmarkcurrent
1420 current = repo._bookmarkcurrent
1421 marks = old.bookmarks()
1421 marks = old.bookmarks()
1422 node = cmdutil.amend(ui, repo, commitfunc, old, extra, pats, opts)
1422 node = cmdutil.amend(ui, repo, commitfunc, old, extra, pats, opts)
1423 if node == old.node():
1423 if node == old.node():
1424 ui.status(_("nothing changed\n"))
1424 ui.status(_("nothing changed\n"))
1425 return 1
1425 return 1
1426 elif marks:
1426 elif marks:
1427 ui.debug('moving bookmarks %r from %s to %s\n' %
1427 ui.debug('moving bookmarks %r from %s to %s\n' %
1428 (marks, old.hex(), hex(node)))
1428 (marks, old.hex(), hex(node)))
1429 newmarks = repo._bookmarks
1429 newmarks = repo._bookmarks
1430 for bm in marks:
1430 for bm in marks:
1431 newmarks[bm] = node
1431 newmarks[bm] = node
1432 if bm == current:
1432 if bm == current:
1433 bookmarks.setcurrent(repo, bm)
1433 bookmarks.setcurrent(repo, bm)
1434 newmarks.write()
1434 newmarks.write()
1435 else:
1435 else:
1436 e = cmdutil.commiteditor
1436 e = cmdutil.commiteditor
1437 if opts.get('force_editor'):
1437 if opts.get('force_editor'):
1438 e = cmdutil.commitforceeditor
1438 e = cmdutil.commitforceeditor
1439
1439
1440 def commitfunc(ui, repo, message, match, opts):
1440 def commitfunc(ui, repo, message, match, opts):
1441 try:
1441 try:
1442 if opts.get('secret'):
1442 if opts.get('secret'):
1443 ui.setconfig('phases', 'new-commit', 'secret')
1443 ui.setconfig('phases', 'new-commit', 'secret')
1444
1444
1445 return repo.commit(message, opts.get('user'), opts.get('date'),
1445 return repo.commit(message, opts.get('user'), opts.get('date'),
1446 match, editor=e, extra=extra)
1446 match, editor=e, extra=extra)
1447 finally:
1447 finally:
1448 ui.setconfig('phases', 'new-commit', oldcommitphase)
1448 ui.setconfig('phases', 'new-commit', oldcommitphase)
1449
1449
1450
1450
1451 node = cmdutil.commit(ui, repo, commitfunc, pats, opts)
1451 node = cmdutil.commit(ui, repo, commitfunc, pats, opts)
1452
1452
1453 if not node:
1453 if not node:
1454 stat = repo.status(match=scmutil.match(repo[None], pats, opts))
1454 stat = repo.status(match=scmutil.match(repo[None], pats, opts))
1455 if stat[3]:
1455 if stat[3]:
1456 ui.status(_("nothing changed (%d missing files, see "
1456 ui.status(_("nothing changed (%d missing files, see "
1457 "'hg status')\n") % len(stat[3]))
1457 "'hg status')\n") % len(stat[3]))
1458 else:
1458 else:
1459 ui.status(_("nothing changed\n"))
1459 ui.status(_("nothing changed\n"))
1460 return 1
1460 return 1
1461
1461
1462 cmdutil.commitstatus(repo, node, branch, bheads, opts)
1462 cmdutil.commitstatus(repo, node, branch, bheads, opts)
1463
1463
1464 @command('config|showconfig|debugconfig',
1464 @command('config|showconfig|debugconfig',
1465 [('u', 'untrusted', None, _('show untrusted configuration options')),
1465 [('u', 'untrusted', None, _('show untrusted configuration options')),
1466 ('e', 'edit', None, _('start editor'))],
1466 ('e', 'edit', None, _('start editor'))],
1467 _('[-u] [NAME]...'))
1467 _('[-u] [NAME]...'))
1468 def config(ui, repo, *values, **opts):
1468 def config(ui, repo, *values, **opts):
1469 """show combined config settings from all hgrc files
1469 """show combined config settings from all hgrc files
1470
1470
1471 With no arguments, print names and values of all config items.
1471 With no arguments, print names and values of all config items.
1472
1472
1473 With one argument of the form section.name, print just the value
1473 With one argument of the form section.name, print just the value
1474 of that config item.
1474 of that config item.
1475
1475
1476 With multiple arguments, print names and values of all config
1476 With multiple arguments, print names and values of all config
1477 items with matching section names.
1477 items with matching section names.
1478
1478
1479 With --debug, the source (filename and line number) is printed
1479 With --debug, the source (filename and line number) is printed
1480 for each config item.
1480 for each config item.
1481
1481
1482 Returns 0 on success.
1482 Returns 0 on success.
1483 """
1483 """
1484
1484
1485 if opts.get('edit'):
1485 if opts.get('edit'):
1486 paths = scmutil.userrcpath()
1486 paths = scmutil.userrcpath()
1487 for f in paths:
1487 for f in paths:
1488 if os.path.exists(f):
1488 if os.path.exists(f):
1489 break
1489 break
1490 else:
1490 else:
1491 f = paths[0]
1491 f = paths[0]
1492 fp = open(f, "w")
1492 fp = open(f, "w")
1493 fp.write(
1493 fp.write(
1494 '# example config (see "hg help config" for more info)\n'
1494 '# example config (see "hg help config" for more info)\n'
1495 '\n'
1495 '\n'
1496 '[ui]\n'
1496 '[ui]\n'
1497 '# set this to your full email address\n'
1497 '# set this to your full email address\n'
1498 'username =\n'
1498 'username =\n'
1499 '\n'
1499 '\n'
1500 '[extensions]\n'
1500 '[extensions]\n'
1501 '# uncomment these lines to enable some popular extensions\n'
1501 '# uncomment these lines to enable some popular extensions\n'
1502 '# (see "hg help extensions" for more info)\n'
1502 '# (see "hg help extensions" for more info)\n'
1503 '# pager =\n'
1503 '# pager =\n'
1504 '# progress =\n'
1504 '# progress =\n'
1505 '# color =\n')
1505 '# color =\n')
1506 fp.close()
1506 fp.close()
1507
1507
1508 editor = ui.geteditor()
1508 editor = ui.geteditor()
1509 util.system("%s \"%s\"" % (editor, f),
1509 util.system("%s \"%s\"" % (editor, f),
1510 onerr=util.Abort, errprefix=_("edit failed"),
1510 onerr=util.Abort, errprefix=_("edit failed"),
1511 out=ui.fout)
1511 out=ui.fout)
1512 return
1512 return
1513
1513
1514 for f in scmutil.rcpath():
1514 for f in scmutil.rcpath():
1515 ui.debug('read config from: %s\n' % f)
1515 ui.debug('read config from: %s\n' % f)
1516 untrusted = bool(opts.get('untrusted'))
1516 untrusted = bool(opts.get('untrusted'))
1517 if values:
1517 if values:
1518 sections = [v for v in values if '.' not in v]
1518 sections = [v for v in values if '.' not in v]
1519 items = [v for v in values if '.' in v]
1519 items = [v for v in values if '.' in v]
1520 if len(items) > 1 or items and sections:
1520 if len(items) > 1 or items and sections:
1521 raise util.Abort(_('only one config item permitted'))
1521 raise util.Abort(_('only one config item permitted'))
1522 for section, name, value in ui.walkconfig(untrusted=untrusted):
1522 for section, name, value in ui.walkconfig(untrusted=untrusted):
1523 value = str(value).replace('\n', '\\n')
1523 value = str(value).replace('\n', '\\n')
1524 sectname = section + '.' + name
1524 sectname = section + '.' + name
1525 if values:
1525 if values:
1526 for v in values:
1526 for v in values:
1527 if v == section:
1527 if v == section:
1528 ui.debug('%s: ' %
1528 ui.debug('%s: ' %
1529 ui.configsource(section, name, untrusted))
1529 ui.configsource(section, name, untrusted))
1530 ui.write('%s=%s\n' % (sectname, value))
1530 ui.write('%s=%s\n' % (sectname, value))
1531 elif v == sectname:
1531 elif v == sectname:
1532 ui.debug('%s: ' %
1532 ui.debug('%s: ' %
1533 ui.configsource(section, name, untrusted))
1533 ui.configsource(section, name, untrusted))
1534 ui.write(value, '\n')
1534 ui.write(value, '\n')
1535 else:
1535 else:
1536 ui.debug('%s: ' %
1536 ui.debug('%s: ' %
1537 ui.configsource(section, name, untrusted))
1537 ui.configsource(section, name, untrusted))
1538 ui.write('%s=%s\n' % (sectname, value))
1538 ui.write('%s=%s\n' % (sectname, value))
1539
1539
1540 @command('copy|cp',
1540 @command('copy|cp',
1541 [('A', 'after', None, _('record a copy that has already occurred')),
1541 [('A', 'after', None, _('record a copy that has already occurred')),
1542 ('f', 'force', None, _('forcibly copy over an existing managed file')),
1542 ('f', 'force', None, _('forcibly copy over an existing managed file')),
1543 ] + walkopts + dryrunopts,
1543 ] + walkopts + dryrunopts,
1544 _('[OPTION]... [SOURCE]... DEST'))
1544 _('[OPTION]... [SOURCE]... DEST'))
1545 def copy(ui, repo, *pats, **opts):
1545 def copy(ui, repo, *pats, **opts):
1546 """mark files as copied for the next commit
1546 """mark files as copied for the next commit
1547
1547
1548 Mark dest as having copies of source files. If dest is a
1548 Mark dest as having copies of source files. If dest is a
1549 directory, copies are put in that directory. If dest is a file,
1549 directory, copies are put in that directory. If dest is a file,
1550 the source must be a single file.
1550 the source must be a single file.
1551
1551
1552 By default, this command copies the contents of files as they
1552 By default, this command copies the contents of files as they
1553 exist in the working directory. If invoked with -A/--after, the
1553 exist in the working directory. If invoked with -A/--after, the
1554 operation is recorded, but no copying is performed.
1554 operation is recorded, but no copying is performed.
1555
1555
1556 This command takes effect with the next commit. To undo a copy
1556 This command takes effect with the next commit. To undo a copy
1557 before that, see :hg:`revert`.
1557 before that, see :hg:`revert`.
1558
1558
1559 Returns 0 on success, 1 if errors are encountered.
1559 Returns 0 on success, 1 if errors are encountered.
1560 """
1560 """
1561 wlock = repo.wlock(False)
1561 wlock = repo.wlock(False)
1562 try:
1562 try:
1563 return cmdutil.copy(ui, repo, pats, opts)
1563 return cmdutil.copy(ui, repo, pats, opts)
1564 finally:
1564 finally:
1565 wlock.release()
1565 wlock.release()
1566
1566
1567 @command('debugancestor', [], _('[INDEX] REV1 REV2'))
1567 @command('debugancestor', [], _('[INDEX] REV1 REV2'))
1568 def debugancestor(ui, repo, *args):
1568 def debugancestor(ui, repo, *args):
1569 """find the ancestor revision of two revisions in a given index"""
1569 """find the ancestor revision of two revisions in a given index"""
1570 if len(args) == 3:
1570 if len(args) == 3:
1571 index, rev1, rev2 = args
1571 index, rev1, rev2 = args
1572 r = revlog.revlog(scmutil.opener(os.getcwd(), audit=False), index)
1572 r = revlog.revlog(scmutil.opener(os.getcwd(), audit=False), index)
1573 lookup = r.lookup
1573 lookup = r.lookup
1574 elif len(args) == 2:
1574 elif len(args) == 2:
1575 if not repo:
1575 if not repo:
1576 raise util.Abort(_("there is no Mercurial repository here "
1576 raise util.Abort(_("there is no Mercurial repository here "
1577 "(.hg not found)"))
1577 "(.hg not found)"))
1578 rev1, rev2 = args
1578 rev1, rev2 = args
1579 r = repo.changelog
1579 r = repo.changelog
1580 lookup = repo.lookup
1580 lookup = repo.lookup
1581 else:
1581 else:
1582 raise util.Abort(_('either two or three arguments required'))
1582 raise util.Abort(_('either two or three arguments required'))
1583 a = r.ancestor(lookup(rev1), lookup(rev2))
1583 a = r.ancestor(lookup(rev1), lookup(rev2))
1584 ui.write("%d:%s\n" % (r.rev(a), hex(a)))
1584 ui.write("%d:%s\n" % (r.rev(a), hex(a)))
1585
1585
1586 @command('debugbuilddag',
1586 @command('debugbuilddag',
1587 [('m', 'mergeable-file', None, _('add single file mergeable changes')),
1587 [('m', 'mergeable-file', None, _('add single file mergeable changes')),
1588 ('o', 'overwritten-file', None, _('add single file all revs overwrite')),
1588 ('o', 'overwritten-file', None, _('add single file all revs overwrite')),
1589 ('n', 'new-file', None, _('add new file at each rev'))],
1589 ('n', 'new-file', None, _('add new file at each rev'))],
1590 _('[OPTION]... [TEXT]'))
1590 _('[OPTION]... [TEXT]'))
1591 def debugbuilddag(ui, repo, text=None,
1591 def debugbuilddag(ui, repo, text=None,
1592 mergeable_file=False,
1592 mergeable_file=False,
1593 overwritten_file=False,
1593 overwritten_file=False,
1594 new_file=False):
1594 new_file=False):
1595 """builds a repo with a given DAG from scratch in the current empty repo
1595 """builds a repo with a given DAG from scratch in the current empty repo
1596
1596
1597 The description of the DAG is read from stdin if not given on the
1597 The description of the DAG is read from stdin if not given on the
1598 command line.
1598 command line.
1599
1599
1600 Elements:
1600 Elements:
1601
1601
1602 - "+n" is a linear run of n nodes based on the current default parent
1602 - "+n" is a linear run of n nodes based on the current default parent
1603 - "." is a single node based on the current default parent
1603 - "." is a single node based on the current default parent
1604 - "$" resets the default parent to null (implied at the start);
1604 - "$" resets the default parent to null (implied at the start);
1605 otherwise the default parent is always the last node created
1605 otherwise the default parent is always the last node created
1606 - "<p" sets the default parent to the backref p
1606 - "<p" sets the default parent to the backref p
1607 - "*p" is a fork at parent p, which is a backref
1607 - "*p" is a fork at parent p, which is a backref
1608 - "*p1/p2" is a merge of parents p1 and p2, which are backrefs
1608 - "*p1/p2" is a merge of parents p1 and p2, which are backrefs
1609 - "/p2" is a merge of the preceding node and p2
1609 - "/p2" is a merge of the preceding node and p2
1610 - ":tag" defines a local tag for the preceding node
1610 - ":tag" defines a local tag for the preceding node
1611 - "@branch" sets the named branch for subsequent nodes
1611 - "@branch" sets the named branch for subsequent nodes
1612 - "#...\\n" is a comment up to the end of the line
1612 - "#...\\n" is a comment up to the end of the line
1613
1613
1614 Whitespace between the above elements is ignored.
1614 Whitespace between the above elements is ignored.
1615
1615
1616 A backref is either
1616 A backref is either
1617
1617
1618 - a number n, which references the node curr-n, where curr is the current
1618 - a number n, which references the node curr-n, where curr is the current
1619 node, or
1619 node, or
1620 - the name of a local tag you placed earlier using ":tag", or
1620 - the name of a local tag you placed earlier using ":tag", or
1621 - empty to denote the default parent.
1621 - empty to denote the default parent.
1622
1622
1623 All string valued-elements are either strictly alphanumeric, or must
1623 All string valued-elements are either strictly alphanumeric, or must
1624 be enclosed in double quotes ("..."), with "\\" as escape character.
1624 be enclosed in double quotes ("..."), with "\\" as escape character.
1625 """
1625 """
1626
1626
1627 if text is None:
1627 if text is None:
1628 ui.status(_("reading DAG from stdin\n"))
1628 ui.status(_("reading DAG from stdin\n"))
1629 text = ui.fin.read()
1629 text = ui.fin.read()
1630
1630
1631 cl = repo.changelog
1631 cl = repo.changelog
1632 if len(cl) > 0:
1632 if len(cl) > 0:
1633 raise util.Abort(_('repository is not empty'))
1633 raise util.Abort(_('repository is not empty'))
1634
1634
1635 # determine number of revs in DAG
1635 # determine number of revs in DAG
1636 total = 0
1636 total = 0
1637 for type, data in dagparser.parsedag(text):
1637 for type, data in dagparser.parsedag(text):
1638 if type == 'n':
1638 if type == 'n':
1639 total += 1
1639 total += 1
1640
1640
1641 if mergeable_file:
1641 if mergeable_file:
1642 linesperrev = 2
1642 linesperrev = 2
1643 # make a file with k lines per rev
1643 # make a file with k lines per rev
1644 initialmergedlines = [str(i) for i in xrange(0, total * linesperrev)]
1644 initialmergedlines = [str(i) for i in xrange(0, total * linesperrev)]
1645 initialmergedlines.append("")
1645 initialmergedlines.append("")
1646
1646
1647 tags = []
1647 tags = []
1648
1648
1649 lock = tr = None
1649 lock = tr = None
1650 try:
1650 try:
1651 lock = repo.lock()
1651 lock = repo.lock()
1652 tr = repo.transaction("builddag")
1652 tr = repo.transaction("builddag")
1653
1653
1654 at = -1
1654 at = -1
1655 atbranch = 'default'
1655 atbranch = 'default'
1656 nodeids = []
1656 nodeids = []
1657 id = 0
1657 id = 0
1658 ui.progress(_('building'), id, unit=_('revisions'), total=total)
1658 ui.progress(_('building'), id, unit=_('revisions'), total=total)
1659 for type, data in dagparser.parsedag(text):
1659 for type, data in dagparser.parsedag(text):
1660 if type == 'n':
1660 if type == 'n':
1661 ui.note(('node %s\n' % str(data)))
1661 ui.note(('node %s\n' % str(data)))
1662 id, ps = data
1662 id, ps = data
1663
1663
1664 files = []
1664 files = []
1665 fctxs = {}
1665 fctxs = {}
1666
1666
1667 p2 = None
1667 p2 = None
1668 if mergeable_file:
1668 if mergeable_file:
1669 fn = "mf"
1669 fn = "mf"
1670 p1 = repo[ps[0]]
1670 p1 = repo[ps[0]]
1671 if len(ps) > 1:
1671 if len(ps) > 1:
1672 p2 = repo[ps[1]]
1672 p2 = repo[ps[1]]
1673 pa = p1.ancestor(p2)
1673 pa = p1.ancestor(p2)
1674 base, local, other = [x[fn].data() for x in (pa, p1,
1674 base, local, other = [x[fn].data() for x in (pa, p1,
1675 p2)]
1675 p2)]
1676 m3 = simplemerge.Merge3Text(base, local, other)
1676 m3 = simplemerge.Merge3Text(base, local, other)
1677 ml = [l.strip() for l in m3.merge_lines()]
1677 ml = [l.strip() for l in m3.merge_lines()]
1678 ml.append("")
1678 ml.append("")
1679 elif at > 0:
1679 elif at > 0:
1680 ml = p1[fn].data().split("\n")
1680 ml = p1[fn].data().split("\n")
1681 else:
1681 else:
1682 ml = initialmergedlines
1682 ml = initialmergedlines
1683 ml[id * linesperrev] += " r%i" % id
1683 ml[id * linesperrev] += " r%i" % id
1684 mergedtext = "\n".join(ml)
1684 mergedtext = "\n".join(ml)
1685 files.append(fn)
1685 files.append(fn)
1686 fctxs[fn] = context.memfilectx(fn, mergedtext)
1686 fctxs[fn] = context.memfilectx(fn, mergedtext)
1687
1687
1688 if overwritten_file:
1688 if overwritten_file:
1689 fn = "of"
1689 fn = "of"
1690 files.append(fn)
1690 files.append(fn)
1691 fctxs[fn] = context.memfilectx(fn, "r%i\n" % id)
1691 fctxs[fn] = context.memfilectx(fn, "r%i\n" % id)
1692
1692
1693 if new_file:
1693 if new_file:
1694 fn = "nf%i" % id
1694 fn = "nf%i" % id
1695 files.append(fn)
1695 files.append(fn)
1696 fctxs[fn] = context.memfilectx(fn, "r%i\n" % id)
1696 fctxs[fn] = context.memfilectx(fn, "r%i\n" % id)
1697 if len(ps) > 1:
1697 if len(ps) > 1:
1698 if not p2:
1698 if not p2:
1699 p2 = repo[ps[1]]
1699 p2 = repo[ps[1]]
1700 for fn in p2:
1700 for fn in p2:
1701 if fn.startswith("nf"):
1701 if fn.startswith("nf"):
1702 files.append(fn)
1702 files.append(fn)
1703 fctxs[fn] = p2[fn]
1703 fctxs[fn] = p2[fn]
1704
1704
1705 def fctxfn(repo, cx, path):
1705 def fctxfn(repo, cx, path):
1706 return fctxs.get(path)
1706 return fctxs.get(path)
1707
1707
1708 if len(ps) == 0 or ps[0] < 0:
1708 if len(ps) == 0 or ps[0] < 0:
1709 pars = [None, None]
1709 pars = [None, None]
1710 elif len(ps) == 1:
1710 elif len(ps) == 1:
1711 pars = [nodeids[ps[0]], None]
1711 pars = [nodeids[ps[0]], None]
1712 else:
1712 else:
1713 pars = [nodeids[p] for p in ps]
1713 pars = [nodeids[p] for p in ps]
1714 cx = context.memctx(repo, pars, "r%i" % id, files, fctxfn,
1714 cx = context.memctx(repo, pars, "r%i" % id, files, fctxfn,
1715 date=(id, 0),
1715 date=(id, 0),
1716 user="debugbuilddag",
1716 user="debugbuilddag",
1717 extra={'branch': atbranch})
1717 extra={'branch': atbranch})
1718 nodeid = repo.commitctx(cx)
1718 nodeid = repo.commitctx(cx)
1719 nodeids.append(nodeid)
1719 nodeids.append(nodeid)
1720 at = id
1720 at = id
1721 elif type == 'l':
1721 elif type == 'l':
1722 id, name = data
1722 id, name = data
1723 ui.note(('tag %s\n' % name))
1723 ui.note(('tag %s\n' % name))
1724 tags.append("%s %s\n" % (hex(repo.changelog.node(id)), name))
1724 tags.append("%s %s\n" % (hex(repo.changelog.node(id)), name))
1725 elif type == 'a':
1725 elif type == 'a':
1726 ui.note(('branch %s\n' % data))
1726 ui.note(('branch %s\n' % data))
1727 atbranch = data
1727 atbranch = data
1728 ui.progress(_('building'), id, unit=_('revisions'), total=total)
1728 ui.progress(_('building'), id, unit=_('revisions'), total=total)
1729 tr.close()
1729 tr.close()
1730
1730
1731 if tags:
1731 if tags:
1732 repo.opener.write("localtags", "".join(tags))
1732 repo.opener.write("localtags", "".join(tags))
1733 finally:
1733 finally:
1734 ui.progress(_('building'), None)
1734 ui.progress(_('building'), None)
1735 release(tr, lock)
1735 release(tr, lock)
1736
1736
1737 @command('debugbundle', [('a', 'all', None, _('show all details'))], _('FILE'))
1737 @command('debugbundle', [('a', 'all', None, _('show all details'))], _('FILE'))
1738 def debugbundle(ui, bundlepath, all=None, **opts):
1738 def debugbundle(ui, bundlepath, all=None, **opts):
1739 """lists the contents of a bundle"""
1739 """lists the contents of a bundle"""
1740 f = hg.openpath(ui, bundlepath)
1740 f = hg.openpath(ui, bundlepath)
1741 try:
1741 try:
1742 gen = changegroup.readbundle(f, bundlepath)
1742 gen = changegroup.readbundle(f, bundlepath)
1743 if all:
1743 if all:
1744 ui.write(("format: id, p1, p2, cset, delta base, len(delta)\n"))
1744 ui.write(("format: id, p1, p2, cset, delta base, len(delta)\n"))
1745
1745
1746 def showchunks(named):
1746 def showchunks(named):
1747 ui.write("\n%s\n" % named)
1747 ui.write("\n%s\n" % named)
1748 chain = None
1748 chain = None
1749 while True:
1749 while True:
1750 chunkdata = gen.deltachunk(chain)
1750 chunkdata = gen.deltachunk(chain)
1751 if not chunkdata:
1751 if not chunkdata:
1752 break
1752 break
1753 node = chunkdata['node']
1753 node = chunkdata['node']
1754 p1 = chunkdata['p1']
1754 p1 = chunkdata['p1']
1755 p2 = chunkdata['p2']
1755 p2 = chunkdata['p2']
1756 cs = chunkdata['cs']
1756 cs = chunkdata['cs']
1757 deltabase = chunkdata['deltabase']
1757 deltabase = chunkdata['deltabase']
1758 delta = chunkdata['delta']
1758 delta = chunkdata['delta']
1759 ui.write("%s %s %s %s %s %s\n" %
1759 ui.write("%s %s %s %s %s %s\n" %
1760 (hex(node), hex(p1), hex(p2),
1760 (hex(node), hex(p1), hex(p2),
1761 hex(cs), hex(deltabase), len(delta)))
1761 hex(cs), hex(deltabase), len(delta)))
1762 chain = node
1762 chain = node
1763
1763
1764 chunkdata = gen.changelogheader()
1764 chunkdata = gen.changelogheader()
1765 showchunks("changelog")
1765 showchunks("changelog")
1766 chunkdata = gen.manifestheader()
1766 chunkdata = gen.manifestheader()
1767 showchunks("manifest")
1767 showchunks("manifest")
1768 while True:
1768 while True:
1769 chunkdata = gen.filelogheader()
1769 chunkdata = gen.filelogheader()
1770 if not chunkdata:
1770 if not chunkdata:
1771 break
1771 break
1772 fname = chunkdata['filename']
1772 fname = chunkdata['filename']
1773 showchunks(fname)
1773 showchunks(fname)
1774 else:
1774 else:
1775 chunkdata = gen.changelogheader()
1775 chunkdata = gen.changelogheader()
1776 chain = None
1776 chain = None
1777 while True:
1777 while True:
1778 chunkdata = gen.deltachunk(chain)
1778 chunkdata = gen.deltachunk(chain)
1779 if not chunkdata:
1779 if not chunkdata:
1780 break
1780 break
1781 node = chunkdata['node']
1781 node = chunkdata['node']
1782 ui.write("%s\n" % hex(node))
1782 ui.write("%s\n" % hex(node))
1783 chain = node
1783 chain = node
1784 finally:
1784 finally:
1785 f.close()
1785 f.close()
1786
1786
1787 @command('debugcheckstate', [], '')
1787 @command('debugcheckstate', [], '')
1788 def debugcheckstate(ui, repo):
1788 def debugcheckstate(ui, repo):
1789 """validate the correctness of the current dirstate"""
1789 """validate the correctness of the current dirstate"""
1790 parent1, parent2 = repo.dirstate.parents()
1790 parent1, parent2 = repo.dirstate.parents()
1791 m1 = repo[parent1].manifest()
1791 m1 = repo[parent1].manifest()
1792 m2 = repo[parent2].manifest()
1792 m2 = repo[parent2].manifest()
1793 errors = 0
1793 errors = 0
1794 for f in repo.dirstate:
1794 for f in repo.dirstate:
1795 state = repo.dirstate[f]
1795 state = repo.dirstate[f]
1796 if state in "nr" and f not in m1:
1796 if state in "nr" and f not in m1:
1797 ui.warn(_("%s in state %s, but not in manifest1\n") % (f, state))
1797 ui.warn(_("%s in state %s, but not in manifest1\n") % (f, state))
1798 errors += 1
1798 errors += 1
1799 if state in "a" and f in m1:
1799 if state in "a" and f in m1:
1800 ui.warn(_("%s in state %s, but also in manifest1\n") % (f, state))
1800 ui.warn(_("%s in state %s, but also in manifest1\n") % (f, state))
1801 errors += 1
1801 errors += 1
1802 if state in "m" and f not in m1 and f not in m2:
1802 if state in "m" and f not in m1 and f not in m2:
1803 ui.warn(_("%s in state %s, but not in either manifest\n") %
1803 ui.warn(_("%s in state %s, but not in either manifest\n") %
1804 (f, state))
1804 (f, state))
1805 errors += 1
1805 errors += 1
1806 for f in m1:
1806 for f in m1:
1807 state = repo.dirstate[f]
1807 state = repo.dirstate[f]
1808 if state not in "nrm":
1808 if state not in "nrm":
1809 ui.warn(_("%s in manifest1, but listed as state %s") % (f, state))
1809 ui.warn(_("%s in manifest1, but listed as state %s") % (f, state))
1810 errors += 1
1810 errors += 1
1811 if errors:
1811 if errors:
1812 error = _(".hg/dirstate inconsistent with current parent's manifest")
1812 error = _(".hg/dirstate inconsistent with current parent's manifest")
1813 raise util.Abort(error)
1813 raise util.Abort(error)
1814
1814
1815 @command('debugcommands', [], _('[COMMAND]'))
1815 @command('debugcommands', [], _('[COMMAND]'))
1816 def debugcommands(ui, cmd='', *args):
1816 def debugcommands(ui, cmd='', *args):
1817 """list all available commands and options"""
1817 """list all available commands and options"""
1818 for cmd, vals in sorted(table.iteritems()):
1818 for cmd, vals in sorted(table.iteritems()):
1819 cmd = cmd.split('|')[0].strip('^')
1819 cmd = cmd.split('|')[0].strip('^')
1820 opts = ', '.join([i[1] for i in vals[1]])
1820 opts = ', '.join([i[1] for i in vals[1]])
1821 ui.write('%s: %s\n' % (cmd, opts))
1821 ui.write('%s: %s\n' % (cmd, opts))
1822
1822
1823 @command('debugcomplete',
1823 @command('debugcomplete',
1824 [('o', 'options', None, _('show the command options'))],
1824 [('o', 'options', None, _('show the command options'))],
1825 _('[-o] CMD'))
1825 _('[-o] CMD'))
1826 def debugcomplete(ui, cmd='', **opts):
1826 def debugcomplete(ui, cmd='', **opts):
1827 """returns the completion list associated with the given command"""
1827 """returns the completion list associated with the given command"""
1828
1828
1829 if opts.get('options'):
1829 if opts.get('options'):
1830 options = []
1830 options = []
1831 otables = [globalopts]
1831 otables = [globalopts]
1832 if cmd:
1832 if cmd:
1833 aliases, entry = cmdutil.findcmd(cmd, table, False)
1833 aliases, entry = cmdutil.findcmd(cmd, table, False)
1834 otables.append(entry[1])
1834 otables.append(entry[1])
1835 for t in otables:
1835 for t in otables:
1836 for o in t:
1836 for o in t:
1837 if "(DEPRECATED)" in o[3]:
1837 if "(DEPRECATED)" in o[3]:
1838 continue
1838 continue
1839 if o[0]:
1839 if o[0]:
1840 options.append('-%s' % o[0])
1840 options.append('-%s' % o[0])
1841 options.append('--%s' % o[1])
1841 options.append('--%s' % o[1])
1842 ui.write("%s\n" % "\n".join(options))
1842 ui.write("%s\n" % "\n".join(options))
1843 return
1843 return
1844
1844
1845 cmdlist = cmdutil.findpossible(cmd, table)
1845 cmdlist = cmdutil.findpossible(cmd, table)
1846 if ui.verbose:
1846 if ui.verbose:
1847 cmdlist = [' '.join(c[0]) for c in cmdlist.values()]
1847 cmdlist = [' '.join(c[0]) for c in cmdlist.values()]
1848 ui.write("%s\n" % "\n".join(sorted(cmdlist)))
1848 ui.write("%s\n" % "\n".join(sorted(cmdlist)))
1849
1849
1850 @command('debugdag',
1850 @command('debugdag',
1851 [('t', 'tags', None, _('use tags as labels')),
1851 [('t', 'tags', None, _('use tags as labels')),
1852 ('b', 'branches', None, _('annotate with branch names')),
1852 ('b', 'branches', None, _('annotate with branch names')),
1853 ('', 'dots', None, _('use dots for runs')),
1853 ('', 'dots', None, _('use dots for runs')),
1854 ('s', 'spaces', None, _('separate elements by spaces'))],
1854 ('s', 'spaces', None, _('separate elements by spaces'))],
1855 _('[OPTION]... [FILE [REV]...]'))
1855 _('[OPTION]... [FILE [REV]...]'))
1856 def debugdag(ui, repo, file_=None, *revs, **opts):
1856 def debugdag(ui, repo, file_=None, *revs, **opts):
1857 """format the changelog or an index DAG as a concise textual description
1857 """format the changelog or an index DAG as a concise textual description
1858
1858
1859 If you pass a revlog index, the revlog's DAG is emitted. If you list
1859 If you pass a revlog index, the revlog's DAG is emitted. If you list
1860 revision numbers, they get labeled in the output as rN.
1860 revision numbers, they get labeled in the output as rN.
1861
1861
1862 Otherwise, the changelog DAG of the current repo is emitted.
1862 Otherwise, the changelog DAG of the current repo is emitted.
1863 """
1863 """
1864 spaces = opts.get('spaces')
1864 spaces = opts.get('spaces')
1865 dots = opts.get('dots')
1865 dots = opts.get('dots')
1866 if file_:
1866 if file_:
1867 rlog = revlog.revlog(scmutil.opener(os.getcwd(), audit=False), file_)
1867 rlog = revlog.revlog(scmutil.opener(os.getcwd(), audit=False), file_)
1868 revs = set((int(r) for r in revs))
1868 revs = set((int(r) for r in revs))
1869 def events():
1869 def events():
1870 for r in rlog:
1870 for r in rlog:
1871 yield 'n', (r, list(set(p for p in rlog.parentrevs(r)
1871 yield 'n', (r, list(set(p for p in rlog.parentrevs(r)
1872 if p != -1)))
1872 if p != -1)))
1873 if r in revs:
1873 if r in revs:
1874 yield 'l', (r, "r%i" % r)
1874 yield 'l', (r, "r%i" % r)
1875 elif repo:
1875 elif repo:
1876 cl = repo.changelog
1876 cl = repo.changelog
1877 tags = opts.get('tags')
1877 tags = opts.get('tags')
1878 branches = opts.get('branches')
1878 branches = opts.get('branches')
1879 if tags:
1879 if tags:
1880 labels = {}
1880 labels = {}
1881 for l, n in repo.tags().items():
1881 for l, n in repo.tags().items():
1882 labels.setdefault(cl.rev(n), []).append(l)
1882 labels.setdefault(cl.rev(n), []).append(l)
1883 def events():
1883 def events():
1884 b = "default"
1884 b = "default"
1885 for r in cl:
1885 for r in cl:
1886 if branches:
1886 if branches:
1887 newb = cl.read(cl.node(r))[5]['branch']
1887 newb = cl.read(cl.node(r))[5]['branch']
1888 if newb != b:
1888 if newb != b:
1889 yield 'a', newb
1889 yield 'a', newb
1890 b = newb
1890 b = newb
1891 yield 'n', (r, list(set(p for p in cl.parentrevs(r)
1891 yield 'n', (r, list(set(p for p in cl.parentrevs(r)
1892 if p != -1)))
1892 if p != -1)))
1893 if tags:
1893 if tags:
1894 ls = labels.get(r)
1894 ls = labels.get(r)
1895 if ls:
1895 if ls:
1896 for l in ls:
1896 for l in ls:
1897 yield 'l', (r, l)
1897 yield 'l', (r, l)
1898 else:
1898 else:
1899 raise util.Abort(_('need repo for changelog dag'))
1899 raise util.Abort(_('need repo for changelog dag'))
1900
1900
1901 for line in dagparser.dagtextlines(events(),
1901 for line in dagparser.dagtextlines(events(),
1902 addspaces=spaces,
1902 addspaces=spaces,
1903 wraplabels=True,
1903 wraplabels=True,
1904 wrapannotations=True,
1904 wrapannotations=True,
1905 wrapnonlinear=dots,
1905 wrapnonlinear=dots,
1906 usedots=dots,
1906 usedots=dots,
1907 maxlinewidth=70):
1907 maxlinewidth=70):
1908 ui.write(line)
1908 ui.write(line)
1909 ui.write("\n")
1909 ui.write("\n")
1910
1910
1911 @command('debugdata',
1911 @command('debugdata',
1912 [('c', 'changelog', False, _('open changelog')),
1912 [('c', 'changelog', False, _('open changelog')),
1913 ('m', 'manifest', False, _('open manifest'))],
1913 ('m', 'manifest', False, _('open manifest'))],
1914 _('-c|-m|FILE REV'))
1914 _('-c|-m|FILE REV'))
1915 def debugdata(ui, repo, file_, rev=None, **opts):
1915 def debugdata(ui, repo, file_, rev=None, **opts):
1916 """dump the contents of a data file revision"""
1916 """dump the contents of a data file revision"""
1917 if opts.get('changelog') or opts.get('manifest'):
1917 if opts.get('changelog') or opts.get('manifest'):
1918 file_, rev = None, file_
1918 file_, rev = None, file_
1919 elif rev is None:
1919 elif rev is None:
1920 raise error.CommandError('debugdata', _('invalid arguments'))
1920 raise error.CommandError('debugdata', _('invalid arguments'))
1921 r = cmdutil.openrevlog(repo, 'debugdata', file_, opts)
1921 r = cmdutil.openrevlog(repo, 'debugdata', file_, opts)
1922 try:
1922 try:
1923 ui.write(r.revision(r.lookup(rev)))
1923 ui.write(r.revision(r.lookup(rev)))
1924 except KeyError:
1924 except KeyError:
1925 raise util.Abort(_('invalid revision identifier %s') % rev)
1925 raise util.Abort(_('invalid revision identifier %s') % rev)
1926
1926
1927 @command('debugdate',
1927 @command('debugdate',
1928 [('e', 'extended', None, _('try extended date formats'))],
1928 [('e', 'extended', None, _('try extended date formats'))],
1929 _('[-e] DATE [RANGE]'))
1929 _('[-e] DATE [RANGE]'))
1930 def debugdate(ui, date, range=None, **opts):
1930 def debugdate(ui, date, range=None, **opts):
1931 """parse and display a date"""
1931 """parse and display a date"""
1932 if opts["extended"]:
1932 if opts["extended"]:
1933 d = util.parsedate(date, util.extendeddateformats)
1933 d = util.parsedate(date, util.extendeddateformats)
1934 else:
1934 else:
1935 d = util.parsedate(date)
1935 d = util.parsedate(date)
1936 ui.write(("internal: %s %s\n") % d)
1936 ui.write(("internal: %s %s\n") % d)
1937 ui.write(("standard: %s\n") % util.datestr(d))
1937 ui.write(("standard: %s\n") % util.datestr(d))
1938 if range:
1938 if range:
1939 m = util.matchdate(range)
1939 m = util.matchdate(range)
1940 ui.write(("match: %s\n") % m(d[0]))
1940 ui.write(("match: %s\n") % m(d[0]))
1941
1941
1942 @command('debugdiscovery',
1942 @command('debugdiscovery',
1943 [('', 'old', None, _('use old-style discovery')),
1943 [('', 'old', None, _('use old-style discovery')),
1944 ('', 'nonheads', None,
1944 ('', 'nonheads', None,
1945 _('use old-style discovery with non-heads included')),
1945 _('use old-style discovery with non-heads included')),
1946 ] + remoteopts,
1946 ] + remoteopts,
1947 _('[-l REV] [-r REV] [-b BRANCH]... [OTHER]'))
1947 _('[-l REV] [-r REV] [-b BRANCH]... [OTHER]'))
1948 def debugdiscovery(ui, repo, remoteurl="default", **opts):
1948 def debugdiscovery(ui, repo, remoteurl="default", **opts):
1949 """runs the changeset discovery protocol in isolation"""
1949 """runs the changeset discovery protocol in isolation"""
1950 remoteurl, branches = hg.parseurl(ui.expandpath(remoteurl),
1950 remoteurl, branches = hg.parseurl(ui.expandpath(remoteurl),
1951 opts.get('branch'))
1951 opts.get('branch'))
1952 remote = hg.peer(repo, opts, remoteurl)
1952 remote = hg.peer(repo, opts, remoteurl)
1953 ui.status(_('comparing with %s\n') % util.hidepassword(remoteurl))
1953 ui.status(_('comparing with %s\n') % util.hidepassword(remoteurl))
1954
1954
1955 # make sure tests are repeatable
1955 # make sure tests are repeatable
1956 random.seed(12323)
1956 random.seed(12323)
1957
1957
1958 def doit(localheads, remoteheads, remote=remote):
1958 def doit(localheads, remoteheads, remote=remote):
1959 if opts.get('old'):
1959 if opts.get('old'):
1960 if localheads:
1960 if localheads:
1961 raise util.Abort('cannot use localheads with old style '
1961 raise util.Abort('cannot use localheads with old style '
1962 'discovery')
1962 'discovery')
1963 if not util.safehasattr(remote, 'branches'):
1963 if not util.safehasattr(remote, 'branches'):
1964 # enable in-client legacy support
1964 # enable in-client legacy support
1965 remote = localrepo.locallegacypeer(remote.local())
1965 remote = localrepo.locallegacypeer(remote.local())
1966 common, _in, hds = treediscovery.findcommonincoming(repo, remote,
1966 common, _in, hds = treediscovery.findcommonincoming(repo, remote,
1967 force=True)
1967 force=True)
1968 common = set(common)
1968 common = set(common)
1969 if not opts.get('nonheads'):
1969 if not opts.get('nonheads'):
1970 ui.write(("unpruned common: %s\n") %
1970 ui.write(("unpruned common: %s\n") %
1971 " ".join(sorted(short(n) for n in common)))
1971 " ".join(sorted(short(n) for n in common)))
1972 dag = dagutil.revlogdag(repo.changelog)
1972 dag = dagutil.revlogdag(repo.changelog)
1973 all = dag.ancestorset(dag.internalizeall(common))
1973 all = dag.ancestorset(dag.internalizeall(common))
1974 common = dag.externalizeall(dag.headsetofconnecteds(all))
1974 common = dag.externalizeall(dag.headsetofconnecteds(all))
1975 else:
1975 else:
1976 common, any, hds = setdiscovery.findcommonheads(ui, repo, remote)
1976 common, any, hds = setdiscovery.findcommonheads(ui, repo, remote)
1977 common = set(common)
1977 common = set(common)
1978 rheads = set(hds)
1978 rheads = set(hds)
1979 lheads = set(repo.heads())
1979 lheads = set(repo.heads())
1980 ui.write(("common heads: %s\n") %
1980 ui.write(("common heads: %s\n") %
1981 " ".join(sorted(short(n) for n in common)))
1981 " ".join(sorted(short(n) for n in common)))
1982 if lheads <= common:
1982 if lheads <= common:
1983 ui.write(("local is subset\n"))
1983 ui.write(("local is subset\n"))
1984 elif rheads <= common:
1984 elif rheads <= common:
1985 ui.write(("remote is subset\n"))
1985 ui.write(("remote is subset\n"))
1986
1986
1987 serverlogs = opts.get('serverlog')
1987 serverlogs = opts.get('serverlog')
1988 if serverlogs:
1988 if serverlogs:
1989 for filename in serverlogs:
1989 for filename in serverlogs:
1990 logfile = open(filename, 'r')
1990 logfile = open(filename, 'r')
1991 try:
1991 try:
1992 line = logfile.readline()
1992 line = logfile.readline()
1993 while line:
1993 while line:
1994 parts = line.strip().split(';')
1994 parts = line.strip().split(';')
1995 op = parts[1]
1995 op = parts[1]
1996 if op == 'cg':
1996 if op == 'cg':
1997 pass
1997 pass
1998 elif op == 'cgss':
1998 elif op == 'cgss':
1999 doit(parts[2].split(' '), parts[3].split(' '))
1999 doit(parts[2].split(' '), parts[3].split(' '))
2000 elif op == 'unb':
2000 elif op == 'unb':
2001 doit(parts[3].split(' '), parts[2].split(' '))
2001 doit(parts[3].split(' '), parts[2].split(' '))
2002 line = logfile.readline()
2002 line = logfile.readline()
2003 finally:
2003 finally:
2004 logfile.close()
2004 logfile.close()
2005
2005
2006 else:
2006 else:
2007 remoterevs, _checkout = hg.addbranchrevs(repo, remote, branches,
2007 remoterevs, _checkout = hg.addbranchrevs(repo, remote, branches,
2008 opts.get('remote_head'))
2008 opts.get('remote_head'))
2009 localrevs = opts.get('local_head')
2009 localrevs = opts.get('local_head')
2010 doit(localrevs, remoterevs)
2010 doit(localrevs, remoterevs)
2011
2011
2012 @command('debugfileset',
2012 @command('debugfileset',
2013 [('r', 'rev', '', _('apply the filespec on this revision'), _('REV'))],
2013 [('r', 'rev', '', _('apply the filespec on this revision'), _('REV'))],
2014 _('[-r REV] FILESPEC'))
2014 _('[-r REV] FILESPEC'))
2015 def debugfileset(ui, repo, expr, **opts):
2015 def debugfileset(ui, repo, expr, **opts):
2016 '''parse and apply a fileset specification'''
2016 '''parse and apply a fileset specification'''
2017 ctx = scmutil.revsingle(repo, opts.get('rev'), None)
2017 ctx = scmutil.revsingle(repo, opts.get('rev'), None)
2018 if ui.verbose:
2018 if ui.verbose:
2019 tree = fileset.parse(expr)[0]
2019 tree = fileset.parse(expr)[0]
2020 ui.note(tree, "\n")
2020 ui.note(tree, "\n")
2021
2021
2022 for f in ctx.getfileset(expr):
2022 for f in ctx.getfileset(expr):
2023 ui.write("%s\n" % f)
2023 ui.write("%s\n" % f)
2024
2024
2025 @command('debugfsinfo', [], _('[PATH]'))
2025 @command('debugfsinfo', [], _('[PATH]'))
2026 def debugfsinfo(ui, path="."):
2026 def debugfsinfo(ui, path="."):
2027 """show information detected about current filesystem"""
2027 """show information detected about current filesystem"""
2028 util.writefile('.debugfsinfo', '')
2028 util.writefile('.debugfsinfo', '')
2029 ui.write(('exec: %s\n') % (util.checkexec(path) and 'yes' or 'no'))
2029 ui.write(('exec: %s\n') % (util.checkexec(path) and 'yes' or 'no'))
2030 ui.write(('symlink: %s\n') % (util.checklink(path) and 'yes' or 'no'))
2030 ui.write(('symlink: %s\n') % (util.checklink(path) and 'yes' or 'no'))
2031 ui.write(('hardlink: %s\n') % (util.checknlink(path) and 'yes' or 'no'))
2031 ui.write(('hardlink: %s\n') % (util.checknlink(path) and 'yes' or 'no'))
2032 ui.write(('case-sensitive: %s\n') % (util.checkcase('.debugfsinfo')
2032 ui.write(('case-sensitive: %s\n') % (util.checkcase('.debugfsinfo')
2033 and 'yes' or 'no'))
2033 and 'yes' or 'no'))
2034 os.unlink('.debugfsinfo')
2034 os.unlink('.debugfsinfo')
2035
2035
2036 @command('debuggetbundle',
2036 @command('debuggetbundle',
2037 [('H', 'head', [], _('id of head node'), _('ID')),
2037 [('H', 'head', [], _('id of head node'), _('ID')),
2038 ('C', 'common', [], _('id of common node'), _('ID')),
2038 ('C', 'common', [], _('id of common node'), _('ID')),
2039 ('t', 'type', 'bzip2', _('bundle compression type to use'), _('TYPE'))],
2039 ('t', 'type', 'bzip2', _('bundle compression type to use'), _('TYPE'))],
2040 _('REPO FILE [-H|-C ID]...'))
2040 _('REPO FILE [-H|-C ID]...'))
2041 def debuggetbundle(ui, repopath, bundlepath, head=None, common=None, **opts):
2041 def debuggetbundle(ui, repopath, bundlepath, head=None, common=None, **opts):
2042 """retrieves a bundle from a repo
2042 """retrieves a bundle from a repo
2043
2043
2044 Every ID must be a full-length hex node id string. Saves the bundle to the
2044 Every ID must be a full-length hex node id string. Saves the bundle to the
2045 given file.
2045 given file.
2046 """
2046 """
2047 repo = hg.peer(ui, opts, repopath)
2047 repo = hg.peer(ui, opts, repopath)
2048 if not repo.capable('getbundle'):
2048 if not repo.capable('getbundle'):
2049 raise util.Abort("getbundle() not supported by target repository")
2049 raise util.Abort("getbundle() not supported by target repository")
2050 args = {}
2050 args = {}
2051 if common:
2051 if common:
2052 args['common'] = [bin(s) for s in common]
2052 args['common'] = [bin(s) for s in common]
2053 if head:
2053 if head:
2054 args['heads'] = [bin(s) for s in head]
2054 args['heads'] = [bin(s) for s in head]
2055 # TODO: get desired bundlecaps from command line.
2055 # TODO: get desired bundlecaps from command line.
2056 args['bundlecaps'] = None
2056 args['bundlecaps'] = None
2057 bundle = repo.getbundle('debug', **args)
2057 bundle = repo.getbundle('debug', **args)
2058
2058
2059 bundletype = opts.get('type', 'bzip2').lower()
2059 bundletype = opts.get('type', 'bzip2').lower()
2060 btypes = {'none': 'HG10UN', 'bzip2': 'HG10BZ', 'gzip': 'HG10GZ'}
2060 btypes = {'none': 'HG10UN', 'bzip2': 'HG10BZ', 'gzip': 'HG10GZ'}
2061 bundletype = btypes.get(bundletype)
2061 bundletype = btypes.get(bundletype)
2062 if bundletype not in changegroup.bundletypes:
2062 if bundletype not in changegroup.bundletypes:
2063 raise util.Abort(_('unknown bundle type specified with --type'))
2063 raise util.Abort(_('unknown bundle type specified with --type'))
2064 changegroup.writebundle(bundle, bundlepath, bundletype)
2064 changegroup.writebundle(bundle, bundlepath, bundletype)
2065
2065
2066 @command('debugignore', [], '')
2066 @command('debugignore', [], '')
2067 def debugignore(ui, repo, *values, **opts):
2067 def debugignore(ui, repo, *values, **opts):
2068 """display the combined ignore pattern"""
2068 """display the combined ignore pattern"""
2069 ignore = repo.dirstate._ignore
2069 ignore = repo.dirstate._ignore
2070 includepat = getattr(ignore, 'includepat', None)
2070 includepat = getattr(ignore, 'includepat', None)
2071 if includepat is not None:
2071 if includepat is not None:
2072 ui.write("%s\n" % includepat)
2072 ui.write("%s\n" % includepat)
2073 else:
2073 else:
2074 raise util.Abort(_("no ignore patterns found"))
2074 raise util.Abort(_("no ignore patterns found"))
2075
2075
2076 @command('debugindex',
2076 @command('debugindex',
2077 [('c', 'changelog', False, _('open changelog')),
2077 [('c', 'changelog', False, _('open changelog')),
2078 ('m', 'manifest', False, _('open manifest')),
2078 ('m', 'manifest', False, _('open manifest')),
2079 ('f', 'format', 0, _('revlog format'), _('FORMAT'))],
2079 ('f', 'format', 0, _('revlog format'), _('FORMAT'))],
2080 _('[-f FORMAT] -c|-m|FILE'))
2080 _('[-f FORMAT] -c|-m|FILE'))
2081 def debugindex(ui, repo, file_=None, **opts):
2081 def debugindex(ui, repo, file_=None, **opts):
2082 """dump the contents of an index file"""
2082 """dump the contents of an index file"""
2083 r = cmdutil.openrevlog(repo, 'debugindex', file_, opts)
2083 r = cmdutil.openrevlog(repo, 'debugindex', file_, opts)
2084 format = opts.get('format', 0)
2084 format = opts.get('format', 0)
2085 if format not in (0, 1):
2085 if format not in (0, 1):
2086 raise util.Abort(_("unknown format %d") % format)
2086 raise util.Abort(_("unknown format %d") % format)
2087
2087
2088 generaldelta = r.version & revlog.REVLOGGENERALDELTA
2088 generaldelta = r.version & revlog.REVLOGGENERALDELTA
2089 if generaldelta:
2089 if generaldelta:
2090 basehdr = ' delta'
2090 basehdr = ' delta'
2091 else:
2091 else:
2092 basehdr = ' base'
2092 basehdr = ' base'
2093
2093
2094 if format == 0:
2094 if format == 0:
2095 ui.write(" rev offset length " + basehdr + " linkrev"
2095 ui.write(" rev offset length " + basehdr + " linkrev"
2096 " nodeid p1 p2\n")
2096 " nodeid p1 p2\n")
2097 elif format == 1:
2097 elif format == 1:
2098 ui.write(" rev flag offset length"
2098 ui.write(" rev flag offset length"
2099 " size " + basehdr + " link p1 p2"
2099 " size " + basehdr + " link p1 p2"
2100 " nodeid\n")
2100 " nodeid\n")
2101
2101
2102 for i in r:
2102 for i in r:
2103 node = r.node(i)
2103 node = r.node(i)
2104 if generaldelta:
2104 if generaldelta:
2105 base = r.deltaparent(i)
2105 base = r.deltaparent(i)
2106 else:
2106 else:
2107 base = r.chainbase(i)
2107 base = r.chainbase(i)
2108 if format == 0:
2108 if format == 0:
2109 try:
2109 try:
2110 pp = r.parents(node)
2110 pp = r.parents(node)
2111 except Exception:
2111 except Exception:
2112 pp = [nullid, nullid]
2112 pp = [nullid, nullid]
2113 ui.write("% 6d % 9d % 7d % 6d % 7d %s %s %s\n" % (
2113 ui.write("% 6d % 9d % 7d % 6d % 7d %s %s %s\n" % (
2114 i, r.start(i), r.length(i), base, r.linkrev(i),
2114 i, r.start(i), r.length(i), base, r.linkrev(i),
2115 short(node), short(pp[0]), short(pp[1])))
2115 short(node), short(pp[0]), short(pp[1])))
2116 elif format == 1:
2116 elif format == 1:
2117 pr = r.parentrevs(i)
2117 pr = r.parentrevs(i)
2118 ui.write("% 6d %04x % 8d % 8d % 8d % 6d % 6d % 6d % 6d %s\n" % (
2118 ui.write("% 6d %04x % 8d % 8d % 8d % 6d % 6d % 6d % 6d %s\n" % (
2119 i, r.flags(i), r.start(i), r.length(i), r.rawsize(i),
2119 i, r.flags(i), r.start(i), r.length(i), r.rawsize(i),
2120 base, r.linkrev(i), pr[0], pr[1], short(node)))
2120 base, r.linkrev(i), pr[0], pr[1], short(node)))
2121
2121
2122 @command('debugindexdot', [], _('FILE'))
2122 @command('debugindexdot', [], _('FILE'))
2123 def debugindexdot(ui, repo, file_):
2123 def debugindexdot(ui, repo, file_):
2124 """dump an index DAG as a graphviz dot file"""
2124 """dump an index DAG as a graphviz dot file"""
2125 r = None
2125 r = None
2126 if repo:
2126 if repo:
2127 filelog = repo.file(file_)
2127 filelog = repo.file(file_)
2128 if len(filelog):
2128 if len(filelog):
2129 r = filelog
2129 r = filelog
2130 if not r:
2130 if not r:
2131 r = revlog.revlog(scmutil.opener(os.getcwd(), audit=False), file_)
2131 r = revlog.revlog(scmutil.opener(os.getcwd(), audit=False), file_)
2132 ui.write(("digraph G {\n"))
2132 ui.write(("digraph G {\n"))
2133 for i in r:
2133 for i in r:
2134 node = r.node(i)
2134 node = r.node(i)
2135 pp = r.parents(node)
2135 pp = r.parents(node)
2136 ui.write("\t%d -> %d\n" % (r.rev(pp[0]), i))
2136 ui.write("\t%d -> %d\n" % (r.rev(pp[0]), i))
2137 if pp[1] != nullid:
2137 if pp[1] != nullid:
2138 ui.write("\t%d -> %d\n" % (r.rev(pp[1]), i))
2138 ui.write("\t%d -> %d\n" % (r.rev(pp[1]), i))
2139 ui.write("}\n")
2139 ui.write("}\n")
2140
2140
2141 @command('debuginstall', [], '')
2141 @command('debuginstall', [], '')
2142 def debuginstall(ui):
2142 def debuginstall(ui):
2143 '''test Mercurial installation
2143 '''test Mercurial installation
2144
2144
2145 Returns 0 on success.
2145 Returns 0 on success.
2146 '''
2146 '''
2147
2147
2148 def writetemp(contents):
2148 def writetemp(contents):
2149 (fd, name) = tempfile.mkstemp(prefix="hg-debuginstall-")
2149 (fd, name) = tempfile.mkstemp(prefix="hg-debuginstall-")
2150 f = os.fdopen(fd, "wb")
2150 f = os.fdopen(fd, "wb")
2151 f.write(contents)
2151 f.write(contents)
2152 f.close()
2152 f.close()
2153 return name
2153 return name
2154
2154
2155 problems = 0
2155 problems = 0
2156
2156
2157 # encoding
2157 # encoding
2158 ui.status(_("checking encoding (%s)...\n") % encoding.encoding)
2158 ui.status(_("checking encoding (%s)...\n") % encoding.encoding)
2159 try:
2159 try:
2160 encoding.fromlocal("test")
2160 encoding.fromlocal("test")
2161 except util.Abort, inst:
2161 except util.Abort, inst:
2162 ui.write(" %s\n" % inst)
2162 ui.write(" %s\n" % inst)
2163 ui.write(_(" (check that your locale is properly set)\n"))
2163 ui.write(_(" (check that your locale is properly set)\n"))
2164 problems += 1
2164 problems += 1
2165
2165
2166 # Python lib
2166 # Python lib
2167 ui.status(_("checking Python lib (%s)...\n")
2167 ui.status(_("checking Python lib (%s)...\n")
2168 % os.path.dirname(os.__file__))
2168 % os.path.dirname(os.__file__))
2169
2169
2170 # compiled modules
2170 # compiled modules
2171 ui.status(_("checking installed modules (%s)...\n")
2171 ui.status(_("checking installed modules (%s)...\n")
2172 % os.path.dirname(__file__))
2172 % os.path.dirname(__file__))
2173 try:
2173 try:
2174 import bdiff, mpatch, base85, osutil
2174 import bdiff, mpatch, base85, osutil
2175 dir(bdiff), dir(mpatch), dir(base85), dir(osutil) # quiet pyflakes
2175 dir(bdiff), dir(mpatch), dir(base85), dir(osutil) # quiet pyflakes
2176 except Exception, inst:
2176 except Exception, inst:
2177 ui.write(" %s\n" % inst)
2177 ui.write(" %s\n" % inst)
2178 ui.write(_(" One or more extensions could not be found"))
2178 ui.write(_(" One or more extensions could not be found"))
2179 ui.write(_(" (check that you compiled the extensions)\n"))
2179 ui.write(_(" (check that you compiled the extensions)\n"))
2180 problems += 1
2180 problems += 1
2181
2181
2182 # templates
2182 # templates
2183 import templater
2183 import templater
2184 p = templater.templatepath()
2184 p = templater.templatepath()
2185 ui.status(_("checking templates (%s)...\n") % ' '.join(p))
2185 ui.status(_("checking templates (%s)...\n") % ' '.join(p))
2186 if p:
2186 if p:
2187 m = templater.templatepath("map-cmdline.default")
2187 m = templater.templatepath("map-cmdline.default")
2188 if m:
2188 if m:
2189 # template found, check if it is working
2189 # template found, check if it is working
2190 try:
2190 try:
2191 templater.templater(m)
2191 templater.templater(m)
2192 except Exception, inst:
2192 except Exception, inst:
2193 ui.write(" %s\n" % inst)
2193 ui.write(" %s\n" % inst)
2194 p = None
2194 p = None
2195 else:
2195 else:
2196 ui.write(_(" template 'default' not found\n"))
2196 ui.write(_(" template 'default' not found\n"))
2197 p = None
2197 p = None
2198 else:
2198 else:
2199 ui.write(_(" no template directories found\n"))
2199 ui.write(_(" no template directories found\n"))
2200 if not p:
2200 if not p:
2201 ui.write(_(" (templates seem to have been installed incorrectly)\n"))
2201 ui.write(_(" (templates seem to have been installed incorrectly)\n"))
2202 problems += 1
2202 problems += 1
2203
2203
2204 # editor
2204 # editor
2205 ui.status(_("checking commit editor...\n"))
2205 ui.status(_("checking commit editor...\n"))
2206 editor = ui.geteditor()
2206 editor = ui.geteditor()
2207 cmdpath = util.findexe(editor) or util.findexe(editor.split()[0])
2207 cmdpath = util.findexe(editor) or util.findexe(editor.split()[0])
2208 if not cmdpath:
2208 if not cmdpath:
2209 if editor == 'vi':
2209 if editor == 'vi':
2210 ui.write(_(" No commit editor set and can't find vi in PATH\n"))
2210 ui.write(_(" No commit editor set and can't find vi in PATH\n"))
2211 ui.write(_(" (specify a commit editor in your configuration"
2211 ui.write(_(" (specify a commit editor in your configuration"
2212 " file)\n"))
2212 " file)\n"))
2213 else:
2213 else:
2214 ui.write(_(" Can't find editor '%s' in PATH\n") % editor)
2214 ui.write(_(" Can't find editor '%s' in PATH\n") % editor)
2215 ui.write(_(" (specify a commit editor in your configuration"
2215 ui.write(_(" (specify a commit editor in your configuration"
2216 " file)\n"))
2216 " file)\n"))
2217 problems += 1
2217 problems += 1
2218
2218
2219 # check username
2219 # check username
2220 ui.status(_("checking username...\n"))
2220 ui.status(_("checking username...\n"))
2221 try:
2221 try:
2222 ui.username()
2222 ui.username()
2223 except util.Abort, e:
2223 except util.Abort, e:
2224 ui.write(" %s\n" % e)
2224 ui.write(" %s\n" % e)
2225 ui.write(_(" (specify a username in your configuration file)\n"))
2225 ui.write(_(" (specify a username in your configuration file)\n"))
2226 problems += 1
2226 problems += 1
2227
2227
2228 if not problems:
2228 if not problems:
2229 ui.status(_("no problems detected\n"))
2229 ui.status(_("no problems detected\n"))
2230 else:
2230 else:
2231 ui.write(_("%s problems detected,"
2231 ui.write(_("%s problems detected,"
2232 " please check your install!\n") % problems)
2232 " please check your install!\n") % problems)
2233
2233
2234 return problems
2234 return problems
2235
2235
2236 @command('debugknown', [], _('REPO ID...'))
2236 @command('debugknown', [], _('REPO ID...'))
2237 def debugknown(ui, repopath, *ids, **opts):
2237 def debugknown(ui, repopath, *ids, **opts):
2238 """test whether node ids are known to a repo
2238 """test whether node ids are known to a repo
2239
2239
2240 Every ID must be a full-length hex node id string. Returns a list of 0s
2240 Every ID must be a full-length hex node id string. Returns a list of 0s
2241 and 1s indicating unknown/known.
2241 and 1s indicating unknown/known.
2242 """
2242 """
2243 repo = hg.peer(ui, opts, repopath)
2243 repo = hg.peer(ui, opts, repopath)
2244 if not repo.capable('known'):
2244 if not repo.capable('known'):
2245 raise util.Abort("known() not supported by target repository")
2245 raise util.Abort("known() not supported by target repository")
2246 flags = repo.known([bin(s) for s in ids])
2246 flags = repo.known([bin(s) for s in ids])
2247 ui.write("%s\n" % ("".join([f and "1" or "0" for f in flags])))
2247 ui.write("%s\n" % ("".join([f and "1" or "0" for f in flags])))
2248
2248
2249 @command('debuglabelcomplete', [], _('LABEL...'))
2249 @command('debuglabelcomplete', [], _('LABEL...'))
2250 def debuglabelcomplete(ui, repo, *args):
2250 def debuglabelcomplete(ui, repo, *args):
2251 '''complete "labels" - tags, open branch names, bookmark names'''
2251 '''complete "labels" - tags, open branch names, bookmark names'''
2252
2252
2253 labels = set()
2253 labels = set()
2254 labels.update(t[0] for t in repo.tagslist())
2254 labels.update(t[0] for t in repo.tagslist())
2255 labels.update(repo._bookmarks.keys())
2255 labels.update(repo._bookmarks.keys())
2256 labels.update(tag for (tag, heads, tip, closed)
2256 labels.update(tag for (tag, heads, tip, closed)
2257 in repo.branchmap().iterbranches() if not closed)
2257 in repo.branchmap().iterbranches() if not closed)
2258 completions = set()
2258 completions = set()
2259 if not args:
2259 if not args:
2260 args = ['']
2260 args = ['']
2261 for a in args:
2261 for a in args:
2262 completions.update(l for l in labels if l.startswith(a))
2262 completions.update(l for l in labels if l.startswith(a))
2263 ui.write('\n'.join(sorted(completions)))
2263 ui.write('\n'.join(sorted(completions)))
2264 ui.write('\n')
2264 ui.write('\n')
2265
2265
2266 @command('debugobsolete',
2266 @command('debugobsolete',
2267 [('', 'flags', 0, _('markers flag')),
2267 [('', 'flags', 0, _('markers flag')),
2268 ] + commitopts2,
2268 ] + commitopts2,
2269 _('[OBSOLETED [REPLACEMENT] [REPL... ]'))
2269 _('[OBSOLETED [REPLACEMENT] [REPL... ]'))
2270 def debugobsolete(ui, repo, precursor=None, *successors, **opts):
2270 def debugobsolete(ui, repo, precursor=None, *successors, **opts):
2271 """create arbitrary obsolete marker
2271 """create arbitrary obsolete marker
2272
2272
2273 With no arguments, displays the list of obsolescence markers."""
2273 With no arguments, displays the list of obsolescence markers."""
2274 def parsenodeid(s):
2274 def parsenodeid(s):
2275 try:
2275 try:
2276 # We do not use revsingle/revrange functions here to accept
2276 # We do not use revsingle/revrange functions here to accept
2277 # arbitrary node identifiers, possibly not present in the
2277 # arbitrary node identifiers, possibly not present in the
2278 # local repository.
2278 # local repository.
2279 n = bin(s)
2279 n = bin(s)
2280 if len(n) != len(nullid):
2280 if len(n) != len(nullid):
2281 raise TypeError()
2281 raise TypeError()
2282 return n
2282 return n
2283 except TypeError:
2283 except TypeError:
2284 raise util.Abort('changeset references must be full hexadecimal '
2284 raise util.Abort('changeset references must be full hexadecimal '
2285 'node identifiers')
2285 'node identifiers')
2286
2286
2287 if precursor is not None:
2287 if precursor is not None:
2288 metadata = {}
2288 metadata = {}
2289 if 'date' in opts:
2289 if 'date' in opts:
2290 metadata['date'] = opts['date']
2290 metadata['date'] = opts['date']
2291 metadata['user'] = opts['user'] or ui.username()
2291 metadata['user'] = opts['user'] or ui.username()
2292 succs = tuple(parsenodeid(succ) for succ in successors)
2292 succs = tuple(parsenodeid(succ) for succ in successors)
2293 l = repo.lock()
2293 l = repo.lock()
2294 try:
2294 try:
2295 tr = repo.transaction('debugobsolete')
2295 tr = repo.transaction('debugobsolete')
2296 try:
2296 try:
2297 repo.obsstore.create(tr, parsenodeid(precursor), succs,
2297 repo.obsstore.create(tr, parsenodeid(precursor), succs,
2298 opts['flags'], metadata)
2298 opts['flags'], metadata)
2299 tr.close()
2299 tr.close()
2300 finally:
2300 finally:
2301 tr.release()
2301 tr.release()
2302 finally:
2302 finally:
2303 l.release()
2303 l.release()
2304 else:
2304 else:
2305 for m in obsolete.allmarkers(repo):
2305 for m in obsolete.allmarkers(repo):
2306 cmdutil.showmarker(ui, m)
2306 cmdutil.showmarker(ui, m)
2307
2307
2308 @command('debugpathcomplete',
2308 @command('debugpathcomplete',
2309 [('f', 'full', None, _('complete an entire path')),
2309 [('f', 'full', None, _('complete an entire path')),
2310 ('n', 'normal', None, _('show only normal files')),
2310 ('n', 'normal', None, _('show only normal files')),
2311 ('a', 'added', None, _('show only added files')),
2311 ('a', 'added', None, _('show only added files')),
2312 ('r', 'removed', None, _('show only removed files'))],
2312 ('r', 'removed', None, _('show only removed files'))],
2313 _('FILESPEC...'))
2313 _('FILESPEC...'))
2314 def debugpathcomplete(ui, repo, *specs, **opts):
2314 def debugpathcomplete(ui, repo, *specs, **opts):
2315 '''complete part or all of a tracked path
2315 '''complete part or all of a tracked path
2316
2316
2317 This command supports shells that offer path name completion. It
2317 This command supports shells that offer path name completion. It
2318 currently completes only files already known to the dirstate.
2318 currently completes only files already known to the dirstate.
2319
2319
2320 Completion extends only to the next path segment unless
2320 Completion extends only to the next path segment unless
2321 --full is specified, in which case entire paths are used.'''
2321 --full is specified, in which case entire paths are used.'''
2322
2322
2323 def complete(path, acceptable):
2323 def complete(path, acceptable):
2324 dirstate = repo.dirstate
2324 dirstate = repo.dirstate
2325 spec = os.path.normpath(os.path.join(os.getcwd(), path))
2325 spec = os.path.normpath(os.path.join(os.getcwd(), path))
2326 rootdir = repo.root + os.sep
2326 rootdir = repo.root + os.sep
2327 if spec != repo.root and not spec.startswith(rootdir):
2327 if spec != repo.root and not spec.startswith(rootdir):
2328 return [], []
2328 return [], []
2329 if os.path.isdir(spec):
2329 if os.path.isdir(spec):
2330 spec += '/'
2330 spec += '/'
2331 spec = spec[len(rootdir):]
2331 spec = spec[len(rootdir):]
2332 fixpaths = os.sep != '/'
2332 fixpaths = os.sep != '/'
2333 if fixpaths:
2333 if fixpaths:
2334 spec = spec.replace(os.sep, '/')
2334 spec = spec.replace(os.sep, '/')
2335 speclen = len(spec)
2335 speclen = len(spec)
2336 fullpaths = opts['full']
2336 fullpaths = opts['full']
2337 files, dirs = set(), set()
2337 files, dirs = set(), set()
2338 adddir, addfile = dirs.add, files.add
2338 adddir, addfile = dirs.add, files.add
2339 for f, st in dirstate.iteritems():
2339 for f, st in dirstate.iteritems():
2340 if f.startswith(spec) and st[0] in acceptable:
2340 if f.startswith(spec) and st[0] in acceptable:
2341 if fixpaths:
2341 if fixpaths:
2342 f = f.replace('/', os.sep)
2342 f = f.replace('/', os.sep)
2343 if fullpaths:
2343 if fullpaths:
2344 addfile(f)
2344 addfile(f)
2345 continue
2345 continue
2346 s = f.find(os.sep, speclen)
2346 s = f.find(os.sep, speclen)
2347 if s >= 0:
2347 if s >= 0:
2348 adddir(f[:s])
2348 adddir(f[:s])
2349 else:
2349 else:
2350 addfile(f)
2350 addfile(f)
2351 return files, dirs
2351 return files, dirs
2352
2352
2353 acceptable = ''
2353 acceptable = ''
2354 if opts['normal']:
2354 if opts['normal']:
2355 acceptable += 'nm'
2355 acceptable += 'nm'
2356 if opts['added']:
2356 if opts['added']:
2357 acceptable += 'a'
2357 acceptable += 'a'
2358 if opts['removed']:
2358 if opts['removed']:
2359 acceptable += 'r'
2359 acceptable += 'r'
2360 cwd = repo.getcwd()
2360 cwd = repo.getcwd()
2361 if not specs:
2361 if not specs:
2362 specs = ['.']
2362 specs = ['.']
2363
2363
2364 files, dirs = set(), set()
2364 files, dirs = set(), set()
2365 for spec in specs:
2365 for spec in specs:
2366 f, d = complete(spec, acceptable or 'nmar')
2366 f, d = complete(spec, acceptable or 'nmar')
2367 files.update(f)
2367 files.update(f)
2368 dirs.update(d)
2368 dirs.update(d)
2369 files.update(dirs)
2369 files.update(dirs)
2370 ui.write('\n'.join(repo.pathto(p, cwd) for p in sorted(files)))
2370 ui.write('\n'.join(repo.pathto(p, cwd) for p in sorted(files)))
2371 ui.write('\n')
2371 ui.write('\n')
2372
2372
2373 @command('debugpushkey', [], _('REPO NAMESPACE [KEY OLD NEW]'))
2373 @command('debugpushkey', [], _('REPO NAMESPACE [KEY OLD NEW]'))
2374 def debugpushkey(ui, repopath, namespace, *keyinfo, **opts):
2374 def debugpushkey(ui, repopath, namespace, *keyinfo, **opts):
2375 '''access the pushkey key/value protocol
2375 '''access the pushkey key/value protocol
2376
2376
2377 With two args, list the keys in the given namespace.
2377 With two args, list the keys in the given namespace.
2378
2378
2379 With five args, set a key to new if it currently is set to old.
2379 With five args, set a key to new if it currently is set to old.
2380 Reports success or failure.
2380 Reports success or failure.
2381 '''
2381 '''
2382
2382
2383 target = hg.peer(ui, {}, repopath)
2383 target = hg.peer(ui, {}, repopath)
2384 if keyinfo:
2384 if keyinfo:
2385 key, old, new = keyinfo
2385 key, old, new = keyinfo
2386 r = target.pushkey(namespace, key, old, new)
2386 r = target.pushkey(namespace, key, old, new)
2387 ui.status(str(r) + '\n')
2387 ui.status(str(r) + '\n')
2388 return not r
2388 return not r
2389 else:
2389 else:
2390 for k, v in sorted(target.listkeys(namespace).iteritems()):
2390 for k, v in sorted(target.listkeys(namespace).iteritems()):
2391 ui.write("%s\t%s\n" % (k.encode('string-escape'),
2391 ui.write("%s\t%s\n" % (k.encode('string-escape'),
2392 v.encode('string-escape')))
2392 v.encode('string-escape')))
2393
2393
2394 @command('debugpvec', [], _('A B'))
2394 @command('debugpvec', [], _('A B'))
2395 def debugpvec(ui, repo, a, b=None):
2395 def debugpvec(ui, repo, a, b=None):
2396 ca = scmutil.revsingle(repo, a)
2396 ca = scmutil.revsingle(repo, a)
2397 cb = scmutil.revsingle(repo, b)
2397 cb = scmutil.revsingle(repo, b)
2398 pa = pvec.ctxpvec(ca)
2398 pa = pvec.ctxpvec(ca)
2399 pb = pvec.ctxpvec(cb)
2399 pb = pvec.ctxpvec(cb)
2400 if pa == pb:
2400 if pa == pb:
2401 rel = "="
2401 rel = "="
2402 elif pa > pb:
2402 elif pa > pb:
2403 rel = ">"
2403 rel = ">"
2404 elif pa < pb:
2404 elif pa < pb:
2405 rel = "<"
2405 rel = "<"
2406 elif pa | pb:
2406 elif pa | pb:
2407 rel = "|"
2407 rel = "|"
2408 ui.write(_("a: %s\n") % pa)
2408 ui.write(_("a: %s\n") % pa)
2409 ui.write(_("b: %s\n") % pb)
2409 ui.write(_("b: %s\n") % pb)
2410 ui.write(_("depth(a): %d depth(b): %d\n") % (pa._depth, pb._depth))
2410 ui.write(_("depth(a): %d depth(b): %d\n") % (pa._depth, pb._depth))
2411 ui.write(_("delta: %d hdist: %d distance: %d relation: %s\n") %
2411 ui.write(_("delta: %d hdist: %d distance: %d relation: %s\n") %
2412 (abs(pa._depth - pb._depth), pvec._hamming(pa._vec, pb._vec),
2412 (abs(pa._depth - pb._depth), pvec._hamming(pa._vec, pb._vec),
2413 pa.distance(pb), rel))
2413 pa.distance(pb), rel))
2414
2414
2415 @command('debugrebuilddirstate|debugrebuildstate',
2415 @command('debugrebuilddirstate|debugrebuildstate',
2416 [('r', 'rev', '', _('revision to rebuild to'), _('REV'))],
2416 [('r', 'rev', '', _('revision to rebuild to'), _('REV'))],
2417 _('[-r REV]'))
2417 _('[-r REV]'))
2418 def debugrebuilddirstate(ui, repo, rev):
2418 def debugrebuilddirstate(ui, repo, rev):
2419 """rebuild the dirstate as it would look like for the given revision
2419 """rebuild the dirstate as it would look like for the given revision
2420
2420
2421 If no revision is specified the first current parent will be used.
2421 If no revision is specified the first current parent will be used.
2422
2422
2423 The dirstate will be set to the files of the given revision.
2423 The dirstate will be set to the files of the given revision.
2424 The actual working directory content or existing dirstate
2424 The actual working directory content or existing dirstate
2425 information such as adds or removes is not considered.
2425 information such as adds or removes is not considered.
2426
2426
2427 One use of this command is to make the next :hg:`status` invocation
2427 One use of this command is to make the next :hg:`status` invocation
2428 check the actual file content.
2428 check the actual file content.
2429 """
2429 """
2430 ctx = scmutil.revsingle(repo, rev)
2430 ctx = scmutil.revsingle(repo, rev)
2431 wlock = repo.wlock()
2431 wlock = repo.wlock()
2432 try:
2432 try:
2433 repo.dirstate.rebuild(ctx.node(), ctx.manifest())
2433 repo.dirstate.rebuild(ctx.node(), ctx.manifest())
2434 finally:
2434 finally:
2435 wlock.release()
2435 wlock.release()
2436
2436
2437 @command('debugrename',
2437 @command('debugrename',
2438 [('r', 'rev', '', _('revision to debug'), _('REV'))],
2438 [('r', 'rev', '', _('revision to debug'), _('REV'))],
2439 _('[-r REV] FILE'))
2439 _('[-r REV] FILE'))
2440 def debugrename(ui, repo, file1, *pats, **opts):
2440 def debugrename(ui, repo, file1, *pats, **opts):
2441 """dump rename information"""
2441 """dump rename information"""
2442
2442
2443 ctx = scmutil.revsingle(repo, opts.get('rev'))
2443 ctx = scmutil.revsingle(repo, opts.get('rev'))
2444 m = scmutil.match(ctx, (file1,) + pats, opts)
2444 m = scmutil.match(ctx, (file1,) + pats, opts)
2445 for abs in ctx.walk(m):
2445 for abs in ctx.walk(m):
2446 fctx = ctx[abs]
2446 fctx = ctx[abs]
2447 o = fctx.filelog().renamed(fctx.filenode())
2447 o = fctx.filelog().renamed(fctx.filenode())
2448 rel = m.rel(abs)
2448 rel = m.rel(abs)
2449 if o:
2449 if o:
2450 ui.write(_("%s renamed from %s:%s\n") % (rel, o[0], hex(o[1])))
2450 ui.write(_("%s renamed from %s:%s\n") % (rel, o[0], hex(o[1])))
2451 else:
2451 else:
2452 ui.write(_("%s not renamed\n") % rel)
2452 ui.write(_("%s not renamed\n") % rel)
2453
2453
2454 @command('debugrevlog',
2454 @command('debugrevlog',
2455 [('c', 'changelog', False, _('open changelog')),
2455 [('c', 'changelog', False, _('open changelog')),
2456 ('m', 'manifest', False, _('open manifest')),
2456 ('m', 'manifest', False, _('open manifest')),
2457 ('d', 'dump', False, _('dump index data'))],
2457 ('d', 'dump', False, _('dump index data'))],
2458 _('-c|-m|FILE'))
2458 _('-c|-m|FILE'))
2459 def debugrevlog(ui, repo, file_=None, **opts):
2459 def debugrevlog(ui, repo, file_=None, **opts):
2460 """show data and statistics about a revlog"""
2460 """show data and statistics about a revlog"""
2461 r = cmdutil.openrevlog(repo, 'debugrevlog', file_, opts)
2461 r = cmdutil.openrevlog(repo, 'debugrevlog', file_, opts)
2462
2462
2463 if opts.get("dump"):
2463 if opts.get("dump"):
2464 numrevs = len(r)
2464 numrevs = len(r)
2465 ui.write("# rev p1rev p2rev start end deltastart base p1 p2"
2465 ui.write("# rev p1rev p2rev start end deltastart base p1 p2"
2466 " rawsize totalsize compression heads\n")
2466 " rawsize totalsize compression heads\n")
2467 ts = 0
2467 ts = 0
2468 heads = set()
2468 heads = set()
2469 for rev in xrange(numrevs):
2469 for rev in xrange(numrevs):
2470 dbase = r.deltaparent(rev)
2470 dbase = r.deltaparent(rev)
2471 if dbase == -1:
2471 if dbase == -1:
2472 dbase = rev
2472 dbase = rev
2473 cbase = r.chainbase(rev)
2473 cbase = r.chainbase(rev)
2474 p1, p2 = r.parentrevs(rev)
2474 p1, p2 = r.parentrevs(rev)
2475 rs = r.rawsize(rev)
2475 rs = r.rawsize(rev)
2476 ts = ts + rs
2476 ts = ts + rs
2477 heads -= set(r.parentrevs(rev))
2477 heads -= set(r.parentrevs(rev))
2478 heads.add(rev)
2478 heads.add(rev)
2479 ui.write("%d %d %d %d %d %d %d %d %d %d %d %d %d\n" %
2479 ui.write("%d %d %d %d %d %d %d %d %d %d %d %d %d\n" %
2480 (rev, p1, p2, r.start(rev), r.end(rev),
2480 (rev, p1, p2, r.start(rev), r.end(rev),
2481 r.start(dbase), r.start(cbase),
2481 r.start(dbase), r.start(cbase),
2482 r.start(p1), r.start(p2),
2482 r.start(p1), r.start(p2),
2483 rs, ts, ts / r.end(rev), len(heads)))
2483 rs, ts, ts / r.end(rev), len(heads)))
2484 return 0
2484 return 0
2485
2485
2486 v = r.version
2486 v = r.version
2487 format = v & 0xFFFF
2487 format = v & 0xFFFF
2488 flags = []
2488 flags = []
2489 gdelta = False
2489 gdelta = False
2490 if v & revlog.REVLOGNGINLINEDATA:
2490 if v & revlog.REVLOGNGINLINEDATA:
2491 flags.append('inline')
2491 flags.append('inline')
2492 if v & revlog.REVLOGGENERALDELTA:
2492 if v & revlog.REVLOGGENERALDELTA:
2493 gdelta = True
2493 gdelta = True
2494 flags.append('generaldelta')
2494 flags.append('generaldelta')
2495 if not flags:
2495 if not flags:
2496 flags = ['(none)']
2496 flags = ['(none)']
2497
2497
2498 nummerges = 0
2498 nummerges = 0
2499 numfull = 0
2499 numfull = 0
2500 numprev = 0
2500 numprev = 0
2501 nump1 = 0
2501 nump1 = 0
2502 nump2 = 0
2502 nump2 = 0
2503 numother = 0
2503 numother = 0
2504 nump1prev = 0
2504 nump1prev = 0
2505 nump2prev = 0
2505 nump2prev = 0
2506 chainlengths = []
2506 chainlengths = []
2507
2507
2508 datasize = [None, 0, 0L]
2508 datasize = [None, 0, 0L]
2509 fullsize = [None, 0, 0L]
2509 fullsize = [None, 0, 0L]
2510 deltasize = [None, 0, 0L]
2510 deltasize = [None, 0, 0L]
2511
2511
2512 def addsize(size, l):
2512 def addsize(size, l):
2513 if l[0] is None or size < l[0]:
2513 if l[0] is None or size < l[0]:
2514 l[0] = size
2514 l[0] = size
2515 if size > l[1]:
2515 if size > l[1]:
2516 l[1] = size
2516 l[1] = size
2517 l[2] += size
2517 l[2] += size
2518
2518
2519 numrevs = len(r)
2519 numrevs = len(r)
2520 for rev in xrange(numrevs):
2520 for rev in xrange(numrevs):
2521 p1, p2 = r.parentrevs(rev)
2521 p1, p2 = r.parentrevs(rev)
2522 delta = r.deltaparent(rev)
2522 delta = r.deltaparent(rev)
2523 if format > 0:
2523 if format > 0:
2524 addsize(r.rawsize(rev), datasize)
2524 addsize(r.rawsize(rev), datasize)
2525 if p2 != nullrev:
2525 if p2 != nullrev:
2526 nummerges += 1
2526 nummerges += 1
2527 size = r.length(rev)
2527 size = r.length(rev)
2528 if delta == nullrev:
2528 if delta == nullrev:
2529 chainlengths.append(0)
2529 chainlengths.append(0)
2530 numfull += 1
2530 numfull += 1
2531 addsize(size, fullsize)
2531 addsize(size, fullsize)
2532 else:
2532 else:
2533 chainlengths.append(chainlengths[delta] + 1)
2533 chainlengths.append(chainlengths[delta] + 1)
2534 addsize(size, deltasize)
2534 addsize(size, deltasize)
2535 if delta == rev - 1:
2535 if delta == rev - 1:
2536 numprev += 1
2536 numprev += 1
2537 if delta == p1:
2537 if delta == p1:
2538 nump1prev += 1
2538 nump1prev += 1
2539 elif delta == p2:
2539 elif delta == p2:
2540 nump2prev += 1
2540 nump2prev += 1
2541 elif delta == p1:
2541 elif delta == p1:
2542 nump1 += 1
2542 nump1 += 1
2543 elif delta == p2:
2543 elif delta == p2:
2544 nump2 += 1
2544 nump2 += 1
2545 elif delta != nullrev:
2545 elif delta != nullrev:
2546 numother += 1
2546 numother += 1
2547
2547
2548 # Adjust size min value for empty cases
2548 # Adjust size min value for empty cases
2549 for size in (datasize, fullsize, deltasize):
2549 for size in (datasize, fullsize, deltasize):
2550 if size[0] is None:
2550 if size[0] is None:
2551 size[0] = 0
2551 size[0] = 0
2552
2552
2553 numdeltas = numrevs - numfull
2553 numdeltas = numrevs - numfull
2554 numoprev = numprev - nump1prev - nump2prev
2554 numoprev = numprev - nump1prev - nump2prev
2555 totalrawsize = datasize[2]
2555 totalrawsize = datasize[2]
2556 datasize[2] /= numrevs
2556 datasize[2] /= numrevs
2557 fulltotal = fullsize[2]
2557 fulltotal = fullsize[2]
2558 fullsize[2] /= numfull
2558 fullsize[2] /= numfull
2559 deltatotal = deltasize[2]
2559 deltatotal = deltasize[2]
2560 if numrevs - numfull > 0:
2560 if numrevs - numfull > 0:
2561 deltasize[2] /= numrevs - numfull
2561 deltasize[2] /= numrevs - numfull
2562 totalsize = fulltotal + deltatotal
2562 totalsize = fulltotal + deltatotal
2563 avgchainlen = sum(chainlengths) / numrevs
2563 avgchainlen = sum(chainlengths) / numrevs
2564 compratio = totalrawsize / totalsize
2564 compratio = totalrawsize / totalsize
2565
2565
2566 basedfmtstr = '%%%dd\n'
2566 basedfmtstr = '%%%dd\n'
2567 basepcfmtstr = '%%%dd %s(%%5.2f%%%%)\n'
2567 basepcfmtstr = '%%%dd %s(%%5.2f%%%%)\n'
2568
2568
2569 def dfmtstr(max):
2569 def dfmtstr(max):
2570 return basedfmtstr % len(str(max))
2570 return basedfmtstr % len(str(max))
2571 def pcfmtstr(max, padding=0):
2571 def pcfmtstr(max, padding=0):
2572 return basepcfmtstr % (len(str(max)), ' ' * padding)
2572 return basepcfmtstr % (len(str(max)), ' ' * padding)
2573
2573
2574 def pcfmt(value, total):
2574 def pcfmt(value, total):
2575 return (value, 100 * float(value) / total)
2575 return (value, 100 * float(value) / total)
2576
2576
2577 ui.write(('format : %d\n') % format)
2577 ui.write(('format : %d\n') % format)
2578 ui.write(('flags : %s\n') % ', '.join(flags))
2578 ui.write(('flags : %s\n') % ', '.join(flags))
2579
2579
2580 ui.write('\n')
2580 ui.write('\n')
2581 fmt = pcfmtstr(totalsize)
2581 fmt = pcfmtstr(totalsize)
2582 fmt2 = dfmtstr(totalsize)
2582 fmt2 = dfmtstr(totalsize)
2583 ui.write(('revisions : ') + fmt2 % numrevs)
2583 ui.write(('revisions : ') + fmt2 % numrevs)
2584 ui.write((' merges : ') + fmt % pcfmt(nummerges, numrevs))
2584 ui.write((' merges : ') + fmt % pcfmt(nummerges, numrevs))
2585 ui.write((' normal : ') + fmt % pcfmt(numrevs - nummerges, numrevs))
2585 ui.write((' normal : ') + fmt % pcfmt(numrevs - nummerges, numrevs))
2586 ui.write(('revisions : ') + fmt2 % numrevs)
2586 ui.write(('revisions : ') + fmt2 % numrevs)
2587 ui.write((' full : ') + fmt % pcfmt(numfull, numrevs))
2587 ui.write((' full : ') + fmt % pcfmt(numfull, numrevs))
2588 ui.write((' deltas : ') + fmt % pcfmt(numdeltas, numrevs))
2588 ui.write((' deltas : ') + fmt % pcfmt(numdeltas, numrevs))
2589 ui.write(('revision size : ') + fmt2 % totalsize)
2589 ui.write(('revision size : ') + fmt2 % totalsize)
2590 ui.write((' full : ') + fmt % pcfmt(fulltotal, totalsize))
2590 ui.write((' full : ') + fmt % pcfmt(fulltotal, totalsize))
2591 ui.write((' deltas : ') + fmt % pcfmt(deltatotal, totalsize))
2591 ui.write((' deltas : ') + fmt % pcfmt(deltatotal, totalsize))
2592
2592
2593 ui.write('\n')
2593 ui.write('\n')
2594 fmt = dfmtstr(max(avgchainlen, compratio))
2594 fmt = dfmtstr(max(avgchainlen, compratio))
2595 ui.write(('avg chain length : ') + fmt % avgchainlen)
2595 ui.write(('avg chain length : ') + fmt % avgchainlen)
2596 ui.write(('compression ratio : ') + fmt % compratio)
2596 ui.write(('compression ratio : ') + fmt % compratio)
2597
2597
2598 if format > 0:
2598 if format > 0:
2599 ui.write('\n')
2599 ui.write('\n')
2600 ui.write(('uncompressed data size (min/max/avg) : %d / %d / %d\n')
2600 ui.write(('uncompressed data size (min/max/avg) : %d / %d / %d\n')
2601 % tuple(datasize))
2601 % tuple(datasize))
2602 ui.write(('full revision size (min/max/avg) : %d / %d / %d\n')
2602 ui.write(('full revision size (min/max/avg) : %d / %d / %d\n')
2603 % tuple(fullsize))
2603 % tuple(fullsize))
2604 ui.write(('delta size (min/max/avg) : %d / %d / %d\n')
2604 ui.write(('delta size (min/max/avg) : %d / %d / %d\n')
2605 % tuple(deltasize))
2605 % tuple(deltasize))
2606
2606
2607 if numdeltas > 0:
2607 if numdeltas > 0:
2608 ui.write('\n')
2608 ui.write('\n')
2609 fmt = pcfmtstr(numdeltas)
2609 fmt = pcfmtstr(numdeltas)
2610 fmt2 = pcfmtstr(numdeltas, 4)
2610 fmt2 = pcfmtstr(numdeltas, 4)
2611 ui.write(('deltas against prev : ') + fmt % pcfmt(numprev, numdeltas))
2611 ui.write(('deltas against prev : ') + fmt % pcfmt(numprev, numdeltas))
2612 if numprev > 0:
2612 if numprev > 0:
2613 ui.write((' where prev = p1 : ') + fmt2 % pcfmt(nump1prev,
2613 ui.write((' where prev = p1 : ') + fmt2 % pcfmt(nump1prev,
2614 numprev))
2614 numprev))
2615 ui.write((' where prev = p2 : ') + fmt2 % pcfmt(nump2prev,
2615 ui.write((' where prev = p2 : ') + fmt2 % pcfmt(nump2prev,
2616 numprev))
2616 numprev))
2617 ui.write((' other : ') + fmt2 % pcfmt(numoprev,
2617 ui.write((' other : ') + fmt2 % pcfmt(numoprev,
2618 numprev))
2618 numprev))
2619 if gdelta:
2619 if gdelta:
2620 ui.write(('deltas against p1 : ')
2620 ui.write(('deltas against p1 : ')
2621 + fmt % pcfmt(nump1, numdeltas))
2621 + fmt % pcfmt(nump1, numdeltas))
2622 ui.write(('deltas against p2 : ')
2622 ui.write(('deltas against p2 : ')
2623 + fmt % pcfmt(nump2, numdeltas))
2623 + fmt % pcfmt(nump2, numdeltas))
2624 ui.write(('deltas against other : ') + fmt % pcfmt(numother,
2624 ui.write(('deltas against other : ') + fmt % pcfmt(numother,
2625 numdeltas))
2625 numdeltas))
2626
2626
2627 @command('debugrevspec',
2627 @command('debugrevspec',
2628 [('', 'optimize', None, _('print parsed tree after optimizing'))],
2628 [('', 'optimize', None, _('print parsed tree after optimizing'))],
2629 ('REVSPEC'))
2629 ('REVSPEC'))
2630 def debugrevspec(ui, repo, expr, **opts):
2630 def debugrevspec(ui, repo, expr, **opts):
2631 """parse and apply a revision specification
2631 """parse and apply a revision specification
2632
2632
2633 Use --verbose to print the parsed tree before and after aliases
2633 Use --verbose to print the parsed tree before and after aliases
2634 expansion.
2634 expansion.
2635 """
2635 """
2636 if ui.verbose:
2636 if ui.verbose:
2637 tree = revset.parse(expr)[0]
2637 tree = revset.parse(expr)[0]
2638 ui.note(revset.prettyformat(tree), "\n")
2638 ui.note(revset.prettyformat(tree), "\n")
2639 newtree = revset.findaliases(ui, tree)
2639 newtree = revset.findaliases(ui, tree)
2640 if newtree != tree:
2640 if newtree != tree:
2641 ui.note(revset.prettyformat(newtree), "\n")
2641 ui.note(revset.prettyformat(newtree), "\n")
2642 if opts["optimize"]:
2642 if opts["optimize"]:
2643 weight, optimizedtree = revset.optimize(newtree, True)
2643 weight, optimizedtree = revset.optimize(newtree, True)
2644 ui.note("* optimized:\n", revset.prettyformat(optimizedtree), "\n")
2644 ui.note("* optimized:\n", revset.prettyformat(optimizedtree), "\n")
2645 func = revset.match(ui, expr)
2645 func = revset.match(ui, expr)
2646 for c in func(repo, revset.spanset(repo)):
2646 for c in func(repo, revset.spanset(repo)):
2647 ui.write("%s\n" % c)
2647 ui.write("%s\n" % c)
2648
2648
2649 @command('debugsetparents', [], _('REV1 [REV2]'))
2649 @command('debugsetparents', [], _('REV1 [REV2]'))
2650 def debugsetparents(ui, repo, rev1, rev2=None):
2650 def debugsetparents(ui, repo, rev1, rev2=None):
2651 """manually set the parents of the current working directory
2651 """manually set the parents of the current working directory
2652
2652
2653 This is useful for writing repository conversion tools, but should
2653 This is useful for writing repository conversion tools, but should
2654 be used with care.
2654 be used with care.
2655
2655
2656 Returns 0 on success.
2656 Returns 0 on success.
2657 """
2657 """
2658
2658
2659 r1 = scmutil.revsingle(repo, rev1).node()
2659 r1 = scmutil.revsingle(repo, rev1).node()
2660 r2 = scmutil.revsingle(repo, rev2, 'null').node()
2660 r2 = scmutil.revsingle(repo, rev2, 'null').node()
2661
2661
2662 wlock = repo.wlock()
2662 wlock = repo.wlock()
2663 try:
2663 try:
2664 repo.setparents(r1, r2)
2664 repo.setparents(r1, r2)
2665 finally:
2665 finally:
2666 wlock.release()
2666 wlock.release()
2667
2667
2668 @command('debugdirstate|debugstate',
2668 @command('debugdirstate|debugstate',
2669 [('', 'nodates', None, _('do not display the saved mtime')),
2669 [('', 'nodates', None, _('do not display the saved mtime')),
2670 ('', 'datesort', None, _('sort by saved mtime'))],
2670 ('', 'datesort', None, _('sort by saved mtime'))],
2671 _('[OPTION]...'))
2671 _('[OPTION]...'))
2672 def debugstate(ui, repo, nodates=None, datesort=None):
2672 def debugstate(ui, repo, nodates=None, datesort=None):
2673 """show the contents of the current dirstate"""
2673 """show the contents of the current dirstate"""
2674 timestr = ""
2674 timestr = ""
2675 showdate = not nodates
2675 showdate = not nodates
2676 if datesort:
2676 if datesort:
2677 keyfunc = lambda x: (x[1][3], x[0]) # sort by mtime, then by filename
2677 keyfunc = lambda x: (x[1][3], x[0]) # sort by mtime, then by filename
2678 else:
2678 else:
2679 keyfunc = None # sort by filename
2679 keyfunc = None # sort by filename
2680 for file_, ent in sorted(repo.dirstate._map.iteritems(), key=keyfunc):
2680 for file_, ent in sorted(repo.dirstate._map.iteritems(), key=keyfunc):
2681 if showdate:
2681 if showdate:
2682 if ent[3] == -1:
2682 if ent[3] == -1:
2683 # Pad or slice to locale representation
2683 # Pad or slice to locale representation
2684 locale_len = len(time.strftime("%Y-%m-%d %H:%M:%S ",
2684 locale_len = len(time.strftime("%Y-%m-%d %H:%M:%S ",
2685 time.localtime(0)))
2685 time.localtime(0)))
2686 timestr = 'unset'
2686 timestr = 'unset'
2687 timestr = (timestr[:locale_len] +
2687 timestr = (timestr[:locale_len] +
2688 ' ' * (locale_len - len(timestr)))
2688 ' ' * (locale_len - len(timestr)))
2689 else:
2689 else:
2690 timestr = time.strftime("%Y-%m-%d %H:%M:%S ",
2690 timestr = time.strftime("%Y-%m-%d %H:%M:%S ",
2691 time.localtime(ent[3]))
2691 time.localtime(ent[3]))
2692 if ent[1] & 020000:
2692 if ent[1] & 020000:
2693 mode = 'lnk'
2693 mode = 'lnk'
2694 else:
2694 else:
2695 mode = '%3o' % (ent[1] & 0777 & ~util.umask)
2695 mode = '%3o' % (ent[1] & 0777 & ~util.umask)
2696 ui.write("%c %s %10d %s%s\n" % (ent[0], mode, ent[2], timestr, file_))
2696 ui.write("%c %s %10d %s%s\n" % (ent[0], mode, ent[2], timestr, file_))
2697 for f in repo.dirstate.copies():
2697 for f in repo.dirstate.copies():
2698 ui.write(_("copy: %s -> %s\n") % (repo.dirstate.copied(f), f))
2698 ui.write(_("copy: %s -> %s\n") % (repo.dirstate.copied(f), f))
2699
2699
2700 @command('debugsub',
2700 @command('debugsub',
2701 [('r', 'rev', '',
2701 [('r', 'rev', '',
2702 _('revision to check'), _('REV'))],
2702 _('revision to check'), _('REV'))],
2703 _('[-r REV] [REV]'))
2703 _('[-r REV] [REV]'))
2704 def debugsub(ui, repo, rev=None):
2704 def debugsub(ui, repo, rev=None):
2705 ctx = scmutil.revsingle(repo, rev, None)
2705 ctx = scmutil.revsingle(repo, rev, None)
2706 for k, v in sorted(ctx.substate.items()):
2706 for k, v in sorted(ctx.substate.items()):
2707 ui.write(('path %s\n') % k)
2707 ui.write(('path %s\n') % k)
2708 ui.write((' source %s\n') % v[0])
2708 ui.write((' source %s\n') % v[0])
2709 ui.write((' revision %s\n') % v[1])
2709 ui.write((' revision %s\n') % v[1])
2710
2710
2711 @command('debugsuccessorssets',
2711 @command('debugsuccessorssets',
2712 [],
2712 [],
2713 _('[REV]'))
2713 _('[REV]'))
2714 def debugsuccessorssets(ui, repo, *revs):
2714 def debugsuccessorssets(ui, repo, *revs):
2715 """show set of successors for revision
2715 """show set of successors for revision
2716
2716
2717 A successors set of changeset A is a consistent group of revisions that
2717 A successors set of changeset A is a consistent group of revisions that
2718 succeed A. It contains non-obsolete changesets only.
2718 succeed A. It contains non-obsolete changesets only.
2719
2719
2720 In most cases a changeset A has a single successors set containing a single
2720 In most cases a changeset A has a single successors set containing a single
2721 successor (changeset A replaced by A').
2721 successor (changeset A replaced by A').
2722
2722
2723 A changeset that is made obsolete with no successors are called "pruned".
2723 A changeset that is made obsolete with no successors are called "pruned".
2724 Such changesets have no successors sets at all.
2724 Such changesets have no successors sets at all.
2725
2725
2726 A changeset that has been "split" will have a successors set containing
2726 A changeset that has been "split" will have a successors set containing
2727 more than one successor.
2727 more than one successor.
2728
2728
2729 A changeset that has been rewritten in multiple different ways is called
2729 A changeset that has been rewritten in multiple different ways is called
2730 "divergent". Such changesets have multiple successor sets (each of which
2730 "divergent". Such changesets have multiple successor sets (each of which
2731 may also be split, i.e. have multiple successors).
2731 may also be split, i.e. have multiple successors).
2732
2732
2733 Results are displayed as follows::
2733 Results are displayed as follows::
2734
2734
2735 <rev1>
2735 <rev1>
2736 <successors-1A>
2736 <successors-1A>
2737 <rev2>
2737 <rev2>
2738 <successors-2A>
2738 <successors-2A>
2739 <successors-2B1> <successors-2B2> <successors-2B3>
2739 <successors-2B1> <successors-2B2> <successors-2B3>
2740
2740
2741 Here rev2 has two possible (i.e. divergent) successors sets. The first
2741 Here rev2 has two possible (i.e. divergent) successors sets. The first
2742 holds one element, whereas the second holds three (i.e. the changeset has
2742 holds one element, whereas the second holds three (i.e. the changeset has
2743 been split).
2743 been split).
2744 """
2744 """
2745 # passed to successorssets caching computation from one call to another
2745 # passed to successorssets caching computation from one call to another
2746 cache = {}
2746 cache = {}
2747 ctx2str = str
2747 ctx2str = str
2748 node2str = short
2748 node2str = short
2749 if ui.debug():
2749 if ui.debug():
2750 def ctx2str(ctx):
2750 def ctx2str(ctx):
2751 return ctx.hex()
2751 return ctx.hex()
2752 node2str = hex
2752 node2str = hex
2753 for rev in scmutil.revrange(repo, revs):
2753 for rev in scmutil.revrange(repo, revs):
2754 ctx = repo[rev]
2754 ctx = repo[rev]
2755 ui.write('%s\n'% ctx2str(ctx))
2755 ui.write('%s\n'% ctx2str(ctx))
2756 for succsset in obsolete.successorssets(repo, ctx.node(), cache):
2756 for succsset in obsolete.successorssets(repo, ctx.node(), cache):
2757 if succsset:
2757 if succsset:
2758 ui.write(' ')
2758 ui.write(' ')
2759 ui.write(node2str(succsset[0]))
2759 ui.write(node2str(succsset[0]))
2760 for node in succsset[1:]:
2760 for node in succsset[1:]:
2761 ui.write(' ')
2761 ui.write(' ')
2762 ui.write(node2str(node))
2762 ui.write(node2str(node))
2763 ui.write('\n')
2763 ui.write('\n')
2764
2764
2765 @command('debugwalk', walkopts, _('[OPTION]... [FILE]...'))
2765 @command('debugwalk', walkopts, _('[OPTION]... [FILE]...'))
2766 def debugwalk(ui, repo, *pats, **opts):
2766 def debugwalk(ui, repo, *pats, **opts):
2767 """show how files match on given patterns"""
2767 """show how files match on given patterns"""
2768 m = scmutil.match(repo[None], pats, opts)
2768 m = scmutil.match(repo[None], pats, opts)
2769 items = list(repo.walk(m))
2769 items = list(repo.walk(m))
2770 if not items:
2770 if not items:
2771 return
2771 return
2772 f = lambda fn: fn
2772 f = lambda fn: fn
2773 if ui.configbool('ui', 'slash') and os.sep != '/':
2773 if ui.configbool('ui', 'slash') and os.sep != '/':
2774 f = lambda fn: util.normpath(fn)
2774 f = lambda fn: util.normpath(fn)
2775 fmt = 'f %%-%ds %%-%ds %%s' % (
2775 fmt = 'f %%-%ds %%-%ds %%s' % (
2776 max([len(abs) for abs in items]),
2776 max([len(abs) for abs in items]),
2777 max([len(m.rel(abs)) for abs in items]))
2777 max([len(m.rel(abs)) for abs in items]))
2778 for abs in items:
2778 for abs in items:
2779 line = fmt % (abs, f(m.rel(abs)), m.exact(abs) and 'exact' or '')
2779 line = fmt % (abs, f(m.rel(abs)), m.exact(abs) and 'exact' or '')
2780 ui.write("%s\n" % line.rstrip())
2780 ui.write("%s\n" % line.rstrip())
2781
2781
2782 @command('debugwireargs',
2782 @command('debugwireargs',
2783 [('', 'three', '', 'three'),
2783 [('', 'three', '', 'three'),
2784 ('', 'four', '', 'four'),
2784 ('', 'four', '', 'four'),
2785 ('', 'five', '', 'five'),
2785 ('', 'five', '', 'five'),
2786 ] + remoteopts,
2786 ] + remoteopts,
2787 _('REPO [OPTIONS]... [ONE [TWO]]'))
2787 _('REPO [OPTIONS]... [ONE [TWO]]'))
2788 def debugwireargs(ui, repopath, *vals, **opts):
2788 def debugwireargs(ui, repopath, *vals, **opts):
2789 repo = hg.peer(ui, opts, repopath)
2789 repo = hg.peer(ui, opts, repopath)
2790 for opt in remoteopts:
2790 for opt in remoteopts:
2791 del opts[opt[1]]
2791 del opts[opt[1]]
2792 args = {}
2792 args = {}
2793 for k, v in opts.iteritems():
2793 for k, v in opts.iteritems():
2794 if v:
2794 if v:
2795 args[k] = v
2795 args[k] = v
2796 # run twice to check that we don't mess up the stream for the next command
2796 # run twice to check that we don't mess up the stream for the next command
2797 res1 = repo.debugwireargs(*vals, **args)
2797 res1 = repo.debugwireargs(*vals, **args)
2798 res2 = repo.debugwireargs(*vals, **args)
2798 res2 = repo.debugwireargs(*vals, **args)
2799 ui.write("%s\n" % res1)
2799 ui.write("%s\n" % res1)
2800 if res1 != res2:
2800 if res1 != res2:
2801 ui.warn("%s\n" % res2)
2801 ui.warn("%s\n" % res2)
2802
2802
2803 @command('^diff',
2803 @command('^diff',
2804 [('r', 'rev', [], _('revision'), _('REV')),
2804 [('r', 'rev', [], _('revision'), _('REV')),
2805 ('c', 'change', '', _('change made by revision'), _('REV'))
2805 ('c', 'change', '', _('change made by revision'), _('REV'))
2806 ] + diffopts + diffopts2 + walkopts + subrepoopts,
2806 ] + diffopts + diffopts2 + walkopts + subrepoopts,
2807 _('[OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...'))
2807 _('[OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...'))
2808 def diff(ui, repo, *pats, **opts):
2808 def diff(ui, repo, *pats, **opts):
2809 """diff repository (or selected files)
2809 """diff repository (or selected files)
2810
2810
2811 Show differences between revisions for the specified files.
2811 Show differences between revisions for the specified files.
2812
2812
2813 Differences between files are shown using the unified diff format.
2813 Differences between files are shown using the unified diff format.
2814
2814
2815 .. note::
2815 .. note::
2816
2816
2817 diff may generate unexpected results for merges, as it will
2817 diff may generate unexpected results for merges, as it will
2818 default to comparing against the working directory's first
2818 default to comparing against the working directory's first
2819 parent changeset if no revisions are specified.
2819 parent changeset if no revisions are specified.
2820
2820
2821 When two revision arguments are given, then changes are shown
2821 When two revision arguments are given, then changes are shown
2822 between those revisions. If only one revision is specified then
2822 between those revisions. If only one revision is specified then
2823 that revision is compared to the working directory, and, when no
2823 that revision is compared to the working directory, and, when no
2824 revisions are specified, the working directory files are compared
2824 revisions are specified, the working directory files are compared
2825 to its parent.
2825 to its parent.
2826
2826
2827 Alternatively you can specify -c/--change with a revision to see
2827 Alternatively you can specify -c/--change with a revision to see
2828 the changes in that changeset relative to its first parent.
2828 the changes in that changeset relative to its first parent.
2829
2829
2830 Without the -a/--text option, diff will avoid generating diffs of
2830 Without the -a/--text option, diff will avoid generating diffs of
2831 files it detects as binary. With -a, diff will generate a diff
2831 files it detects as binary. With -a, diff will generate a diff
2832 anyway, probably with undesirable results.
2832 anyway, probably with undesirable results.
2833
2833
2834 Use the -g/--git option to generate diffs in the git extended diff
2834 Use the -g/--git option to generate diffs in the git extended diff
2835 format. For more information, read :hg:`help diffs`.
2835 format. For more information, read :hg:`help diffs`.
2836
2836
2837 .. container:: verbose
2837 .. container:: verbose
2838
2838
2839 Examples:
2839 Examples:
2840
2840
2841 - compare a file in the current working directory to its parent::
2841 - compare a file in the current working directory to its parent::
2842
2842
2843 hg diff foo.c
2843 hg diff foo.c
2844
2844
2845 - compare two historical versions of a directory, with rename info::
2845 - compare two historical versions of a directory, with rename info::
2846
2846
2847 hg diff --git -r 1.0:1.2 lib/
2847 hg diff --git -r 1.0:1.2 lib/
2848
2848
2849 - get change stats relative to the last change on some date::
2849 - get change stats relative to the last change on some date::
2850
2850
2851 hg diff --stat -r "date('may 2')"
2851 hg diff --stat -r "date('may 2')"
2852
2852
2853 - diff all newly-added files that contain a keyword::
2853 - diff all newly-added files that contain a keyword::
2854
2854
2855 hg diff "set:added() and grep(GNU)"
2855 hg diff "set:added() and grep(GNU)"
2856
2856
2857 - compare a revision and its parents::
2857 - compare a revision and its parents::
2858
2858
2859 hg diff -c 9353 # compare against first parent
2859 hg diff -c 9353 # compare against first parent
2860 hg diff -r 9353^:9353 # same using revset syntax
2860 hg diff -r 9353^:9353 # same using revset syntax
2861 hg diff -r 9353^2:9353 # compare against the second parent
2861 hg diff -r 9353^2:9353 # compare against the second parent
2862
2862
2863 Returns 0 on success.
2863 Returns 0 on success.
2864 """
2864 """
2865
2865
2866 revs = opts.get('rev')
2866 revs = opts.get('rev')
2867 change = opts.get('change')
2867 change = opts.get('change')
2868 stat = opts.get('stat')
2868 stat = opts.get('stat')
2869 reverse = opts.get('reverse')
2869 reverse = opts.get('reverse')
2870
2870
2871 if revs and change:
2871 if revs and change:
2872 msg = _('cannot specify --rev and --change at the same time')
2872 msg = _('cannot specify --rev and --change at the same time')
2873 raise util.Abort(msg)
2873 raise util.Abort(msg)
2874 elif change:
2874 elif change:
2875 node2 = scmutil.revsingle(repo, change, None).node()
2875 node2 = scmutil.revsingle(repo, change, None).node()
2876 node1 = repo[node2].p1().node()
2876 node1 = repo[node2].p1().node()
2877 else:
2877 else:
2878 node1, node2 = scmutil.revpair(repo, revs)
2878 node1, node2 = scmutil.revpair(repo, revs)
2879
2879
2880 if reverse:
2880 if reverse:
2881 node1, node2 = node2, node1
2881 node1, node2 = node2, node1
2882
2882
2883 diffopts = patch.diffopts(ui, opts)
2883 diffopts = patch.diffopts(ui, opts)
2884 m = scmutil.match(repo[node2], pats, opts)
2884 m = scmutil.match(repo[node2], pats, opts)
2885 cmdutil.diffordiffstat(ui, repo, diffopts, node1, node2, m, stat=stat,
2885 cmdutil.diffordiffstat(ui, repo, diffopts, node1, node2, m, stat=stat,
2886 listsubrepos=opts.get('subrepos'))
2886 listsubrepos=opts.get('subrepos'))
2887
2887
2888 @command('^export',
2888 @command('^export',
2889 [('o', 'output', '',
2889 [('o', 'output', '',
2890 _('print output to file with formatted name'), _('FORMAT')),
2890 _('print output to file with formatted name'), _('FORMAT')),
2891 ('', 'switch-parent', None, _('diff against the second parent')),
2891 ('', 'switch-parent', None, _('diff against the second parent')),
2892 ('r', 'rev', [], _('revisions to export'), _('REV')),
2892 ('r', 'rev', [], _('revisions to export'), _('REV')),
2893 ] + diffopts,
2893 ] + diffopts,
2894 _('[OPTION]... [-o OUTFILESPEC] [-r] [REV]...'))
2894 _('[OPTION]... [-o OUTFILESPEC] [-r] [REV]...'))
2895 def export(ui, repo, *changesets, **opts):
2895 def export(ui, repo, *changesets, **opts):
2896 """dump the header and diffs for one or more changesets
2896 """dump the header and diffs for one or more changesets
2897
2897
2898 Print the changeset header and diffs for one or more revisions.
2898 Print the changeset header and diffs for one or more revisions.
2899 If no revision is given, the parent of the working directory is used.
2899 If no revision is given, the parent of the working directory is used.
2900
2900
2901 The information shown in the changeset header is: author, date,
2901 The information shown in the changeset header is: author, date,
2902 branch name (if non-default), changeset hash, parent(s) and commit
2902 branch name (if non-default), changeset hash, parent(s) and commit
2903 comment.
2903 comment.
2904
2904
2905 .. note::
2905 .. note::
2906
2906
2907 export may generate unexpected diff output for merge
2907 export may generate unexpected diff output for merge
2908 changesets, as it will compare the merge changeset against its
2908 changesets, as it will compare the merge changeset against its
2909 first parent only.
2909 first parent only.
2910
2910
2911 Output may be to a file, in which case the name of the file is
2911 Output may be to a file, in which case the name of the file is
2912 given using a format string. The formatting rules are as follows:
2912 given using a format string. The formatting rules are as follows:
2913
2913
2914 :``%%``: literal "%" character
2914 :``%%``: literal "%" character
2915 :``%H``: changeset hash (40 hexadecimal digits)
2915 :``%H``: changeset hash (40 hexadecimal digits)
2916 :``%N``: number of patches being generated
2916 :``%N``: number of patches being generated
2917 :``%R``: changeset revision number
2917 :``%R``: changeset revision number
2918 :``%b``: basename of the exporting repository
2918 :``%b``: basename of the exporting repository
2919 :``%h``: short-form changeset hash (12 hexadecimal digits)
2919 :``%h``: short-form changeset hash (12 hexadecimal digits)
2920 :``%m``: first line of the commit message (only alphanumeric characters)
2920 :``%m``: first line of the commit message (only alphanumeric characters)
2921 :``%n``: zero-padded sequence number, starting at 1
2921 :``%n``: zero-padded sequence number, starting at 1
2922 :``%r``: zero-padded changeset revision number
2922 :``%r``: zero-padded changeset revision number
2923
2923
2924 Without the -a/--text option, export will avoid generating diffs
2924 Without the -a/--text option, export will avoid generating diffs
2925 of files it detects as binary. With -a, export will generate a
2925 of files it detects as binary. With -a, export will generate a
2926 diff anyway, probably with undesirable results.
2926 diff anyway, probably with undesirable results.
2927
2927
2928 Use the -g/--git option to generate diffs in the git extended diff
2928 Use the -g/--git option to generate diffs in the git extended diff
2929 format. See :hg:`help diffs` for more information.
2929 format. See :hg:`help diffs` for more information.
2930
2930
2931 With the --switch-parent option, the diff will be against the
2931 With the --switch-parent option, the diff will be against the
2932 second parent. It can be useful to review a merge.
2932 second parent. It can be useful to review a merge.
2933
2933
2934 .. container:: verbose
2934 .. container:: verbose
2935
2935
2936 Examples:
2936 Examples:
2937
2937
2938 - use export and import to transplant a bugfix to the current
2938 - use export and import to transplant a bugfix to the current
2939 branch::
2939 branch::
2940
2940
2941 hg export -r 9353 | hg import -
2941 hg export -r 9353 | hg import -
2942
2942
2943 - export all the changesets between two revisions to a file with
2943 - export all the changesets between two revisions to a file with
2944 rename information::
2944 rename information::
2945
2945
2946 hg export --git -r 123:150 > changes.txt
2946 hg export --git -r 123:150 > changes.txt
2947
2947
2948 - split outgoing changes into a series of patches with
2948 - split outgoing changes into a series of patches with
2949 descriptive names::
2949 descriptive names::
2950
2950
2951 hg export -r "outgoing()" -o "%n-%m.patch"
2951 hg export -r "outgoing()" -o "%n-%m.patch"
2952
2952
2953 Returns 0 on success.
2953 Returns 0 on success.
2954 """
2954 """
2955 changesets += tuple(opts.get('rev', []))
2955 changesets += tuple(opts.get('rev', []))
2956 if not changesets:
2956 if not changesets:
2957 changesets = ['.']
2957 changesets = ['.']
2958 revs = scmutil.revrange(repo, changesets)
2958 revs = scmutil.revrange(repo, changesets)
2959 if not revs:
2959 if not revs:
2960 raise util.Abort(_("export requires at least one changeset"))
2960 raise util.Abort(_("export requires at least one changeset"))
2961 if len(revs) > 1:
2961 if len(revs) > 1:
2962 ui.note(_('exporting patches:\n'))
2962 ui.note(_('exporting patches:\n'))
2963 else:
2963 else:
2964 ui.note(_('exporting patch:\n'))
2964 ui.note(_('exporting patch:\n'))
2965 cmdutil.export(repo, revs, template=opts.get('output'),
2965 cmdutil.export(repo, revs, template=opts.get('output'),
2966 switch_parent=opts.get('switch_parent'),
2966 switch_parent=opts.get('switch_parent'),
2967 opts=patch.diffopts(ui, opts))
2967 opts=patch.diffopts(ui, opts))
2968
2968
2969 @command('^forget', walkopts, _('[OPTION]... FILE...'))
2969 @command('^forget', walkopts, _('[OPTION]... FILE...'))
2970 def forget(ui, repo, *pats, **opts):
2970 def forget(ui, repo, *pats, **opts):
2971 """forget the specified files on the next commit
2971 """forget the specified files on the next commit
2972
2972
2973 Mark the specified files so they will no longer be tracked
2973 Mark the specified files so they will no longer be tracked
2974 after the next commit.
2974 after the next commit.
2975
2975
2976 This only removes files from the current branch, not from the
2976 This only removes files from the current branch, not from the
2977 entire project history, and it does not delete them from the
2977 entire project history, and it does not delete them from the
2978 working directory.
2978 working directory.
2979
2979
2980 To undo a forget before the next commit, see :hg:`add`.
2980 To undo a forget before the next commit, see :hg:`add`.
2981
2981
2982 .. container:: verbose
2982 .. container:: verbose
2983
2983
2984 Examples:
2984 Examples:
2985
2985
2986 - forget newly-added binary files::
2986 - forget newly-added binary files::
2987
2987
2988 hg forget "set:added() and binary()"
2988 hg forget "set:added() and binary()"
2989
2989
2990 - forget files that would be excluded by .hgignore::
2990 - forget files that would be excluded by .hgignore::
2991
2991
2992 hg forget "set:hgignore()"
2992 hg forget "set:hgignore()"
2993
2993
2994 Returns 0 on success.
2994 Returns 0 on success.
2995 """
2995 """
2996
2996
2997 if not pats:
2997 if not pats:
2998 raise util.Abort(_('no files specified'))
2998 raise util.Abort(_('no files specified'))
2999
2999
3000 m = scmutil.match(repo[None], pats, opts)
3000 m = scmutil.match(repo[None], pats, opts)
3001 rejected = cmdutil.forget(ui, repo, m, prefix="", explicitonly=False)[0]
3001 rejected = cmdutil.forget(ui, repo, m, prefix="", explicitonly=False)[0]
3002 return rejected and 1 or 0
3002 return rejected and 1 or 0
3003
3003
3004 @command(
3004 @command(
3005 'graft',
3005 'graft',
3006 [('r', 'rev', [], _('revisions to graft'), _('REV')),
3006 [('r', 'rev', [], _('revisions to graft'), _('REV')),
3007 ('c', 'continue', False, _('resume interrupted graft')),
3007 ('c', 'continue', False, _('resume interrupted graft')),
3008 ('e', 'edit', False, _('invoke editor on commit messages')),
3008 ('e', 'edit', False, _('invoke editor on commit messages')),
3009 ('', 'log', None, _('append graft info to log message')),
3009 ('', 'log', None, _('append graft info to log message')),
3010 ('D', 'currentdate', False,
3010 ('D', 'currentdate', False,
3011 _('record the current date as commit date')),
3011 _('record the current date as commit date')),
3012 ('U', 'currentuser', False,
3012 ('U', 'currentuser', False,
3013 _('record the current user as committer'), _('DATE'))]
3013 _('record the current user as committer'), _('DATE'))]
3014 + commitopts2 + mergetoolopts + dryrunopts,
3014 + commitopts2 + mergetoolopts + dryrunopts,
3015 _('[OPTION]... [-r] REV...'))
3015 _('[OPTION]... [-r] REV...'))
3016 def graft(ui, repo, *revs, **opts):
3016 def graft(ui, repo, *revs, **opts):
3017 '''copy changes from other branches onto the current branch
3017 '''copy changes from other branches onto the current branch
3018
3018
3019 This command uses Mercurial's merge logic to copy individual
3019 This command uses Mercurial's merge logic to copy individual
3020 changes from other branches without merging branches in the
3020 changes from other branches without merging branches in the
3021 history graph. This is sometimes known as 'backporting' or
3021 history graph. This is sometimes known as 'backporting' or
3022 'cherry-picking'. By default, graft will copy user, date, and
3022 'cherry-picking'. By default, graft will copy user, date, and
3023 description from the source changesets.
3023 description from the source changesets.
3024
3024
3025 Changesets that are ancestors of the current revision, that have
3025 Changesets that are ancestors of the current revision, that have
3026 already been grafted, or that are merges will be skipped.
3026 already been grafted, or that are merges will be skipped.
3027
3027
3028 If --log is specified, log messages will have a comment appended
3028 If --log is specified, log messages will have a comment appended
3029 of the form::
3029 of the form::
3030
3030
3031 (grafted from CHANGESETHASH)
3031 (grafted from CHANGESETHASH)
3032
3032
3033 If a graft merge results in conflicts, the graft process is
3033 If a graft merge results in conflicts, the graft process is
3034 interrupted so that the current merge can be manually resolved.
3034 interrupted so that the current merge can be manually resolved.
3035 Once all conflicts are addressed, the graft process can be
3035 Once all conflicts are addressed, the graft process can be
3036 continued with the -c/--continue option.
3036 continued with the -c/--continue option.
3037
3037
3038 .. note::
3038 .. note::
3039
3039
3040 The -c/--continue option does not reapply earlier options.
3040 The -c/--continue option does not reapply earlier options.
3041
3041
3042 .. container:: verbose
3042 .. container:: verbose
3043
3043
3044 Examples:
3044 Examples:
3045
3045
3046 - copy a single change to the stable branch and edit its description::
3046 - copy a single change to the stable branch and edit its description::
3047
3047
3048 hg update stable
3048 hg update stable
3049 hg graft --edit 9393
3049 hg graft --edit 9393
3050
3050
3051 - graft a range of changesets with one exception, updating dates::
3051 - graft a range of changesets with one exception, updating dates::
3052
3052
3053 hg graft -D "2085::2093 and not 2091"
3053 hg graft -D "2085::2093 and not 2091"
3054
3054
3055 - continue a graft after resolving conflicts::
3055 - continue a graft after resolving conflicts::
3056
3056
3057 hg graft -c
3057 hg graft -c
3058
3058
3059 - show the source of a grafted changeset::
3059 - show the source of a grafted changeset::
3060
3060
3061 hg log --debug -r .
3061 hg log --debug -r .
3062
3062
3063 Returns 0 on successful completion.
3063 Returns 0 on successful completion.
3064 '''
3064 '''
3065
3065
3066 revs = list(revs)
3066 revs = list(revs)
3067 revs.extend(opts['rev'])
3067 revs.extend(opts['rev'])
3068
3068
3069 if not opts.get('user') and opts.get('currentuser'):
3069 if not opts.get('user') and opts.get('currentuser'):
3070 opts['user'] = ui.username()
3070 opts['user'] = ui.username()
3071 if not opts.get('date') and opts.get('currentdate'):
3071 if not opts.get('date') and opts.get('currentdate'):
3072 opts['date'] = "%d %d" % util.makedate()
3072 opts['date'] = "%d %d" % util.makedate()
3073
3073
3074 editor = None
3074 editor = None
3075 if opts.get('edit'):
3075 if opts.get('edit'):
3076 editor = cmdutil.commitforceeditor
3076 editor = cmdutil.commitforceeditor
3077
3077
3078 cont = False
3078 cont = False
3079 if opts['continue']:
3079 if opts['continue']:
3080 cont = True
3080 cont = True
3081 if revs:
3081 if revs:
3082 raise util.Abort(_("can't specify --continue and revisions"))
3082 raise util.Abort(_("can't specify --continue and revisions"))
3083 # read in unfinished revisions
3083 # read in unfinished revisions
3084 try:
3084 try:
3085 nodes = repo.opener.read('graftstate').splitlines()
3085 nodes = repo.opener.read('graftstate').splitlines()
3086 revs = [repo[node].rev() for node in nodes]
3086 revs = [repo[node].rev() for node in nodes]
3087 except IOError, inst:
3087 except IOError, inst:
3088 if inst.errno != errno.ENOENT:
3088 if inst.errno != errno.ENOENT:
3089 raise
3089 raise
3090 raise util.Abort(_("no graft state found, can't continue"))
3090 raise util.Abort(_("no graft state found, can't continue"))
3091 else:
3091 else:
3092 cmdutil.checkunfinished(repo)
3092 cmdutil.checkunfinished(repo)
3093 cmdutil.bailifchanged(repo)
3093 cmdutil.bailifchanged(repo)
3094 if not revs:
3094 if not revs:
3095 raise util.Abort(_('no revisions specified'))
3095 raise util.Abort(_('no revisions specified'))
3096 revs = scmutil.revrange(repo, revs)
3096 revs = scmutil.revrange(repo, revs)
3097
3097
3098 # check for merges
3098 # check for merges
3099 for rev in repo.revs('%ld and merge()', revs):
3099 for rev in repo.revs('%ld and merge()', revs):
3100 ui.warn(_('skipping ungraftable merge revision %s\n') % rev)
3100 ui.warn(_('skipping ungraftable merge revision %s\n') % rev)
3101 revs.remove(rev)
3101 revs.remove(rev)
3102 if not revs:
3102 if not revs:
3103 return -1
3103 return -1
3104
3104
3105 # check for ancestors of dest branch
3105 # check for ancestors of dest branch
3106 crev = repo['.'].rev()
3106 crev = repo['.'].rev()
3107 ancestors = repo.changelog.ancestors([crev], inclusive=True)
3107 ancestors = repo.changelog.ancestors([crev], inclusive=True)
3108 # don't mutate while iterating, create a copy
3108 # don't mutate while iterating, create a copy
3109 for rev in list(revs):
3109 for rev in list(revs):
3110 if rev in ancestors:
3110 if rev in ancestors:
3111 ui.warn(_('skipping ancestor revision %s\n') % rev)
3111 ui.warn(_('skipping ancestor revision %s\n') % rev)
3112 revs.remove(rev)
3112 revs.remove(rev)
3113 if not revs:
3113 if not revs:
3114 return -1
3114 return -1
3115
3115
3116 # analyze revs for earlier grafts
3116 # analyze revs for earlier grafts
3117 ids = {}
3117 ids = {}
3118 for ctx in repo.set("%ld", revs):
3118 for ctx in repo.set("%ld", revs):
3119 ids[ctx.hex()] = ctx.rev()
3119 ids[ctx.hex()] = ctx.rev()
3120 n = ctx.extra().get('source')
3120 n = ctx.extra().get('source')
3121 if n:
3121 if n:
3122 ids[n] = ctx.rev()
3122 ids[n] = ctx.rev()
3123
3123
3124 # check ancestors for earlier grafts
3124 # check ancestors for earlier grafts
3125 ui.debug('scanning for duplicate grafts\n')
3125 ui.debug('scanning for duplicate grafts\n')
3126
3126
3127 for rev in repo.changelog.findmissingrevs(revs, [crev]):
3127 for rev in repo.changelog.findmissingrevs(revs, [crev]):
3128 ctx = repo[rev]
3128 ctx = repo[rev]
3129 n = ctx.extra().get('source')
3129 n = ctx.extra().get('source')
3130 if n in ids:
3130 if n in ids:
3131 r = repo[n].rev()
3131 r = repo[n].rev()
3132 if r in revs:
3132 if r in revs:
3133 ui.warn(_('skipping revision %s (already grafted to %s)\n')
3133 ui.warn(_('skipping revision %s (already grafted to %s)\n')
3134 % (r, rev))
3134 % (r, rev))
3135 revs.remove(r)
3135 revs.remove(r)
3136 elif ids[n] in revs:
3136 elif ids[n] in revs:
3137 ui.warn(_('skipping already grafted revision %s '
3137 ui.warn(_('skipping already grafted revision %s '
3138 '(%s also has origin %d)\n') % (ids[n], rev, r))
3138 '(%s also has origin %d)\n') % (ids[n], rev, r))
3139 revs.remove(ids[n])
3139 revs.remove(ids[n])
3140 elif ctx.hex() in ids:
3140 elif ctx.hex() in ids:
3141 r = ids[ctx.hex()]
3141 r = ids[ctx.hex()]
3142 ui.warn(_('skipping already grafted revision %s '
3142 ui.warn(_('skipping already grafted revision %s '
3143 '(was grafted from %d)\n') % (r, rev))
3143 '(was grafted from %d)\n') % (r, rev))
3144 revs.remove(r)
3144 revs.remove(r)
3145 if not revs:
3145 if not revs:
3146 return -1
3146 return -1
3147
3147
3148 wlock = repo.wlock()
3148 wlock = repo.wlock()
3149 try:
3149 try:
3150 current = repo['.']
3150 current = repo['.']
3151 for pos, ctx in enumerate(repo.set("%ld", revs)):
3151 for pos, ctx in enumerate(repo.set("%ld", revs)):
3152
3152
3153 ui.status(_('grafting revision %s\n') % ctx.rev())
3153 ui.status(_('grafting revision %s\n') % ctx.rev())
3154 if opts.get('dry_run'):
3154 if opts.get('dry_run'):
3155 continue
3155 continue
3156
3156
3157 source = ctx.extra().get('source')
3157 source = ctx.extra().get('source')
3158 if not source:
3158 if not source:
3159 source = ctx.hex()
3159 source = ctx.hex()
3160 extra = {'source': source}
3160 extra = {'source': source}
3161 user = ctx.user()
3161 user = ctx.user()
3162 if opts.get('user'):
3162 if opts.get('user'):
3163 user = opts['user']
3163 user = opts['user']
3164 date = ctx.date()
3164 date = ctx.date()
3165 if opts.get('date'):
3165 if opts.get('date'):
3166 date = opts['date']
3166 date = opts['date']
3167 message = ctx.description()
3167 message = ctx.description()
3168 if opts.get('log'):
3168 if opts.get('log'):
3169 message += '\n(grafted from %s)' % ctx.hex()
3169 message += '\n(grafted from %s)' % ctx.hex()
3170
3170
3171 # we don't merge the first commit when continuing
3171 # we don't merge the first commit when continuing
3172 if not cont:
3172 if not cont:
3173 # perform the graft merge with p1(rev) as 'ancestor'
3173 # perform the graft merge with p1(rev) as 'ancestor'
3174 try:
3174 try:
3175 # ui.forcemerge is an internal variable, do not document
3175 # ui.forcemerge is an internal variable, do not document
3176 repo.ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
3176 repo.ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
3177 stats = mergemod.update(repo, ctx.node(), True, True, False,
3177 stats = mergemod.update(repo, ctx.node(), True, True, False,
3178 ctx.p1().node())
3178 ctx.p1().node())
3179 finally:
3179 finally:
3180 repo.ui.setconfig('ui', 'forcemerge', '')
3180 repo.ui.setconfig('ui', 'forcemerge', '')
3181 # report any conflicts
3181 # report any conflicts
3182 if stats and stats[3] > 0:
3182 if stats and stats[3] > 0:
3183 # write out state for --continue
3183 # write out state for --continue
3184 nodelines = [repo[rev].hex() + "\n" for rev in revs[pos:]]
3184 nodelines = [repo[rev].hex() + "\n" for rev in revs[pos:]]
3185 repo.opener.write('graftstate', ''.join(nodelines))
3185 repo.opener.write('graftstate', ''.join(nodelines))
3186 raise util.Abort(
3186 raise util.Abort(
3187 _("unresolved conflicts, can't continue"),
3187 _("unresolved conflicts, can't continue"),
3188 hint=_('use hg resolve and hg graft --continue'))
3188 hint=_('use hg resolve and hg graft --continue'))
3189 else:
3189 else:
3190 cont = False
3190 cont = False
3191
3191
3192 # drop the second merge parent
3192 # drop the second merge parent
3193 repo.setparents(current.node(), nullid)
3193 repo.setparents(current.node(), nullid)
3194 repo.dirstate.write()
3194 repo.dirstate.write()
3195 # fix up dirstate for copies and renames
3195 # fix up dirstate for copies and renames
3196 cmdutil.duplicatecopies(repo, ctx.rev(), ctx.p1().rev())
3196 cmdutil.duplicatecopies(repo, ctx.rev(), ctx.p1().rev())
3197
3197
3198 # commit
3198 # commit
3199 node = repo.commit(text=message, user=user,
3199 node = repo.commit(text=message, user=user,
3200 date=date, extra=extra, editor=editor)
3200 date=date, extra=extra, editor=editor)
3201 if node is None:
3201 if node is None:
3202 ui.status(_('graft for revision %s is empty\n') % ctx.rev())
3202 ui.status(_('graft for revision %s is empty\n') % ctx.rev())
3203 else:
3203 else:
3204 current = repo[node]
3204 current = repo[node]
3205 finally:
3205 finally:
3206 wlock.release()
3206 wlock.release()
3207
3207
3208 # remove state when we complete successfully
3208 # remove state when we complete successfully
3209 if not opts.get('dry_run'):
3209 if not opts.get('dry_run'):
3210 util.unlinkpath(repo.join('graftstate'), ignoremissing=True)
3210 util.unlinkpath(repo.join('graftstate'), ignoremissing=True)
3211
3211
3212 return 0
3212 return 0
3213
3213
3214 @command('grep',
3214 @command('grep',
3215 [('0', 'print0', None, _('end fields with NUL')),
3215 [('0', 'print0', None, _('end fields with NUL')),
3216 ('', 'all', None, _('print all revisions that match')),
3216 ('', 'all', None, _('print all revisions that match')),
3217 ('a', 'text', None, _('treat all files as text')),
3217 ('a', 'text', None, _('treat all files as text')),
3218 ('f', 'follow', None,
3218 ('f', 'follow', None,
3219 _('follow changeset history,'
3219 _('follow changeset history,'
3220 ' or file history across copies and renames')),
3220 ' or file history across copies and renames')),
3221 ('i', 'ignore-case', None, _('ignore case when matching')),
3221 ('i', 'ignore-case', None, _('ignore case when matching')),
3222 ('l', 'files-with-matches', None,
3222 ('l', 'files-with-matches', None,
3223 _('print only filenames and revisions that match')),
3223 _('print only filenames and revisions that match')),
3224 ('n', 'line-number', None, _('print matching line numbers')),
3224 ('n', 'line-number', None, _('print matching line numbers')),
3225 ('r', 'rev', [],
3225 ('r', 'rev', [],
3226 _('only search files changed within revision range'), _('REV')),
3226 _('only search files changed within revision range'), _('REV')),
3227 ('u', 'user', None, _('list the author (long with -v)')),
3227 ('u', 'user', None, _('list the author (long with -v)')),
3228 ('d', 'date', None, _('list the date (short with -q)')),
3228 ('d', 'date', None, _('list the date (short with -q)')),
3229 ] + walkopts,
3229 ] + walkopts,
3230 _('[OPTION]... PATTERN [FILE]...'))
3230 _('[OPTION]... PATTERN [FILE]...'))
3231 def grep(ui, repo, pattern, *pats, **opts):
3231 def grep(ui, repo, pattern, *pats, **opts):
3232 """search for a pattern in specified files and revisions
3232 """search for a pattern in specified files and revisions
3233
3233
3234 Search revisions of files for a regular expression.
3234 Search revisions of files for a regular expression.
3235
3235
3236 This command behaves differently than Unix grep. It only accepts
3236 This command behaves differently than Unix grep. It only accepts
3237 Python/Perl regexps. It searches repository history, not the
3237 Python/Perl regexps. It searches repository history, not the
3238 working directory. It always prints the revision number in which a
3238 working directory. It always prints the revision number in which a
3239 match appears.
3239 match appears.
3240
3240
3241 By default, grep only prints output for the first revision of a
3241 By default, grep only prints output for the first revision of a
3242 file in which it finds a match. To get it to print every revision
3242 file in which it finds a match. To get it to print every revision
3243 that contains a change in match status ("-" for a match that
3243 that contains a change in match status ("-" for a match that
3244 becomes a non-match, or "+" for a non-match that becomes a match),
3244 becomes a non-match, or "+" for a non-match that becomes a match),
3245 use the --all flag.
3245 use the --all flag.
3246
3246
3247 Returns 0 if a match is found, 1 otherwise.
3247 Returns 0 if a match is found, 1 otherwise.
3248 """
3248 """
3249 reflags = re.M
3249 reflags = re.M
3250 if opts.get('ignore_case'):
3250 if opts.get('ignore_case'):
3251 reflags |= re.I
3251 reflags |= re.I
3252 try:
3252 try:
3253 regexp = util.compilere(pattern, reflags)
3253 regexp = util.compilere(pattern, reflags)
3254 except re.error, inst:
3254 except re.error, inst:
3255 ui.warn(_("grep: invalid match pattern: %s\n") % inst)
3255 ui.warn(_("grep: invalid match pattern: %s\n") % inst)
3256 return 1
3256 return 1
3257 sep, eol = ':', '\n'
3257 sep, eol = ':', '\n'
3258 if opts.get('print0'):
3258 if opts.get('print0'):
3259 sep = eol = '\0'
3259 sep = eol = '\0'
3260
3260
3261 getfile = util.lrucachefunc(repo.file)
3261 getfile = util.lrucachefunc(repo.file)
3262
3262
3263 def matchlines(body):
3263 def matchlines(body):
3264 begin = 0
3264 begin = 0
3265 linenum = 0
3265 linenum = 0
3266 while begin < len(body):
3266 while begin < len(body):
3267 match = regexp.search(body, begin)
3267 match = regexp.search(body, begin)
3268 if not match:
3268 if not match:
3269 break
3269 break
3270 mstart, mend = match.span()
3270 mstart, mend = match.span()
3271 linenum += body.count('\n', begin, mstart) + 1
3271 linenum += body.count('\n', begin, mstart) + 1
3272 lstart = body.rfind('\n', begin, mstart) + 1 or begin
3272 lstart = body.rfind('\n', begin, mstart) + 1 or begin
3273 begin = body.find('\n', mend) + 1 or len(body) + 1
3273 begin = body.find('\n', mend) + 1 or len(body) + 1
3274 lend = begin - 1
3274 lend = begin - 1
3275 yield linenum, mstart - lstart, mend - lstart, body[lstart:lend]
3275 yield linenum, mstart - lstart, mend - lstart, body[lstart:lend]
3276
3276
3277 class linestate(object):
3277 class linestate(object):
3278 def __init__(self, line, linenum, colstart, colend):
3278 def __init__(self, line, linenum, colstart, colend):
3279 self.line = line
3279 self.line = line
3280 self.linenum = linenum
3280 self.linenum = linenum
3281 self.colstart = colstart
3281 self.colstart = colstart
3282 self.colend = colend
3282 self.colend = colend
3283
3283
3284 def __hash__(self):
3284 def __hash__(self):
3285 return hash((self.linenum, self.line))
3285 return hash((self.linenum, self.line))
3286
3286
3287 def __eq__(self, other):
3287 def __eq__(self, other):
3288 return self.line == other.line
3288 return self.line == other.line
3289
3289
3290 matches = {}
3290 matches = {}
3291 copies = {}
3291 copies = {}
3292 def grepbody(fn, rev, body):
3292 def grepbody(fn, rev, body):
3293 matches[rev].setdefault(fn, [])
3293 matches[rev].setdefault(fn, [])
3294 m = matches[rev][fn]
3294 m = matches[rev][fn]
3295 for lnum, cstart, cend, line in matchlines(body):
3295 for lnum, cstart, cend, line in matchlines(body):
3296 s = linestate(line, lnum, cstart, cend)
3296 s = linestate(line, lnum, cstart, cend)
3297 m.append(s)
3297 m.append(s)
3298
3298
3299 def difflinestates(a, b):
3299 def difflinestates(a, b):
3300 sm = difflib.SequenceMatcher(None, a, b)
3300 sm = difflib.SequenceMatcher(None, a, b)
3301 for tag, alo, ahi, blo, bhi in sm.get_opcodes():
3301 for tag, alo, ahi, blo, bhi in sm.get_opcodes():
3302 if tag == 'insert':
3302 if tag == 'insert':
3303 for i in xrange(blo, bhi):
3303 for i in xrange(blo, bhi):
3304 yield ('+', b[i])
3304 yield ('+', b[i])
3305 elif tag == 'delete':
3305 elif tag == 'delete':
3306 for i in xrange(alo, ahi):
3306 for i in xrange(alo, ahi):
3307 yield ('-', a[i])
3307 yield ('-', a[i])
3308 elif tag == 'replace':
3308 elif tag == 'replace':
3309 for i in xrange(alo, ahi):
3309 for i in xrange(alo, ahi):
3310 yield ('-', a[i])
3310 yield ('-', a[i])
3311 for i in xrange(blo, bhi):
3311 for i in xrange(blo, bhi):
3312 yield ('+', b[i])
3312 yield ('+', b[i])
3313
3313
3314 def display(fn, ctx, pstates, states):
3314 def display(fn, ctx, pstates, states):
3315 rev = ctx.rev()
3315 rev = ctx.rev()
3316 datefunc = ui.quiet and util.shortdate or util.datestr
3316 datefunc = ui.quiet and util.shortdate or util.datestr
3317 found = False
3317 found = False
3318 filerevmatches = {}
3318 filerevmatches = {}
3319 def binary():
3319 def binary():
3320 flog = getfile(fn)
3320 flog = getfile(fn)
3321 return util.binary(flog.read(ctx.filenode(fn)))
3321 return util.binary(flog.read(ctx.filenode(fn)))
3322
3322
3323 if opts.get('all'):
3323 if opts.get('all'):
3324 iter = difflinestates(pstates, states)
3324 iter = difflinestates(pstates, states)
3325 else:
3325 else:
3326 iter = [('', l) for l in states]
3326 iter = [('', l) for l in states]
3327 for change, l in iter:
3327 for change, l in iter:
3328 cols = [(fn, 'grep.filename'), (str(rev), 'grep.rev')]
3328 cols = [(fn, 'grep.filename'), (str(rev), 'grep.rev')]
3329 before, match, after = None, None, None
3329 before, match, after = None, None, None
3330
3330
3331 if opts.get('line_number'):
3331 if opts.get('line_number'):
3332 cols.append((str(l.linenum), 'grep.linenumber'))
3332 cols.append((str(l.linenum), 'grep.linenumber'))
3333 if opts.get('all'):
3333 if opts.get('all'):
3334 cols.append((change, 'grep.change'))
3334 cols.append((change, 'grep.change'))
3335 if opts.get('user'):
3335 if opts.get('user'):
3336 cols.append((ui.shortuser(ctx.user()), 'grep.user'))
3336 cols.append((ui.shortuser(ctx.user()), 'grep.user'))
3337 if opts.get('date'):
3337 if opts.get('date'):
3338 cols.append((datefunc(ctx.date()), 'grep.date'))
3338 cols.append((datefunc(ctx.date()), 'grep.date'))
3339 if opts.get('files_with_matches'):
3339 if opts.get('files_with_matches'):
3340 c = (fn, rev)
3340 c = (fn, rev)
3341 if c in filerevmatches:
3341 if c in filerevmatches:
3342 continue
3342 continue
3343 filerevmatches[c] = 1
3343 filerevmatches[c] = 1
3344 else:
3344 else:
3345 before = l.line[:l.colstart]
3345 before = l.line[:l.colstart]
3346 match = l.line[l.colstart:l.colend]
3346 match = l.line[l.colstart:l.colend]
3347 after = l.line[l.colend:]
3347 after = l.line[l.colend:]
3348 for col, label in cols[:-1]:
3348 for col, label in cols[:-1]:
3349 ui.write(col, label=label)
3349 ui.write(col, label=label)
3350 ui.write(sep, label='grep.sep')
3350 ui.write(sep, label='grep.sep')
3351 ui.write(cols[-1][0], label=cols[-1][1])
3351 ui.write(cols[-1][0], label=cols[-1][1])
3352 if before is not None:
3352 if before is not None:
3353 ui.write(sep, label='grep.sep')
3353 ui.write(sep, label='grep.sep')
3354 if not opts.get('text') and binary():
3354 if not opts.get('text') and binary():
3355 ui.write(" Binary file matches")
3355 ui.write(" Binary file matches")
3356 else:
3356 else:
3357 ui.write(before)
3357 ui.write(before)
3358 ui.write(match, label='grep.match')
3358 ui.write(match, label='grep.match')
3359 ui.write(after)
3359 ui.write(after)
3360 ui.write(eol)
3360 ui.write(eol)
3361 found = True
3361 found = True
3362 return found
3362 return found
3363
3363
3364 skip = {}
3364 skip = {}
3365 revfiles = {}
3365 revfiles = {}
3366 matchfn = scmutil.match(repo[None], pats, opts)
3366 matchfn = scmutil.match(repo[None], pats, opts)
3367 found = False
3367 found = False
3368 follow = opts.get('follow')
3368 follow = opts.get('follow')
3369
3369
3370 def prep(ctx, fns):
3370 def prep(ctx, fns):
3371 rev = ctx.rev()
3371 rev = ctx.rev()
3372 pctx = ctx.p1()
3372 pctx = ctx.p1()
3373 parent = pctx.rev()
3373 parent = pctx.rev()
3374 matches.setdefault(rev, {})
3374 matches.setdefault(rev, {})
3375 matches.setdefault(parent, {})
3375 matches.setdefault(parent, {})
3376 files = revfiles.setdefault(rev, [])
3376 files = revfiles.setdefault(rev, [])
3377 for fn in fns:
3377 for fn in fns:
3378 flog = getfile(fn)
3378 flog = getfile(fn)
3379 try:
3379 try:
3380 fnode = ctx.filenode(fn)
3380 fnode = ctx.filenode(fn)
3381 except error.LookupError:
3381 except error.LookupError:
3382 continue
3382 continue
3383
3383
3384 copied = flog.renamed(fnode)
3384 copied = flog.renamed(fnode)
3385 copy = follow and copied and copied[0]
3385 copy = follow and copied and copied[0]
3386 if copy:
3386 if copy:
3387 copies.setdefault(rev, {})[fn] = copy
3387 copies.setdefault(rev, {})[fn] = copy
3388 if fn in skip:
3388 if fn in skip:
3389 if copy:
3389 if copy:
3390 skip[copy] = True
3390 skip[copy] = True
3391 continue
3391 continue
3392 files.append(fn)
3392 files.append(fn)
3393
3393
3394 if fn not in matches[rev]:
3394 if fn not in matches[rev]:
3395 grepbody(fn, rev, flog.read(fnode))
3395 grepbody(fn, rev, flog.read(fnode))
3396
3396
3397 pfn = copy or fn
3397 pfn = copy or fn
3398 if pfn not in matches[parent]:
3398 if pfn not in matches[parent]:
3399 try:
3399 try:
3400 fnode = pctx.filenode(pfn)
3400 fnode = pctx.filenode(pfn)
3401 grepbody(pfn, parent, flog.read(fnode))
3401 grepbody(pfn, parent, flog.read(fnode))
3402 except error.LookupError:
3402 except error.LookupError:
3403 pass
3403 pass
3404
3404
3405 for ctx in cmdutil.walkchangerevs(repo, matchfn, opts, prep):
3405 for ctx in cmdutil.walkchangerevs(repo, matchfn, opts, prep):
3406 rev = ctx.rev()
3406 rev = ctx.rev()
3407 parent = ctx.p1().rev()
3407 parent = ctx.p1().rev()
3408 for fn in sorted(revfiles.get(rev, [])):
3408 for fn in sorted(revfiles.get(rev, [])):
3409 states = matches[rev][fn]
3409 states = matches[rev][fn]
3410 copy = copies.get(rev, {}).get(fn)
3410 copy = copies.get(rev, {}).get(fn)
3411 if fn in skip:
3411 if fn in skip:
3412 if copy:
3412 if copy:
3413 skip[copy] = True
3413 skip[copy] = True
3414 continue
3414 continue
3415 pstates = matches.get(parent, {}).get(copy or fn, [])
3415 pstates = matches.get(parent, {}).get(copy or fn, [])
3416 if pstates or states:
3416 if pstates or states:
3417 r = display(fn, ctx, pstates, states)
3417 r = display(fn, ctx, pstates, states)
3418 found = found or r
3418 found = found or r
3419 if r and not opts.get('all'):
3419 if r and not opts.get('all'):
3420 skip[fn] = True
3420 skip[fn] = True
3421 if copy:
3421 if copy:
3422 skip[copy] = True
3422 skip[copy] = True
3423 del matches[rev]
3423 del matches[rev]
3424 del revfiles[rev]
3424 del revfiles[rev]
3425
3425
3426 return not found
3426 return not found
3427
3427
3428 @command('heads',
3428 @command('heads',
3429 [('r', 'rev', '',
3429 [('r', 'rev', '',
3430 _('show only heads which are descendants of STARTREV'), _('STARTREV')),
3430 _('show only heads which are descendants of STARTREV'), _('STARTREV')),
3431 ('t', 'topo', False, _('show topological heads only')),
3431 ('t', 'topo', False, _('show topological heads only')),
3432 ('a', 'active', False, _('show active branchheads only (DEPRECATED)')),
3432 ('a', 'active', False, _('show active branchheads only (DEPRECATED)')),
3433 ('c', 'closed', False, _('show normal and closed branch heads')),
3433 ('c', 'closed', False, _('show normal and closed branch heads')),
3434 ] + templateopts,
3434 ] + templateopts,
3435 _('[-ct] [-r STARTREV] [REV]...'))
3435 _('[-ct] [-r STARTREV] [REV]...'))
3436 def heads(ui, repo, *branchrevs, **opts):
3436 def heads(ui, repo, *branchrevs, **opts):
3437 """show branch heads
3437 """show branch heads
3438
3438
3439 With no arguments, show all open branch heads in the repository.
3439 With no arguments, show all open branch heads in the repository.
3440 Branch heads are changesets that have no descendants on the
3440 Branch heads are changesets that have no descendants on the
3441 same branch. They are where development generally takes place and
3441 same branch. They are where development generally takes place and
3442 are the usual targets for update and merge operations.
3442 are the usual targets for update and merge operations.
3443
3443
3444 If one or more REVs are given, only open branch heads on the
3444 If one or more REVs are given, only open branch heads on the
3445 branches associated with the specified changesets are shown. This
3445 branches associated with the specified changesets are shown. This
3446 means that you can use :hg:`heads .` to see the heads on the
3446 means that you can use :hg:`heads .` to see the heads on the
3447 currently checked-out branch.
3447 currently checked-out branch.
3448
3448
3449 If -c/--closed is specified, also show branch heads marked closed
3449 If -c/--closed is specified, also show branch heads marked closed
3450 (see :hg:`commit --close-branch`).
3450 (see :hg:`commit --close-branch`).
3451
3451
3452 If STARTREV is specified, only those heads that are descendants of
3452 If STARTREV is specified, only those heads that are descendants of
3453 STARTREV will be displayed.
3453 STARTREV will be displayed.
3454
3454
3455 If -t/--topo is specified, named branch mechanics will be ignored and only
3455 If -t/--topo is specified, named branch mechanics will be ignored and only
3456 topological heads (changesets with no children) will be shown.
3456 topological heads (changesets with no children) will be shown.
3457
3457
3458 Returns 0 if matching heads are found, 1 if not.
3458 Returns 0 if matching heads are found, 1 if not.
3459 """
3459 """
3460
3460
3461 start = None
3461 start = None
3462 if 'rev' in opts:
3462 if 'rev' in opts:
3463 start = scmutil.revsingle(repo, opts['rev'], None).node()
3463 start = scmutil.revsingle(repo, opts['rev'], None).node()
3464
3464
3465 if opts.get('topo'):
3465 if opts.get('topo'):
3466 heads = [repo[h] for h in repo.heads(start)]
3466 heads = [repo[h] for h in repo.heads(start)]
3467 else:
3467 else:
3468 heads = []
3468 heads = []
3469 for branch in repo.branchmap():
3469 for branch in repo.branchmap():
3470 heads += repo.branchheads(branch, start, opts.get('closed'))
3470 heads += repo.branchheads(branch, start, opts.get('closed'))
3471 heads = [repo[h] for h in heads]
3471 heads = [repo[h] for h in heads]
3472
3472
3473 if branchrevs:
3473 if branchrevs:
3474 branches = set(repo[br].branch() for br in branchrevs)
3474 branches = set(repo[br].branch() for br in branchrevs)
3475 heads = [h for h in heads if h.branch() in branches]
3475 heads = [h for h in heads if h.branch() in branches]
3476
3476
3477 if opts.get('active') and branchrevs:
3477 if opts.get('active') and branchrevs:
3478 dagheads = repo.heads(start)
3478 dagheads = repo.heads(start)
3479 heads = [h for h in heads if h.node() in dagheads]
3479 heads = [h for h in heads if h.node() in dagheads]
3480
3480
3481 if branchrevs:
3481 if branchrevs:
3482 haveheads = set(h.branch() for h in heads)
3482 haveheads = set(h.branch() for h in heads)
3483 if branches - haveheads:
3483 if branches - haveheads:
3484 headless = ', '.join(b for b in branches - haveheads)
3484 headless = ', '.join(b for b in branches - haveheads)
3485 msg = _('no open branch heads found on branches %s')
3485 msg = _('no open branch heads found on branches %s')
3486 if opts.get('rev'):
3486 if opts.get('rev'):
3487 msg += _(' (started at %s)') % opts['rev']
3487 msg += _(' (started at %s)') % opts['rev']
3488 ui.warn((msg + '\n') % headless)
3488 ui.warn((msg + '\n') % headless)
3489
3489
3490 if not heads:
3490 if not heads:
3491 return 1
3491 return 1
3492
3492
3493 heads = sorted(heads, key=lambda x: -x.rev())
3493 heads = sorted(heads, key=lambda x: -x.rev())
3494 displayer = cmdutil.show_changeset(ui, repo, opts)
3494 displayer = cmdutil.show_changeset(ui, repo, opts)
3495 for ctx in heads:
3495 for ctx in heads:
3496 displayer.show(ctx)
3496 displayer.show(ctx)
3497 displayer.close()
3497 displayer.close()
3498
3498
3499 @command('help',
3499 @command('help',
3500 [('e', 'extension', None, _('show only help for extensions')),
3500 [('e', 'extension', None, _('show only help for extensions')),
3501 ('c', 'command', None, _('show only help for commands')),
3501 ('c', 'command', None, _('show only help for commands')),
3502 ('k', 'keyword', '', _('show topics matching keyword')),
3502 ('k', 'keyword', '', _('show topics matching keyword')),
3503 ],
3503 ],
3504 _('[-ec] [TOPIC]'))
3504 _('[-ec] [TOPIC]'))
3505 def help_(ui, name=None, **opts):
3505 def help_(ui, name=None, **opts):
3506 """show help for a given topic or a help overview
3506 """show help for a given topic or a help overview
3507
3507
3508 With no arguments, print a list of commands with short help messages.
3508 With no arguments, print a list of commands with short help messages.
3509
3509
3510 Given a topic, extension, or command name, print help for that
3510 Given a topic, extension, or command name, print help for that
3511 topic.
3511 topic.
3512
3512
3513 Returns 0 if successful.
3513 Returns 0 if successful.
3514 """
3514 """
3515
3515
3516 textwidth = min(ui.termwidth(), 80) - 2
3516 textwidth = min(ui.termwidth(), 80) - 2
3517
3517
3518 keep = ui.verbose and ['verbose'] or []
3518 keep = ui.verbose and ['verbose'] or []
3519 text = help.help_(ui, name, **opts)
3519 text = help.help_(ui, name, **opts)
3520
3520
3521 formatted, pruned = minirst.format(text, textwidth, keep=keep)
3521 formatted, pruned = minirst.format(text, textwidth, keep=keep)
3522 if 'verbose' in pruned:
3522 if 'verbose' in pruned:
3523 keep.append('omitted')
3523 keep.append('omitted')
3524 else:
3524 else:
3525 keep.append('notomitted')
3525 keep.append('notomitted')
3526 formatted, pruned = minirst.format(text, textwidth, keep=keep)
3526 formatted, pruned = minirst.format(text, textwidth, keep=keep)
3527 ui.write(formatted)
3527 ui.write(formatted)
3528
3528
3529
3529
3530 @command('identify|id',
3530 @command('identify|id',
3531 [('r', 'rev', '',
3531 [('r', 'rev', '',
3532 _('identify the specified revision'), _('REV')),
3532 _('identify the specified revision'), _('REV')),
3533 ('n', 'num', None, _('show local revision number')),
3533 ('n', 'num', None, _('show local revision number')),
3534 ('i', 'id', None, _('show global revision id')),
3534 ('i', 'id', None, _('show global revision id')),
3535 ('b', 'branch', None, _('show branch')),
3535 ('b', 'branch', None, _('show branch')),
3536 ('t', 'tags', None, _('show tags')),
3536 ('t', 'tags', None, _('show tags')),
3537 ('B', 'bookmarks', None, _('show bookmarks')),
3537 ('B', 'bookmarks', None, _('show bookmarks')),
3538 ] + remoteopts,
3538 ] + remoteopts,
3539 _('[-nibtB] [-r REV] [SOURCE]'))
3539 _('[-nibtB] [-r REV] [SOURCE]'))
3540 def identify(ui, repo, source=None, rev=None,
3540 def identify(ui, repo, source=None, rev=None,
3541 num=None, id=None, branch=None, tags=None, bookmarks=None, **opts):
3541 num=None, id=None, branch=None, tags=None, bookmarks=None, **opts):
3542 """identify the working copy or specified revision
3542 """identify the working copy or specified revision
3543
3543
3544 Print a summary identifying the repository state at REV using one or
3544 Print a summary identifying the repository state at REV using one or
3545 two parent hash identifiers, followed by a "+" if the working
3545 two parent hash identifiers, followed by a "+" if the working
3546 directory has uncommitted changes, the branch name (if not default),
3546 directory has uncommitted changes, the branch name (if not default),
3547 a list of tags, and a list of bookmarks.
3547 a list of tags, and a list of bookmarks.
3548
3548
3549 When REV is not given, print a summary of the current state of the
3549 When REV is not given, print a summary of the current state of the
3550 repository.
3550 repository.
3551
3551
3552 Specifying a path to a repository root or Mercurial bundle will
3552 Specifying a path to a repository root or Mercurial bundle will
3553 cause lookup to operate on that repository/bundle.
3553 cause lookup to operate on that repository/bundle.
3554
3554
3555 .. container:: verbose
3555 .. container:: verbose
3556
3556
3557 Examples:
3557 Examples:
3558
3558
3559 - generate a build identifier for the working directory::
3559 - generate a build identifier for the working directory::
3560
3560
3561 hg id --id > build-id.dat
3561 hg id --id > build-id.dat
3562
3562
3563 - find the revision corresponding to a tag::
3563 - find the revision corresponding to a tag::
3564
3564
3565 hg id -n -r 1.3
3565 hg id -n -r 1.3
3566
3566
3567 - check the most recent revision of a remote repository::
3567 - check the most recent revision of a remote repository::
3568
3568
3569 hg id -r tip http://selenic.com/hg/
3569 hg id -r tip http://selenic.com/hg/
3570
3570
3571 Returns 0 if successful.
3571 Returns 0 if successful.
3572 """
3572 """
3573
3573
3574 if not repo and not source:
3574 if not repo and not source:
3575 raise util.Abort(_("there is no Mercurial repository here "
3575 raise util.Abort(_("there is no Mercurial repository here "
3576 "(.hg not found)"))
3576 "(.hg not found)"))
3577
3577
3578 hexfunc = ui.debugflag and hex or short
3578 hexfunc = ui.debugflag and hex or short
3579 default = not (num or id or branch or tags or bookmarks)
3579 default = not (num or id or branch or tags or bookmarks)
3580 output = []
3580 output = []
3581 revs = []
3581 revs = []
3582
3582
3583 if source:
3583 if source:
3584 source, branches = hg.parseurl(ui.expandpath(source))
3584 source, branches = hg.parseurl(ui.expandpath(source))
3585 peer = hg.peer(repo or ui, opts, source) # only pass ui when no repo
3585 peer = hg.peer(repo or ui, opts, source) # only pass ui when no repo
3586 repo = peer.local()
3586 repo = peer.local()
3587 revs, checkout = hg.addbranchrevs(repo, peer, branches, None)
3587 revs, checkout = hg.addbranchrevs(repo, peer, branches, None)
3588
3588
3589 if not repo:
3589 if not repo:
3590 if num or branch or tags:
3590 if num or branch or tags:
3591 raise util.Abort(
3591 raise util.Abort(
3592 _("can't query remote revision number, branch, or tags"))
3592 _("can't query remote revision number, branch, or tags"))
3593 if not rev and revs:
3593 if not rev and revs:
3594 rev = revs[0]
3594 rev = revs[0]
3595 if not rev:
3595 if not rev:
3596 rev = "tip"
3596 rev = "tip"
3597
3597
3598 remoterev = peer.lookup(rev)
3598 remoterev = peer.lookup(rev)
3599 if default or id:
3599 if default or id:
3600 output = [hexfunc(remoterev)]
3600 output = [hexfunc(remoterev)]
3601
3601
3602 def getbms():
3602 def getbms():
3603 bms = []
3603 bms = []
3604
3604
3605 if 'bookmarks' in peer.listkeys('namespaces'):
3605 if 'bookmarks' in peer.listkeys('namespaces'):
3606 hexremoterev = hex(remoterev)
3606 hexremoterev = hex(remoterev)
3607 bms = [bm for bm, bmr in peer.listkeys('bookmarks').iteritems()
3607 bms = [bm for bm, bmr in peer.listkeys('bookmarks').iteritems()
3608 if bmr == hexremoterev]
3608 if bmr == hexremoterev]
3609
3609
3610 return sorted(bms)
3610 return sorted(bms)
3611
3611
3612 if bookmarks:
3612 if bookmarks:
3613 output.extend(getbms())
3613 output.extend(getbms())
3614 elif default and not ui.quiet:
3614 elif default and not ui.quiet:
3615 # multiple bookmarks for a single parent separated by '/'
3615 # multiple bookmarks for a single parent separated by '/'
3616 bm = '/'.join(getbms())
3616 bm = '/'.join(getbms())
3617 if bm:
3617 if bm:
3618 output.append(bm)
3618 output.append(bm)
3619 else:
3619 else:
3620 if not rev:
3620 if not rev:
3621 ctx = repo[None]
3621 ctx = repo[None]
3622 parents = ctx.parents()
3622 parents = ctx.parents()
3623 changed = ""
3623 changed = ""
3624 if default or id or num:
3624 if default or id or num:
3625 if (util.any(repo.status())
3625 if (util.any(repo.status())
3626 or util.any(ctx.sub(s).dirty() for s in ctx.substate)):
3626 or util.any(ctx.sub(s).dirty() for s in ctx.substate)):
3627 changed = '+'
3627 changed = '+'
3628 if default or id:
3628 if default or id:
3629 output = ["%s%s" %
3629 output = ["%s%s" %
3630 ('+'.join([hexfunc(p.node()) for p in parents]), changed)]
3630 ('+'.join([hexfunc(p.node()) for p in parents]), changed)]
3631 if num:
3631 if num:
3632 output.append("%s%s" %
3632 output.append("%s%s" %
3633 ('+'.join([str(p.rev()) for p in parents]), changed))
3633 ('+'.join([str(p.rev()) for p in parents]), changed))
3634 else:
3634 else:
3635 ctx = scmutil.revsingle(repo, rev)
3635 ctx = scmutil.revsingle(repo, rev)
3636 if default or id:
3636 if default or id:
3637 output = [hexfunc(ctx.node())]
3637 output = [hexfunc(ctx.node())]
3638 if num:
3638 if num:
3639 output.append(str(ctx.rev()))
3639 output.append(str(ctx.rev()))
3640
3640
3641 if default and not ui.quiet:
3641 if default and not ui.quiet:
3642 b = ctx.branch()
3642 b = ctx.branch()
3643 if b != 'default':
3643 if b != 'default':
3644 output.append("(%s)" % b)
3644 output.append("(%s)" % b)
3645
3645
3646 # multiple tags for a single parent separated by '/'
3646 # multiple tags for a single parent separated by '/'
3647 t = '/'.join(ctx.tags())
3647 t = '/'.join(ctx.tags())
3648 if t:
3648 if t:
3649 output.append(t)
3649 output.append(t)
3650
3650
3651 # multiple bookmarks for a single parent separated by '/'
3651 # multiple bookmarks for a single parent separated by '/'
3652 bm = '/'.join(ctx.bookmarks())
3652 bm = '/'.join(ctx.bookmarks())
3653 if bm:
3653 if bm:
3654 output.append(bm)
3654 output.append(bm)
3655 else:
3655 else:
3656 if branch:
3656 if branch:
3657 output.append(ctx.branch())
3657 output.append(ctx.branch())
3658
3658
3659 if tags:
3659 if tags:
3660 output.extend(ctx.tags())
3660 output.extend(ctx.tags())
3661
3661
3662 if bookmarks:
3662 if bookmarks:
3663 output.extend(ctx.bookmarks())
3663 output.extend(ctx.bookmarks())
3664
3664
3665 ui.write("%s\n" % ' '.join(output))
3665 ui.write("%s\n" % ' '.join(output))
3666
3666
3667 @command('import|patch',
3667 @command('import|patch',
3668 [('p', 'strip', 1,
3668 [('p', 'strip', 1,
3669 _('directory strip option for patch. This has the same '
3669 _('directory strip option for patch. This has the same '
3670 'meaning as the corresponding patch option'), _('NUM')),
3670 'meaning as the corresponding patch option'), _('NUM')),
3671 ('b', 'base', '', _('base path (DEPRECATED)'), _('PATH')),
3671 ('b', 'base', '', _('base path (DEPRECATED)'), _('PATH')),
3672 ('e', 'edit', False, _('invoke editor on commit messages')),
3672 ('e', 'edit', False, _('invoke editor on commit messages')),
3673 ('f', 'force', None,
3673 ('f', 'force', None,
3674 _('skip check for outstanding uncommitted changes (DEPRECATED)')),
3674 _('skip check for outstanding uncommitted changes (DEPRECATED)')),
3675 ('', 'no-commit', None,
3675 ('', 'no-commit', None,
3676 _("don't commit, just update the working directory")),
3676 _("don't commit, just update the working directory")),
3677 ('', 'bypass', None,
3677 ('', 'bypass', None,
3678 _("apply patch without touching the working directory")),
3678 _("apply patch without touching the working directory")),
3679 ('', 'exact', None,
3679 ('', 'exact', None,
3680 _('apply patch to the nodes from which it was generated')),
3680 _('apply patch to the nodes from which it was generated')),
3681 ('', 'import-branch', None,
3681 ('', 'import-branch', None,
3682 _('use any branch information in patch (implied by --exact)'))] +
3682 _('use any branch information in patch (implied by --exact)'))] +
3683 commitopts + commitopts2 + similarityopts,
3683 commitopts + commitopts2 + similarityopts,
3684 _('[OPTION]... PATCH...'))
3684 _('[OPTION]... PATCH...'))
3685 def import_(ui, repo, patch1=None, *patches, **opts):
3685 def import_(ui, repo, patch1=None, *patches, **opts):
3686 """import an ordered set of patches
3686 """import an ordered set of patches
3687
3687
3688 Import a list of patches and commit them individually (unless
3688 Import a list of patches and commit them individually (unless
3689 --no-commit is specified).
3689 --no-commit is specified).
3690
3690
3691 Because import first applies changes to the working directory,
3691 Because import first applies changes to the working directory,
3692 import will abort if there are outstanding changes.
3692 import will abort if there are outstanding changes.
3693
3693
3694 You can import a patch straight from a mail message. Even patches
3694 You can import a patch straight from a mail message. Even patches
3695 as attachments work (to use the body part, it must have type
3695 as attachments work (to use the body part, it must have type
3696 text/plain or text/x-patch). From and Subject headers of email
3696 text/plain or text/x-patch). From and Subject headers of email
3697 message are used as default committer and commit message. All
3697 message are used as default committer and commit message. All
3698 text/plain body parts before first diff are added to commit
3698 text/plain body parts before first diff are added to commit
3699 message.
3699 message.
3700
3700
3701 If the imported patch was generated by :hg:`export`, user and
3701 If the imported patch was generated by :hg:`export`, user and
3702 description from patch override values from message headers and
3702 description from patch override values from message headers and
3703 body. Values given on command line with -m/--message and -u/--user
3703 body. Values given on command line with -m/--message and -u/--user
3704 override these.
3704 override these.
3705
3705
3706 If --exact is specified, import will set the working directory to
3706 If --exact is specified, import will set the working directory to
3707 the parent of each patch before applying it, and will abort if the
3707 the parent of each patch before applying it, and will abort if the
3708 resulting changeset has a different ID than the one recorded in
3708 resulting changeset has a different ID than the one recorded in
3709 the patch. This may happen due to character set problems or other
3709 the patch. This may happen due to character set problems or other
3710 deficiencies in the text patch format.
3710 deficiencies in the text patch format.
3711
3711
3712 Use --bypass to apply and commit patches directly to the
3712 Use --bypass to apply and commit patches directly to the
3713 repository, not touching the working directory. Without --exact,
3713 repository, not touching the working directory. Without --exact,
3714 patches will be applied on top of the working directory parent
3714 patches will be applied on top of the working directory parent
3715 revision.
3715 revision.
3716
3716
3717 With -s/--similarity, hg will attempt to discover renames and
3717 With -s/--similarity, hg will attempt to discover renames and
3718 copies in the patch in the same way as :hg:`addremove`.
3718 copies in the patch in the same way as :hg:`addremove`.
3719
3719
3720 To read a patch from standard input, use "-" as the patch name. If
3720 To read a patch from standard input, use "-" as the patch name. If
3721 a URL is specified, the patch will be downloaded from it.
3721 a URL is specified, the patch will be downloaded from it.
3722 See :hg:`help dates` for a list of formats valid for -d/--date.
3722 See :hg:`help dates` for a list of formats valid for -d/--date.
3723
3723
3724 .. container:: verbose
3724 .. container:: verbose
3725
3725
3726 Examples:
3726 Examples:
3727
3727
3728 - import a traditional patch from a website and detect renames::
3728 - import a traditional patch from a website and detect renames::
3729
3729
3730 hg import -s 80 http://example.com/bugfix.patch
3730 hg import -s 80 http://example.com/bugfix.patch
3731
3731
3732 - import a changeset from an hgweb server::
3732 - import a changeset from an hgweb server::
3733
3733
3734 hg import http://www.selenic.com/hg/rev/5ca8c111e9aa
3734 hg import http://www.selenic.com/hg/rev/5ca8c111e9aa
3735
3735
3736 - import all the patches in an Unix-style mbox::
3736 - import all the patches in an Unix-style mbox::
3737
3737
3738 hg import incoming-patches.mbox
3738 hg import incoming-patches.mbox
3739
3739
3740 - attempt to exactly restore an exported changeset (not always
3740 - attempt to exactly restore an exported changeset (not always
3741 possible)::
3741 possible)::
3742
3742
3743 hg import --exact proposed-fix.patch
3743 hg import --exact proposed-fix.patch
3744
3744
3745 Returns 0 on success.
3745 Returns 0 on success.
3746 """
3746 """
3747
3747
3748 if not patch1:
3748 if not patch1:
3749 raise util.Abort(_('need at least one patch to import'))
3749 raise util.Abort(_('need at least one patch to import'))
3750
3750
3751 patches = (patch1,) + patches
3751 patches = (patch1,) + patches
3752
3752
3753 date = opts.get('date')
3753 date = opts.get('date')
3754 if date:
3754 if date:
3755 opts['date'] = util.parsedate(date)
3755 opts['date'] = util.parsedate(date)
3756
3756
3757 update = not opts.get('bypass')
3757 update = not opts.get('bypass')
3758 if not update and opts.get('no_commit'):
3758 if not update and opts.get('no_commit'):
3759 raise util.Abort(_('cannot use --no-commit with --bypass'))
3759 raise util.Abort(_('cannot use --no-commit with --bypass'))
3760 try:
3760 try:
3761 sim = float(opts.get('similarity') or 0)
3761 sim = float(opts.get('similarity') or 0)
3762 except ValueError:
3762 except ValueError:
3763 raise util.Abort(_('similarity must be a number'))
3763 raise util.Abort(_('similarity must be a number'))
3764 if sim < 0 or sim > 100:
3764 if sim < 0 or sim > 100:
3765 raise util.Abort(_('similarity must be between 0 and 100'))
3765 raise util.Abort(_('similarity must be between 0 and 100'))
3766 if sim and not update:
3766 if sim and not update:
3767 raise util.Abort(_('cannot use --similarity with --bypass'))
3767 raise util.Abort(_('cannot use --similarity with --bypass'))
3768
3768
3769 if update:
3769 if update:
3770 cmdutil.checkunfinished(repo)
3770 cmdutil.checkunfinished(repo)
3771 if (opts.get('exact') or not opts.get('force')) and update:
3771 if (opts.get('exact') or not opts.get('force')) and update:
3772 cmdutil.bailifchanged(repo)
3772 cmdutil.bailifchanged(repo)
3773
3773
3774 base = opts["base"]
3774 base = opts["base"]
3775 wlock = lock = tr = None
3775 wlock = lock = tr = None
3776 msgs = []
3776 msgs = []
3777
3777
3778
3778
3779 try:
3779 try:
3780 try:
3780 try:
3781 wlock = repo.wlock()
3781 wlock = repo.wlock()
3782 if not opts.get('no_commit'):
3782 if not opts.get('no_commit'):
3783 lock = repo.lock()
3783 lock = repo.lock()
3784 tr = repo.transaction('import')
3784 tr = repo.transaction('import')
3785 parents = repo.parents()
3785 parents = repo.parents()
3786 for patchurl in patches:
3786 for patchurl in patches:
3787 if patchurl == '-':
3787 if patchurl == '-':
3788 ui.status(_('applying patch from stdin\n'))
3788 ui.status(_('applying patch from stdin\n'))
3789 patchfile = ui.fin
3789 patchfile = ui.fin
3790 patchurl = 'stdin' # for error message
3790 patchurl = 'stdin' # for error message
3791 else:
3791 else:
3792 patchurl = os.path.join(base, patchurl)
3792 patchurl = os.path.join(base, patchurl)
3793 ui.status(_('applying %s\n') % patchurl)
3793 ui.status(_('applying %s\n') % patchurl)
3794 patchfile = hg.openpath(ui, patchurl)
3794 patchfile = hg.openpath(ui, patchurl)
3795
3795
3796 haspatch = False
3796 haspatch = False
3797 for hunk in patch.split(patchfile):
3797 for hunk in patch.split(patchfile):
3798 (msg, node) = cmdutil.tryimportone(ui, repo, hunk, parents,
3798 (msg, node) = cmdutil.tryimportone(ui, repo, hunk, parents,
3799 opts, msgs, hg.clean)
3799 opts, msgs, hg.clean)
3800 if msg:
3800 if msg:
3801 haspatch = True
3801 haspatch = True
3802 ui.note(msg + '\n')
3802 ui.note(msg + '\n')
3803 if update or opts.get('exact'):
3803 if update or opts.get('exact'):
3804 parents = repo.parents()
3804 parents = repo.parents()
3805 else:
3805 else:
3806 parents = [repo[node]]
3806 parents = [repo[node]]
3807
3807
3808 if not haspatch:
3808 if not haspatch:
3809 raise util.Abort(_('%s: no diffs found') % patchurl)
3809 raise util.Abort(_('%s: no diffs found') % patchurl)
3810
3810
3811 if tr:
3811 if tr:
3812 tr.close()
3812 tr.close()
3813 if msgs:
3813 if msgs:
3814 repo.savecommitmessage('\n* * *\n'.join(msgs))
3814 repo.savecommitmessage('\n* * *\n'.join(msgs))
3815 except: # re-raises
3815 except: # re-raises
3816 # wlock.release() indirectly calls dirstate.write(): since
3816 # wlock.release() indirectly calls dirstate.write(): since
3817 # we're crashing, we do not want to change the working dir
3817 # we're crashing, we do not want to change the working dir
3818 # parent after all, so make sure it writes nothing
3818 # parent after all, so make sure it writes nothing
3819 repo.dirstate.invalidate()
3819 repo.dirstate.invalidate()
3820 raise
3820 raise
3821 finally:
3821 finally:
3822 if tr:
3822 if tr:
3823 tr.release()
3823 tr.release()
3824 release(lock, wlock)
3824 release(lock, wlock)
3825
3825
3826 @command('incoming|in',
3826 @command('incoming|in',
3827 [('f', 'force', None,
3827 [('f', 'force', None,
3828 _('run even if remote repository is unrelated')),
3828 _('run even if remote repository is unrelated')),
3829 ('n', 'newest-first', None, _('show newest record first')),
3829 ('n', 'newest-first', None, _('show newest record first')),
3830 ('', 'bundle', '',
3830 ('', 'bundle', '',
3831 _('file to store the bundles into'), _('FILE')),
3831 _('file to store the bundles into'), _('FILE')),
3832 ('r', 'rev', [], _('a remote changeset intended to be added'), _('REV')),
3832 ('r', 'rev', [], _('a remote changeset intended to be added'), _('REV')),
3833 ('B', 'bookmarks', False, _("compare bookmarks")),
3833 ('B', 'bookmarks', False, _("compare bookmarks")),
3834 ('b', 'branch', [],
3834 ('b', 'branch', [],
3835 _('a specific branch you would like to pull'), _('BRANCH')),
3835 _('a specific branch you would like to pull'), _('BRANCH')),
3836 ] + logopts + remoteopts + subrepoopts,
3836 ] + logopts + remoteopts + subrepoopts,
3837 _('[-p] [-n] [-M] [-f] [-r REV]... [--bundle FILENAME] [SOURCE]'))
3837 _('[-p] [-n] [-M] [-f] [-r REV]... [--bundle FILENAME] [SOURCE]'))
3838 def incoming(ui, repo, source="default", **opts):
3838 def incoming(ui, repo, source="default", **opts):
3839 """show new changesets found in source
3839 """show new changesets found in source
3840
3840
3841 Show new changesets found in the specified path/URL or the default
3841 Show new changesets found in the specified path/URL or the default
3842 pull location. These are the changesets that would have been pulled
3842 pull location. These are the changesets that would have been pulled
3843 if a pull at the time you issued this command.
3843 if a pull at the time you issued this command.
3844
3844
3845 For remote repository, using --bundle avoids downloading the
3845 For remote repository, using --bundle avoids downloading the
3846 changesets twice if the incoming is followed by a pull.
3846 changesets twice if the incoming is followed by a pull.
3847
3847
3848 See pull for valid source format details.
3848 See pull for valid source format details.
3849
3849
3850 Returns 0 if there are incoming changes, 1 otherwise.
3850 Returns 0 if there are incoming changes, 1 otherwise.
3851 """
3851 """
3852 if opts.get('graph'):
3852 if opts.get('graph'):
3853 cmdutil.checkunsupportedgraphflags([], opts)
3853 cmdutil.checkunsupportedgraphflags([], opts)
3854 def display(other, chlist, displayer):
3854 def display(other, chlist, displayer):
3855 revdag = cmdutil.graphrevs(other, chlist, opts)
3855 revdag = cmdutil.graphrevs(other, chlist, opts)
3856 showparents = [ctx.node() for ctx in repo[None].parents()]
3856 showparents = [ctx.node() for ctx in repo[None].parents()]
3857 cmdutil.displaygraph(ui, revdag, displayer, showparents,
3857 cmdutil.displaygraph(ui, revdag, displayer, showparents,
3858 graphmod.asciiedges)
3858 graphmod.asciiedges)
3859
3859
3860 hg._incoming(display, lambda: 1, ui, repo, source, opts, buffered=True)
3860 hg._incoming(display, lambda: 1, ui, repo, source, opts, buffered=True)
3861 return 0
3861 return 0
3862
3862
3863 if opts.get('bundle') and opts.get('subrepos'):
3863 if opts.get('bundle') and opts.get('subrepos'):
3864 raise util.Abort(_('cannot combine --bundle and --subrepos'))
3864 raise util.Abort(_('cannot combine --bundle and --subrepos'))
3865
3865
3866 if opts.get('bookmarks'):
3866 if opts.get('bookmarks'):
3867 source, branches = hg.parseurl(ui.expandpath(source),
3867 source, branches = hg.parseurl(ui.expandpath(source),
3868 opts.get('branch'))
3868 opts.get('branch'))
3869 other = hg.peer(repo, opts, source)
3869 other = hg.peer(repo, opts, source)
3870 if 'bookmarks' not in other.listkeys('namespaces'):
3870 if 'bookmarks' not in other.listkeys('namespaces'):
3871 ui.warn(_("remote doesn't support bookmarks\n"))
3871 ui.warn(_("remote doesn't support bookmarks\n"))
3872 return 0
3872 return 0
3873 ui.status(_('comparing with %s\n') % util.hidepassword(source))
3873 ui.status(_('comparing with %s\n') % util.hidepassword(source))
3874 return bookmarks.diff(ui, repo, other)
3874 return bookmarks.diff(ui, repo, other)
3875
3875
3876 repo._subtoppath = ui.expandpath(source)
3876 repo._subtoppath = ui.expandpath(source)
3877 try:
3877 try:
3878 return hg.incoming(ui, repo, source, opts)
3878 return hg.incoming(ui, repo, source, opts)
3879 finally:
3879 finally:
3880 del repo._subtoppath
3880 del repo._subtoppath
3881
3881
3882
3882
3883 @command('^init', remoteopts, _('[-e CMD] [--remotecmd CMD] [DEST]'))
3883 @command('^init', remoteopts, _('[-e CMD] [--remotecmd CMD] [DEST]'))
3884 def init(ui, dest=".", **opts):
3884 def init(ui, dest=".", **opts):
3885 """create a new repository in the given directory
3885 """create a new repository in the given directory
3886
3886
3887 Initialize a new repository in the given directory. If the given
3887 Initialize a new repository in the given directory. If the given
3888 directory does not exist, it will be created.
3888 directory does not exist, it will be created.
3889
3889
3890 If no directory is given, the current directory is used.
3890 If no directory is given, the current directory is used.
3891
3891
3892 It is possible to specify an ``ssh://`` URL as the destination.
3892 It is possible to specify an ``ssh://`` URL as the destination.
3893 See :hg:`help urls` for more information.
3893 See :hg:`help urls` for more information.
3894
3894
3895 Returns 0 on success.
3895 Returns 0 on success.
3896 """
3896 """
3897 hg.peer(ui, opts, ui.expandpath(dest), create=True)
3897 hg.peer(ui, opts, ui.expandpath(dest), create=True)
3898
3898
3899 @command('locate',
3899 @command('locate',
3900 [('r', 'rev', '', _('search the repository as it is in REV'), _('REV')),
3900 [('r', 'rev', '', _('search the repository as it is in REV'), _('REV')),
3901 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
3901 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
3902 ('f', 'fullpath', None, _('print complete paths from the filesystem root')),
3902 ('f', 'fullpath', None, _('print complete paths from the filesystem root')),
3903 ] + walkopts,
3903 ] + walkopts,
3904 _('[OPTION]... [PATTERN]...'))
3904 _('[OPTION]... [PATTERN]...'))
3905 def locate(ui, repo, *pats, **opts):
3905 def locate(ui, repo, *pats, **opts):
3906 """locate files matching specific patterns
3906 """locate files matching specific patterns
3907
3907
3908 Print files under Mercurial control in the working directory whose
3908 Print files under Mercurial control in the working directory whose
3909 names match the given patterns.
3909 names match the given patterns.
3910
3910
3911 By default, this command searches all directories in the working
3911 By default, this command searches all directories in the working
3912 directory. To search just the current directory and its
3912 directory. To search just the current directory and its
3913 subdirectories, use "--include .".
3913 subdirectories, use "--include .".
3914
3914
3915 If no patterns are given to match, this command prints the names
3915 If no patterns are given to match, this command prints the names
3916 of all files under Mercurial control in the working directory.
3916 of all files under Mercurial control in the working directory.
3917
3917
3918 If you want to feed the output of this command into the "xargs"
3918 If you want to feed the output of this command into the "xargs"
3919 command, use the -0 option to both this command and "xargs". This
3919 command, use the -0 option to both this command and "xargs". This
3920 will avoid the problem of "xargs" treating single filenames that
3920 will avoid the problem of "xargs" treating single filenames that
3921 contain whitespace as multiple filenames.
3921 contain whitespace as multiple filenames.
3922
3922
3923 Returns 0 if a match is found, 1 otherwise.
3923 Returns 0 if a match is found, 1 otherwise.
3924 """
3924 """
3925 end = opts.get('print0') and '\0' or '\n'
3925 end = opts.get('print0') and '\0' or '\n'
3926 rev = scmutil.revsingle(repo, opts.get('rev'), None).node()
3926 rev = scmutil.revsingle(repo, opts.get('rev'), None).node()
3927
3927
3928 ret = 1
3928 ret = 1
3929 m = scmutil.match(repo[rev], pats, opts, default='relglob')
3929 m = scmutil.match(repo[rev], pats, opts, default='relglob')
3930 m.bad = lambda x, y: False
3930 m.bad = lambda x, y: False
3931 for abs in repo[rev].walk(m):
3931 for abs in repo[rev].walk(m):
3932 if not rev and abs not in repo.dirstate:
3932 if not rev and abs not in repo.dirstate:
3933 continue
3933 continue
3934 if opts.get('fullpath'):
3934 if opts.get('fullpath'):
3935 ui.write(repo.wjoin(abs), end)
3935 ui.write(repo.wjoin(abs), end)
3936 else:
3936 else:
3937 ui.write(((pats and m.rel(abs)) or abs), end)
3937 ui.write(((pats and m.rel(abs)) or abs), end)
3938 ret = 0
3938 ret = 0
3939
3939
3940 return ret
3940 return ret
3941
3941
3942 @command('^log|history',
3942 @command('^log|history',
3943 [('f', 'follow', None,
3943 [('f', 'follow', None,
3944 _('follow changeset history, or file history across copies and renames')),
3944 _('follow changeset history, or file history across copies and renames')),
3945 ('', 'follow-first', None,
3945 ('', 'follow-first', None,
3946 _('only follow the first parent of merge changesets (DEPRECATED)')),
3946 _('only follow the first parent of merge changesets (DEPRECATED)')),
3947 ('d', 'date', '', _('show revisions matching date spec'), _('DATE')),
3947 ('d', 'date', '', _('show revisions matching date spec'), _('DATE')),
3948 ('C', 'copies', None, _('show copied files')),
3948 ('C', 'copies', None, _('show copied files')),
3949 ('k', 'keyword', [],
3949 ('k', 'keyword', [],
3950 _('do case-insensitive search for a given text'), _('TEXT')),
3950 _('do case-insensitive search for a given text'), _('TEXT')),
3951 ('r', 'rev', [], _('show the specified revision or range'), _('REV')),
3951 ('r', 'rev', [], _('show the specified revision or range'), _('REV')),
3952 ('', 'removed', None, _('include revisions where files were removed')),
3952 ('', 'removed', None, _('include revisions where files were removed')),
3953 ('m', 'only-merges', None, _('show only merges (DEPRECATED)')),
3953 ('m', 'only-merges', None, _('show only merges (DEPRECATED)')),
3954 ('u', 'user', [], _('revisions committed by user'), _('USER')),
3954 ('u', 'user', [], _('revisions committed by user'), _('USER')),
3955 ('', 'only-branch', [],
3955 ('', 'only-branch', [],
3956 _('show only changesets within the given named branch (DEPRECATED)'),
3956 _('show only changesets within the given named branch (DEPRECATED)'),
3957 _('BRANCH')),
3957 _('BRANCH')),
3958 ('b', 'branch', [],
3958 ('b', 'branch', [],
3959 _('show changesets within the given named branch'), _('BRANCH')),
3959 _('show changesets within the given named branch'), _('BRANCH')),
3960 ('P', 'prune', [],
3960 ('P', 'prune', [],
3961 _('do not display revision or any of its ancestors'), _('REV')),
3961 _('do not display revision or any of its ancestors'), _('REV')),
3962 ] + logopts + walkopts,
3962 ] + logopts + walkopts,
3963 _('[OPTION]... [FILE]'))
3963 _('[OPTION]... [FILE]'))
3964 def log(ui, repo, *pats, **opts):
3964 def log(ui, repo, *pats, **opts):
3965 """show revision history of entire repository or files
3965 """show revision history of entire repository or files
3966
3966
3967 Print the revision history of the specified files or the entire
3967 Print the revision history of the specified files or the entire
3968 project.
3968 project.
3969
3969
3970 If no revision range is specified, the default is ``tip:0`` unless
3970 If no revision range is specified, the default is ``tip:0`` unless
3971 --follow is set, in which case the working directory parent is
3971 --follow is set, in which case the working directory parent is
3972 used as the starting revision.
3972 used as the starting revision.
3973
3973
3974 File history is shown without following rename or copy history of
3974 File history is shown without following rename or copy history of
3975 files. Use -f/--follow with a filename to follow history across
3975 files. Use -f/--follow with a filename to follow history across
3976 renames and copies. --follow without a filename will only show
3976 renames and copies. --follow without a filename will only show
3977 ancestors or descendants of the starting revision.
3977 ancestors or descendants of the starting revision.
3978
3978
3979 By default this command prints revision number and changeset id,
3979 By default this command prints revision number and changeset id,
3980 tags, non-trivial parents, user, date and time, and a summary for
3980 tags, non-trivial parents, user, date and time, and a summary for
3981 each commit. When the -v/--verbose switch is used, the list of
3981 each commit. When the -v/--verbose switch is used, the list of
3982 changed files and full commit message are shown.
3982 changed files and full commit message are shown.
3983
3983
3984 With --graph the revisions are shown as an ASCII art DAG with the most
3984 With --graph the revisions are shown as an ASCII art DAG with the most
3985 recent changeset at the top.
3985 recent changeset at the top.
3986 'o' is a changeset, '@' is a working directory parent, 'x' is obsolete,
3986 'o' is a changeset, '@' is a working directory parent, 'x' is obsolete,
3987 and '+' represents a fork where the changeset from the lines below is a
3987 and '+' represents a fork where the changeset from the lines below is a
3988 parent of the 'o' merge on the same same line.
3988 parent of the 'o' merge on the same same line.
3989
3989
3990 .. note::
3990 .. note::
3991
3991
3992 log -p/--patch may generate unexpected diff output for merge
3992 log -p/--patch may generate unexpected diff output for merge
3993 changesets, as it will only compare the merge changeset against
3993 changesets, as it will only compare the merge changeset against
3994 its first parent. Also, only files different from BOTH parents
3994 its first parent. Also, only files different from BOTH parents
3995 will appear in files:.
3995 will appear in files:.
3996
3996
3997 .. note::
3997 .. note::
3998
3998
3999 for performance reasons, log FILE may omit duplicate changes
3999 for performance reasons, log FILE may omit duplicate changes
4000 made on branches and will not show deletions. To see all
4000 made on branches and will not show deletions. To see all
4001 changes including duplicates and deletions, use the --removed
4001 changes including duplicates and deletions, use the --removed
4002 switch.
4002 switch.
4003
4003
4004 .. container:: verbose
4004 .. container:: verbose
4005
4005
4006 Some examples:
4006 Some examples:
4007
4007
4008 - changesets with full descriptions and file lists::
4008 - changesets with full descriptions and file lists::
4009
4009
4010 hg log -v
4010 hg log -v
4011
4011
4012 - changesets ancestral to the working directory::
4012 - changesets ancestral to the working directory::
4013
4013
4014 hg log -f
4014 hg log -f
4015
4015
4016 - last 10 commits on the current branch::
4016 - last 10 commits on the current branch::
4017
4017
4018 hg log -l 10 -b .
4018 hg log -l 10 -b .
4019
4019
4020 - changesets showing all modifications of a file, including removals::
4020 - changesets showing all modifications of a file, including removals::
4021
4021
4022 hg log --removed file.c
4022 hg log --removed file.c
4023
4023
4024 - all changesets that touch a directory, with diffs, excluding merges::
4024 - all changesets that touch a directory, with diffs, excluding merges::
4025
4025
4026 hg log -Mp lib/
4026 hg log -Mp lib/
4027
4027
4028 - all revision numbers that match a keyword::
4028 - all revision numbers that match a keyword::
4029
4029
4030 hg log -k bug --template "{rev}\\n"
4030 hg log -k bug --template "{rev}\\n"
4031
4031
4032 - check if a given changeset is included is a tagged release::
4032 - check if a given changeset is included is a tagged release::
4033
4033
4034 hg log -r "a21ccf and ancestor(1.9)"
4034 hg log -r "a21ccf and ancestor(1.9)"
4035
4035
4036 - find all changesets by some user in a date range::
4036 - find all changesets by some user in a date range::
4037
4037
4038 hg log -k alice -d "may 2008 to jul 2008"
4038 hg log -k alice -d "may 2008 to jul 2008"
4039
4039
4040 - summary of all changesets after the last tag::
4040 - summary of all changesets after the last tag::
4041
4041
4042 hg log -r "last(tagged())::" --template "{desc|firstline}\\n"
4042 hg log -r "last(tagged())::" --template "{desc|firstline}\\n"
4043
4043
4044 See :hg:`help dates` for a list of formats valid for -d/--date.
4044 See :hg:`help dates` for a list of formats valid for -d/--date.
4045
4045
4046 See :hg:`help revisions` and :hg:`help revsets` for more about
4046 See :hg:`help revisions` and :hg:`help revsets` for more about
4047 specifying revisions.
4047 specifying revisions.
4048
4048
4049 See :hg:`help templates` for more about pre-packaged styles and
4049 See :hg:`help templates` for more about pre-packaged styles and
4050 specifying custom templates.
4050 specifying custom templates.
4051
4051
4052 Returns 0 on success.
4052 Returns 0 on success.
4053 """
4053 """
4054 if opts.get('graph'):
4054 if opts.get('graph'):
4055 return cmdutil.graphlog(ui, repo, *pats, **opts)
4055 return cmdutil.graphlog(ui, repo, *pats, **opts)
4056
4056
4057 matchfn = scmutil.match(repo[None], pats, opts)
4057 matchfn = scmutil.match(repo[None], pats, opts)
4058 limit = cmdutil.loglimit(opts)
4058 limit = cmdutil.loglimit(opts)
4059 count = 0
4059 count = 0
4060
4060
4061 getrenamed, endrev = None, None
4061 getrenamed, endrev = None, None
4062 if opts.get('copies'):
4062 if opts.get('copies'):
4063 if opts.get('rev'):
4063 if opts.get('rev'):
4064 endrev = max(scmutil.revrange(repo, opts.get('rev'))) + 1
4064 endrev = max(scmutil.revrange(repo, opts.get('rev'))) + 1
4065 getrenamed = templatekw.getrenamedfn(repo, endrev=endrev)
4065 getrenamed = templatekw.getrenamedfn(repo, endrev=endrev)
4066
4066
4067 df = False
4067 df = False
4068 if opts.get("date"):
4068 if opts.get("date"):
4069 df = util.matchdate(opts["date"])
4069 df = util.matchdate(opts["date"])
4070
4070
4071 branches = opts.get('branch', []) + opts.get('only_branch', [])
4071 branches = opts.get('branch', []) + opts.get('only_branch', [])
4072 opts['branch'] = [repo.lookupbranch(b) for b in branches]
4072 opts['branch'] = [repo.lookupbranch(b) for b in branches]
4073
4073
4074 displayer = cmdutil.show_changeset(ui, repo, opts, True)
4074 displayer = cmdutil.show_changeset(ui, repo, opts, True)
4075 def prep(ctx, fns):
4075 def prep(ctx, fns):
4076 rev = ctx.rev()
4076 rev = ctx.rev()
4077 parents = [p for p in repo.changelog.parentrevs(rev)
4077 parents = [p for p in repo.changelog.parentrevs(rev)
4078 if p != nullrev]
4078 if p != nullrev]
4079 if opts.get('no_merges') and len(parents) == 2:
4079 if opts.get('no_merges') and len(parents) == 2:
4080 return
4080 return
4081 if opts.get('only_merges') and len(parents) != 2:
4081 if opts.get('only_merges') and len(parents) != 2:
4082 return
4082 return
4083 if opts.get('branch') and ctx.branch() not in opts['branch']:
4083 if opts.get('branch') and ctx.branch() not in opts['branch']:
4084 return
4084 return
4085 if df and not df(ctx.date()[0]):
4085 if df and not df(ctx.date()[0]):
4086 return
4086 return
4087
4087
4088 lower = encoding.lower
4088 lower = encoding.lower
4089 if opts.get('user'):
4089 if opts.get('user'):
4090 luser = lower(ctx.user())
4090 luser = lower(ctx.user())
4091 for k in [lower(x) for x in opts['user']]:
4091 for k in [lower(x) for x in opts['user']]:
4092 if (k in luser):
4092 if (k in luser):
4093 break
4093 break
4094 else:
4094 else:
4095 return
4095 return
4096 if opts.get('keyword'):
4096 if opts.get('keyword'):
4097 luser = lower(ctx.user())
4097 luser = lower(ctx.user())
4098 ldesc = lower(ctx.description())
4098 ldesc = lower(ctx.description())
4099 lfiles = lower(" ".join(ctx.files()))
4099 lfiles = lower(" ".join(ctx.files()))
4100 for k in [lower(x) for x in opts['keyword']]:
4100 for k in [lower(x) for x in opts['keyword']]:
4101 if (k in luser or k in ldesc or k in lfiles):
4101 if (k in luser or k in ldesc or k in lfiles):
4102 break
4102 break
4103 else:
4103 else:
4104 return
4104 return
4105
4105
4106 copies = None
4106 copies = None
4107 if getrenamed is not None and rev:
4107 if getrenamed is not None and rev:
4108 copies = []
4108 copies = []
4109 for fn in ctx.files():
4109 for fn in ctx.files():
4110 rename = getrenamed(fn, rev)
4110 rename = getrenamed(fn, rev)
4111 if rename:
4111 if rename:
4112 copies.append((fn, rename[0]))
4112 copies.append((fn, rename[0]))
4113
4113
4114 revmatchfn = None
4114 revmatchfn = None
4115 if opts.get('patch') or opts.get('stat'):
4115 if opts.get('patch') or opts.get('stat'):
4116 if opts.get('follow') or opts.get('follow_first'):
4116 if opts.get('follow') or opts.get('follow_first'):
4117 # note: this might be wrong when following through merges
4117 # note: this might be wrong when following through merges
4118 revmatchfn = scmutil.match(repo[None], fns, default='path')
4118 revmatchfn = scmutil.match(repo[None], fns, default='path')
4119 else:
4119 else:
4120 revmatchfn = matchfn
4120 revmatchfn = matchfn
4121
4121
4122 displayer.show(ctx, copies=copies, matchfn=revmatchfn)
4122 displayer.show(ctx, copies=copies, matchfn=revmatchfn)
4123
4123
4124 for ctx in cmdutil.walkchangerevs(repo, matchfn, opts, prep):
4124 for ctx in cmdutil.walkchangerevs(repo, matchfn, opts, prep):
4125 if displayer.flush(ctx.rev()):
4125 if displayer.flush(ctx.rev()):
4126 count += 1
4126 count += 1
4127 if count == limit:
4127 if count == limit:
4128 break
4128 break
4129 displayer.close()
4129 displayer.close()
4130
4130
4131 @command('manifest',
4131 @command('manifest',
4132 [('r', 'rev', '', _('revision to display'), _('REV')),
4132 [('r', 'rev', '', _('revision to display'), _('REV')),
4133 ('', 'all', False, _("list files from all revisions"))],
4133 ('', 'all', False, _("list files from all revisions"))],
4134 _('[-r REV]'))
4134 _('[-r REV]'))
4135 def manifest(ui, repo, node=None, rev=None, **opts):
4135 def manifest(ui, repo, node=None, rev=None, **opts):
4136 """output the current or given revision of the project manifest
4136 """output the current or given revision of the project manifest
4137
4137
4138 Print a list of version controlled files for the given revision.
4138 Print a list of version controlled files for the given revision.
4139 If no revision is given, the first parent of the working directory
4139 If no revision is given, the first parent of the working directory
4140 is used, or the null revision if no revision is checked out.
4140 is used, or the null revision if no revision is checked out.
4141
4141
4142 With -v, print file permissions, symlink and executable bits.
4142 With -v, print file permissions, symlink and executable bits.
4143 With --debug, print file revision hashes.
4143 With --debug, print file revision hashes.
4144
4144
4145 If option --all is specified, the list of all files from all revisions
4145 If option --all is specified, the list of all files from all revisions
4146 is printed. This includes deleted and renamed files.
4146 is printed. This includes deleted and renamed files.
4147
4147
4148 Returns 0 on success.
4148 Returns 0 on success.
4149 """
4149 """
4150
4150
4151 fm = ui.formatter('manifest', opts)
4151 fm = ui.formatter('manifest', opts)
4152
4152
4153 if opts.get('all'):
4153 if opts.get('all'):
4154 if rev or node:
4154 if rev or node:
4155 raise util.Abort(_("can't specify a revision with --all"))
4155 raise util.Abort(_("can't specify a revision with --all"))
4156
4156
4157 res = []
4157 res = []
4158 prefix = "data/"
4158 prefix = "data/"
4159 suffix = ".i"
4159 suffix = ".i"
4160 plen = len(prefix)
4160 plen = len(prefix)
4161 slen = len(suffix)
4161 slen = len(suffix)
4162 lock = repo.lock()
4162 lock = repo.lock()
4163 try:
4163 try:
4164 for fn, b, size in repo.store.datafiles():
4164 for fn, b, size in repo.store.datafiles():
4165 if size != 0 and fn[-slen:] == suffix and fn[:plen] == prefix:
4165 if size != 0 and fn[-slen:] == suffix and fn[:plen] == prefix:
4166 res.append(fn[plen:-slen])
4166 res.append(fn[plen:-slen])
4167 finally:
4167 finally:
4168 lock.release()
4168 lock.release()
4169 for f in res:
4169 for f in res:
4170 fm.startitem()
4170 fm.startitem()
4171 fm.write("path", '%s\n', f)
4171 fm.write("path", '%s\n', f)
4172 fm.end()
4172 fm.end()
4173 return
4173 return
4174
4174
4175 if rev and node:
4175 if rev and node:
4176 raise util.Abort(_("please specify just one revision"))
4176 raise util.Abort(_("please specify just one revision"))
4177
4177
4178 if not node:
4178 if not node:
4179 node = rev
4179 node = rev
4180
4180
4181 char = {'l': '@', 'x': '*', '': ''}
4181 char = {'l': '@', 'x': '*', '': ''}
4182 mode = {'l': '644', 'x': '755', '': '644'}
4182 mode = {'l': '644', 'x': '755', '': '644'}
4183 ctx = scmutil.revsingle(repo, node)
4183 ctx = scmutil.revsingle(repo, node)
4184 mf = ctx.manifest()
4184 mf = ctx.manifest()
4185 for f in ctx:
4185 for f in ctx:
4186 fm.startitem()
4186 fm.startitem()
4187 fl = ctx[f].flags()
4187 fl = ctx[f].flags()
4188 fm.condwrite(ui.debugflag, 'hash', '%s ', hex(mf[f]))
4188 fm.condwrite(ui.debugflag, 'hash', '%s ', hex(mf[f]))
4189 fm.condwrite(ui.verbose, 'mode type', '%s %1s ', mode[fl], char[fl])
4189 fm.condwrite(ui.verbose, 'mode type', '%s %1s ', mode[fl], char[fl])
4190 fm.write('path', '%s\n', f)
4190 fm.write('path', '%s\n', f)
4191 fm.end()
4191 fm.end()
4192
4192
4193 @command('^merge',
4193 @command('^merge',
4194 [('f', 'force', None,
4194 [('f', 'force', None,
4195 _('force a merge including outstanding changes (DEPRECATED)')),
4195 _('force a merge including outstanding changes (DEPRECATED)')),
4196 ('r', 'rev', '', _('revision to merge'), _('REV')),
4196 ('r', 'rev', '', _('revision to merge'), _('REV')),
4197 ('P', 'preview', None,
4197 ('P', 'preview', None,
4198 _('review revisions to merge (no merge is performed)'))
4198 _('review revisions to merge (no merge is performed)'))
4199 ] + mergetoolopts,
4199 ] + mergetoolopts,
4200 _('[-P] [-f] [[-r] REV]'))
4200 _('[-P] [-f] [[-r] REV]'))
4201 def merge(ui, repo, node=None, **opts):
4201 def merge(ui, repo, node=None, **opts):
4202 """merge working directory with another revision
4202 """merge working directory with another revision
4203
4203
4204 The current working directory is updated with all changes made in
4204 The current working directory is updated with all changes made in
4205 the requested revision since the last common predecessor revision.
4205 the requested revision since the last common predecessor revision.
4206
4206
4207 Files that changed between either parent are marked as changed for
4207 Files that changed between either parent are marked as changed for
4208 the next commit and a commit must be performed before any further
4208 the next commit and a commit must be performed before any further
4209 updates to the repository are allowed. The next commit will have
4209 updates to the repository are allowed. The next commit will have
4210 two parents.
4210 two parents.
4211
4211
4212 ``--tool`` can be used to specify the merge tool used for file
4212 ``--tool`` can be used to specify the merge tool used for file
4213 merges. It overrides the HGMERGE environment variable and your
4213 merges. It overrides the HGMERGE environment variable and your
4214 configuration files. See :hg:`help merge-tools` for options.
4214 configuration files. See :hg:`help merge-tools` for options.
4215
4215
4216 If no revision is specified, the working directory's parent is a
4216 If no revision is specified, the working directory's parent is a
4217 head revision, and the current branch contains exactly one other
4217 head revision, and the current branch contains exactly one other
4218 head, the other head is merged with by default. Otherwise, an
4218 head, the other head is merged with by default. Otherwise, an
4219 explicit revision with which to merge with must be provided.
4219 explicit revision with which to merge with must be provided.
4220
4220
4221 :hg:`resolve` must be used to resolve unresolved files.
4221 :hg:`resolve` must be used to resolve unresolved files.
4222
4222
4223 To undo an uncommitted merge, use :hg:`update --clean .` which
4223 To undo an uncommitted merge, use :hg:`update --clean .` which
4224 will check out a clean copy of the original merge parent, losing
4224 will check out a clean copy of the original merge parent, losing
4225 all changes.
4225 all changes.
4226
4226
4227 Returns 0 on success, 1 if there are unresolved files.
4227 Returns 0 on success, 1 if there are unresolved files.
4228 """
4228 """
4229
4229
4230 if opts.get('rev') and node:
4230 if opts.get('rev') and node:
4231 raise util.Abort(_("please specify just one revision"))
4231 raise util.Abort(_("please specify just one revision"))
4232 if not node:
4232 if not node:
4233 node = opts.get('rev')
4233 node = opts.get('rev')
4234
4234
4235 if node:
4235 if node:
4236 node = scmutil.revsingle(repo, node).node()
4236 node = scmutil.revsingle(repo, node).node()
4237
4237
4238 if not node and repo._bookmarkcurrent:
4238 if not node and repo._bookmarkcurrent:
4239 bmheads = repo.bookmarkheads(repo._bookmarkcurrent)
4239 bmheads = repo.bookmarkheads(repo._bookmarkcurrent)
4240 curhead = repo[repo._bookmarkcurrent].node()
4240 curhead = repo[repo._bookmarkcurrent].node()
4241 if len(bmheads) == 2:
4241 if len(bmheads) == 2:
4242 if curhead == bmheads[0]:
4242 if curhead == bmheads[0]:
4243 node = bmheads[1]
4243 node = bmheads[1]
4244 else:
4244 else:
4245 node = bmheads[0]
4245 node = bmheads[0]
4246 elif len(bmheads) > 2:
4246 elif len(bmheads) > 2:
4247 raise util.Abort(_("multiple matching bookmarks to merge - "
4247 raise util.Abort(_("multiple matching bookmarks to merge - "
4248 "please merge with an explicit rev or bookmark"),
4248 "please merge with an explicit rev or bookmark"),
4249 hint=_("run 'hg heads' to see all heads"))
4249 hint=_("run 'hg heads' to see all heads"))
4250 elif len(bmheads) <= 1:
4250 elif len(bmheads) <= 1:
4251 raise util.Abort(_("no matching bookmark to merge - "
4251 raise util.Abort(_("no matching bookmark to merge - "
4252 "please merge with an explicit rev or bookmark"),
4252 "please merge with an explicit rev or bookmark"),
4253 hint=_("run 'hg heads' to see all heads"))
4253 hint=_("run 'hg heads' to see all heads"))
4254
4254
4255 if not node and not repo._bookmarkcurrent:
4255 if not node and not repo._bookmarkcurrent:
4256 branch = repo[None].branch()
4256 branch = repo[None].branch()
4257 bheads = repo.branchheads(branch)
4257 bheads = repo.branchheads(branch)
4258 nbhs = [bh for bh in bheads if not repo[bh].bookmarks()]
4258 nbhs = [bh for bh in bheads if not repo[bh].bookmarks()]
4259
4259
4260 if len(nbhs) > 2:
4260 if len(nbhs) > 2:
4261 raise util.Abort(_("branch '%s' has %d heads - "
4261 raise util.Abort(_("branch '%s' has %d heads - "
4262 "please merge with an explicit rev")
4262 "please merge with an explicit rev")
4263 % (branch, len(bheads)),
4263 % (branch, len(bheads)),
4264 hint=_("run 'hg heads .' to see heads"))
4264 hint=_("run 'hg heads .' to see heads"))
4265
4265
4266 parent = repo.dirstate.p1()
4266 parent = repo.dirstate.p1()
4267 if len(nbhs) <= 1:
4267 if len(nbhs) <= 1:
4268 if len(bheads) > 1:
4268 if len(bheads) > 1:
4269 raise util.Abort(_("heads are bookmarked - "
4269 raise util.Abort(_("heads are bookmarked - "
4270 "please merge with an explicit rev"),
4270 "please merge with an explicit rev"),
4271 hint=_("run 'hg heads' to see all heads"))
4271 hint=_("run 'hg heads' to see all heads"))
4272 if len(repo.heads()) > 1:
4272 if len(repo.heads()) > 1:
4273 raise util.Abort(_("branch '%s' has one head - "
4273 raise util.Abort(_("branch '%s' has one head - "
4274 "please merge with an explicit rev")
4274 "please merge with an explicit rev")
4275 % branch,
4275 % branch,
4276 hint=_("run 'hg heads' to see all heads"))
4276 hint=_("run 'hg heads' to see all heads"))
4277 msg, hint = _('nothing to merge'), None
4277 msg, hint = _('nothing to merge'), None
4278 if parent != repo.lookup(branch):
4278 if parent != repo.lookup(branch):
4279 hint = _("use 'hg update' instead")
4279 hint = _("use 'hg update' instead")
4280 raise util.Abort(msg, hint=hint)
4280 raise util.Abort(msg, hint=hint)
4281
4281
4282 if parent not in bheads:
4282 if parent not in bheads:
4283 raise util.Abort(_('working directory not at a head revision'),
4283 raise util.Abort(_('working directory not at a head revision'),
4284 hint=_("use 'hg update' or merge with an "
4284 hint=_("use 'hg update' or merge with an "
4285 "explicit revision"))
4285 "explicit revision"))
4286 if parent == nbhs[0]:
4286 if parent == nbhs[0]:
4287 node = nbhs[-1]
4287 node = nbhs[-1]
4288 else:
4288 else:
4289 node = nbhs[0]
4289 node = nbhs[0]
4290
4290
4291 if opts.get('preview'):
4291 if opts.get('preview'):
4292 # find nodes that are ancestors of p2 but not of p1
4292 # find nodes that are ancestors of p2 but not of p1
4293 p1 = repo.lookup('.')
4293 p1 = repo.lookup('.')
4294 p2 = repo.lookup(node)
4294 p2 = repo.lookup(node)
4295 nodes = repo.changelog.findmissing(common=[p1], heads=[p2])
4295 nodes = repo.changelog.findmissing(common=[p1], heads=[p2])
4296
4296
4297 displayer = cmdutil.show_changeset(ui, repo, opts)
4297 displayer = cmdutil.show_changeset(ui, repo, opts)
4298 for node in nodes:
4298 for node in nodes:
4299 displayer.show(repo[node])
4299 displayer.show(repo[node])
4300 displayer.close()
4300 displayer.close()
4301 return 0
4301 return 0
4302
4302
4303 try:
4303 try:
4304 # ui.forcemerge is an internal variable, do not document
4304 # ui.forcemerge is an internal variable, do not document
4305 repo.ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
4305 repo.ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
4306 return hg.merge(repo, node, force=opts.get('force'))
4306 return hg.merge(repo, node, force=opts.get('force'))
4307 finally:
4307 finally:
4308 ui.setconfig('ui', 'forcemerge', '')
4308 ui.setconfig('ui', 'forcemerge', '')
4309
4309
4310 @command('outgoing|out',
4310 @command('outgoing|out',
4311 [('f', 'force', None, _('run even when the destination is unrelated')),
4311 [('f', 'force', None, _('run even when the destination is unrelated')),
4312 ('r', 'rev', [],
4312 ('r', 'rev', [],
4313 _('a changeset intended to be included in the destination'), _('REV')),
4313 _('a changeset intended to be included in the destination'), _('REV')),
4314 ('n', 'newest-first', None, _('show newest record first')),
4314 ('n', 'newest-first', None, _('show newest record first')),
4315 ('B', 'bookmarks', False, _('compare bookmarks')),
4315 ('B', 'bookmarks', False, _('compare bookmarks')),
4316 ('b', 'branch', [], _('a specific branch you would like to push'),
4316 ('b', 'branch', [], _('a specific branch you would like to push'),
4317 _('BRANCH')),
4317 _('BRANCH')),
4318 ] + logopts + remoteopts + subrepoopts,
4318 ] + logopts + remoteopts + subrepoopts,
4319 _('[-M] [-p] [-n] [-f] [-r REV]... [DEST]'))
4319 _('[-M] [-p] [-n] [-f] [-r REV]... [DEST]'))
4320 def outgoing(ui, repo, dest=None, **opts):
4320 def outgoing(ui, repo, dest=None, **opts):
4321 """show changesets not found in the destination
4321 """show changesets not found in the destination
4322
4322
4323 Show changesets not found in the specified destination repository
4323 Show changesets not found in the specified destination repository
4324 or the default push location. These are the changesets that would
4324 or the default push location. These are the changesets that would
4325 be pushed if a push was requested.
4325 be pushed if a push was requested.
4326
4326
4327 See pull for details of valid destination formats.
4327 See pull for details of valid destination formats.
4328
4328
4329 Returns 0 if there are outgoing changes, 1 otherwise.
4329 Returns 0 if there are outgoing changes, 1 otherwise.
4330 """
4330 """
4331 if opts.get('graph'):
4331 if opts.get('graph'):
4332 cmdutil.checkunsupportedgraphflags([], opts)
4332 cmdutil.checkunsupportedgraphflags([], opts)
4333 o = hg._outgoing(ui, repo, dest, opts)
4333 o = hg._outgoing(ui, repo, dest, opts)
4334 if o is None:
4334 if o is None:
4335 return
4335 return
4336
4336
4337 revdag = cmdutil.graphrevs(repo, o, opts)
4337 revdag = cmdutil.graphrevs(repo, o, opts)
4338 displayer = cmdutil.show_changeset(ui, repo, opts, buffered=True)
4338 displayer = cmdutil.show_changeset(ui, repo, opts, buffered=True)
4339 showparents = [ctx.node() for ctx in repo[None].parents()]
4339 showparents = [ctx.node() for ctx in repo[None].parents()]
4340 cmdutil.displaygraph(ui, revdag, displayer, showparents,
4340 cmdutil.displaygraph(ui, revdag, displayer, showparents,
4341 graphmod.asciiedges)
4341 graphmod.asciiedges)
4342 return 0
4342 return 0
4343
4343
4344 if opts.get('bookmarks'):
4344 if opts.get('bookmarks'):
4345 dest = ui.expandpath(dest or 'default-push', dest or 'default')
4345 dest = ui.expandpath(dest or 'default-push', dest or 'default')
4346 dest, branches = hg.parseurl(dest, opts.get('branch'))
4346 dest, branches = hg.parseurl(dest, opts.get('branch'))
4347 other = hg.peer(repo, opts, dest)
4347 other = hg.peer(repo, opts, dest)
4348 if 'bookmarks' not in other.listkeys('namespaces'):
4348 if 'bookmarks' not in other.listkeys('namespaces'):
4349 ui.warn(_("remote doesn't support bookmarks\n"))
4349 ui.warn(_("remote doesn't support bookmarks\n"))
4350 return 0
4350 return 0
4351 ui.status(_('comparing with %s\n') % util.hidepassword(dest))
4351 ui.status(_('comparing with %s\n') % util.hidepassword(dest))
4352 return bookmarks.diff(ui, other, repo)
4352 return bookmarks.diff(ui, other, repo)
4353
4353
4354 repo._subtoppath = ui.expandpath(dest or 'default-push', dest or 'default')
4354 repo._subtoppath = ui.expandpath(dest or 'default-push', dest or 'default')
4355 try:
4355 try:
4356 return hg.outgoing(ui, repo, dest, opts)
4356 return hg.outgoing(ui, repo, dest, opts)
4357 finally:
4357 finally:
4358 del repo._subtoppath
4358 del repo._subtoppath
4359
4359
4360 @command('parents',
4360 @command('parents',
4361 [('r', 'rev', '', _('show parents of the specified revision'), _('REV')),
4361 [('r', 'rev', '', _('show parents of the specified revision'), _('REV')),
4362 ] + templateopts,
4362 ] + templateopts,
4363 _('[-r REV] [FILE]'))
4363 _('[-r REV] [FILE]'))
4364 def parents(ui, repo, file_=None, **opts):
4364 def parents(ui, repo, file_=None, **opts):
4365 """show the parents of the working directory or revision
4365 """show the parents of the working directory or revision
4366
4366
4367 Print the working directory's parent revisions. If a revision is
4367 Print the working directory's parent revisions. If a revision is
4368 given via -r/--rev, the parent of that revision will be printed.
4368 given via -r/--rev, the parent of that revision will be printed.
4369 If a file argument is given, the revision in which the file was
4369 If a file argument is given, the revision in which the file was
4370 last changed (before the working directory revision or the
4370 last changed (before the working directory revision or the
4371 argument to --rev if given) is printed.
4371 argument to --rev if given) is printed.
4372
4372
4373 Returns 0 on success.
4373 Returns 0 on success.
4374 """
4374 """
4375
4375
4376 ctx = scmutil.revsingle(repo, opts.get('rev'), None)
4376 ctx = scmutil.revsingle(repo, opts.get('rev'), None)
4377
4377
4378 if file_:
4378 if file_:
4379 m = scmutil.match(ctx, (file_,), opts)
4379 m = scmutil.match(ctx, (file_,), opts)
4380 if m.anypats() or len(m.files()) != 1:
4380 if m.anypats() or len(m.files()) != 1:
4381 raise util.Abort(_('can only specify an explicit filename'))
4381 raise util.Abort(_('can only specify an explicit filename'))
4382 file_ = m.files()[0]
4382 file_ = m.files()[0]
4383 filenodes = []
4383 filenodes = []
4384 for cp in ctx.parents():
4384 for cp in ctx.parents():
4385 if not cp:
4385 if not cp:
4386 continue
4386 continue
4387 try:
4387 try:
4388 filenodes.append(cp.filenode(file_))
4388 filenodes.append(cp.filenode(file_))
4389 except error.LookupError:
4389 except error.LookupError:
4390 pass
4390 pass
4391 if not filenodes:
4391 if not filenodes:
4392 raise util.Abort(_("'%s' not found in manifest!") % file_)
4392 raise util.Abort(_("'%s' not found in manifest!") % file_)
4393 p = []
4393 p = []
4394 for fn in filenodes:
4394 for fn in filenodes:
4395 fctx = repo.filectx(file_, fileid=fn)
4395 fctx = repo.filectx(file_, fileid=fn)
4396 p.append(fctx.node())
4396 p.append(fctx.node())
4397 else:
4397 else:
4398 p = [cp.node() for cp in ctx.parents()]
4398 p = [cp.node() for cp in ctx.parents()]
4399
4399
4400 displayer = cmdutil.show_changeset(ui, repo, opts)
4400 displayer = cmdutil.show_changeset(ui, repo, opts)
4401 for n in p:
4401 for n in p:
4402 if n != nullid:
4402 if n != nullid:
4403 displayer.show(repo[n])
4403 displayer.show(repo[n])
4404 displayer.close()
4404 displayer.close()
4405
4405
4406 @command('paths', [], _('[NAME]'))
4406 @command('paths', [], _('[NAME]'))
4407 def paths(ui, repo, search=None):
4407 def paths(ui, repo, search=None):
4408 """show aliases for remote repositories
4408 """show aliases for remote repositories
4409
4409
4410 Show definition of symbolic path name NAME. If no name is given,
4410 Show definition of symbolic path name NAME. If no name is given,
4411 show definition of all available names.
4411 show definition of all available names.
4412
4412
4413 Option -q/--quiet suppresses all output when searching for NAME
4413 Option -q/--quiet suppresses all output when searching for NAME
4414 and shows only the path names when listing all definitions.
4414 and shows only the path names when listing all definitions.
4415
4415
4416 Path names are defined in the [paths] section of your
4416 Path names are defined in the [paths] section of your
4417 configuration file and in ``/etc/mercurial/hgrc``. If run inside a
4417 configuration file and in ``/etc/mercurial/hgrc``. If run inside a
4418 repository, ``.hg/hgrc`` is used, too.
4418 repository, ``.hg/hgrc`` is used, too.
4419
4419
4420 The path names ``default`` and ``default-push`` have a special
4420 The path names ``default`` and ``default-push`` have a special
4421 meaning. When performing a push or pull operation, they are used
4421 meaning. When performing a push or pull operation, they are used
4422 as fallbacks if no location is specified on the command-line.
4422 as fallbacks if no location is specified on the command-line.
4423 When ``default-push`` is set, it will be used for push and
4423 When ``default-push`` is set, it will be used for push and
4424 ``default`` will be used for pull; otherwise ``default`` is used
4424 ``default`` will be used for pull; otherwise ``default`` is used
4425 as the fallback for both. When cloning a repository, the clone
4425 as the fallback for both. When cloning a repository, the clone
4426 source is written as ``default`` in ``.hg/hgrc``. Note that
4426 source is written as ``default`` in ``.hg/hgrc``. Note that
4427 ``default`` and ``default-push`` apply to all inbound (e.g.
4427 ``default`` and ``default-push`` apply to all inbound (e.g.
4428 :hg:`incoming`) and outbound (e.g. :hg:`outgoing`, :hg:`email` and
4428 :hg:`incoming`) and outbound (e.g. :hg:`outgoing`, :hg:`email` and
4429 :hg:`bundle`) operations.
4429 :hg:`bundle`) operations.
4430
4430
4431 See :hg:`help urls` for more information.
4431 See :hg:`help urls` for more information.
4432
4432
4433 Returns 0 on success.
4433 Returns 0 on success.
4434 """
4434 """
4435 if search:
4435 if search:
4436 for name, path in ui.configitems("paths"):
4436 for name, path in ui.configitems("paths"):
4437 if name == search:
4437 if name == search:
4438 ui.status("%s\n" % util.hidepassword(path))
4438 ui.status("%s\n" % util.hidepassword(path))
4439 return
4439 return
4440 if not ui.quiet:
4440 if not ui.quiet:
4441 ui.warn(_("not found!\n"))
4441 ui.warn(_("not found!\n"))
4442 return 1
4442 return 1
4443 else:
4443 else:
4444 for name, path in ui.configitems("paths"):
4444 for name, path in ui.configitems("paths"):
4445 if ui.quiet:
4445 if ui.quiet:
4446 ui.write("%s\n" % name)
4446 ui.write("%s\n" % name)
4447 else:
4447 else:
4448 ui.write("%s = %s\n" % (name, util.hidepassword(path)))
4448 ui.write("%s = %s\n" % (name, util.hidepassword(path)))
4449
4449
4450 @command('phase',
4450 @command('phase',
4451 [('p', 'public', False, _('set changeset phase to public')),
4451 [('p', 'public', False, _('set changeset phase to public')),
4452 ('d', 'draft', False, _('set changeset phase to draft')),
4452 ('d', 'draft', False, _('set changeset phase to draft')),
4453 ('s', 'secret', False, _('set changeset phase to secret')),
4453 ('s', 'secret', False, _('set changeset phase to secret')),
4454 ('f', 'force', False, _('allow to move boundary backward')),
4454 ('f', 'force', False, _('allow to move boundary backward')),
4455 ('r', 'rev', [], _('target revision'), _('REV')),
4455 ('r', 'rev', [], _('target revision'), _('REV')),
4456 ],
4456 ],
4457 _('[-p|-d|-s] [-f] [-r] REV...'))
4457 _('[-p|-d|-s] [-f] [-r] REV...'))
4458 def phase(ui, repo, *revs, **opts):
4458 def phase(ui, repo, *revs, **opts):
4459 """set or show the current phase name
4459 """set or show the current phase name
4460
4460
4461 With no argument, show the phase name of specified revisions.
4461 With no argument, show the phase name of specified revisions.
4462
4462
4463 With one of -p/--public, -d/--draft or -s/--secret, change the
4463 With one of -p/--public, -d/--draft or -s/--secret, change the
4464 phase value of the specified revisions.
4464 phase value of the specified revisions.
4465
4465
4466 Unless -f/--force is specified, :hg:`phase` won't move changeset from a
4466 Unless -f/--force is specified, :hg:`phase` won't move changeset from a
4467 lower phase to an higher phase. Phases are ordered as follows::
4467 lower phase to an higher phase. Phases are ordered as follows::
4468
4468
4469 public < draft < secret
4469 public < draft < secret
4470
4470
4471 Returns 0 on success, 1 if no phases were changed or some could not
4471 Returns 0 on success, 1 if no phases were changed or some could not
4472 be changed.
4472 be changed.
4473 """
4473 """
4474 # search for a unique phase argument
4474 # search for a unique phase argument
4475 targetphase = None
4475 targetphase = None
4476 for idx, name in enumerate(phases.phasenames):
4476 for idx, name in enumerate(phases.phasenames):
4477 if opts[name]:
4477 if opts[name]:
4478 if targetphase is not None:
4478 if targetphase is not None:
4479 raise util.Abort(_('only one phase can be specified'))
4479 raise util.Abort(_('only one phase can be specified'))
4480 targetphase = idx
4480 targetphase = idx
4481
4481
4482 # look for specified revision
4482 # look for specified revision
4483 revs = list(revs)
4483 revs = list(revs)
4484 revs.extend(opts['rev'])
4484 revs.extend(opts['rev'])
4485 if not revs:
4485 if not revs:
4486 raise util.Abort(_('no revisions specified'))
4486 raise util.Abort(_('no revisions specified'))
4487
4487
4488 revs = scmutil.revrange(repo, revs)
4488 revs = scmutil.revrange(repo, revs)
4489
4489
4490 lock = None
4490 lock = None
4491 ret = 0
4491 ret = 0
4492 if targetphase is None:
4492 if targetphase is None:
4493 # display
4493 # display
4494 for r in revs:
4494 for r in revs:
4495 ctx = repo[r]
4495 ctx = repo[r]
4496 ui.write('%i: %s\n' % (ctx.rev(), ctx.phasestr()))
4496 ui.write('%i: %s\n' % (ctx.rev(), ctx.phasestr()))
4497 else:
4497 else:
4498 lock = repo.lock()
4498 lock = repo.lock()
4499 try:
4499 try:
4500 # set phase
4500 # set phase
4501 if not revs:
4501 if not revs:
4502 raise util.Abort(_('empty revision set'))
4502 raise util.Abort(_('empty revision set'))
4503 nodes = [repo[r].node() for r in revs]
4503 nodes = [repo[r].node() for r in revs]
4504 olddata = repo._phasecache.getphaserevs(repo)[:]
4504 olddata = repo._phasecache.getphaserevs(repo)[:]
4505 phases.advanceboundary(repo, targetphase, nodes)
4505 phases.advanceboundary(repo, targetphase, nodes)
4506 if opts['force']:
4506 if opts['force']:
4507 phases.retractboundary(repo, targetphase, nodes)
4507 phases.retractboundary(repo, targetphase, nodes)
4508 finally:
4508 finally:
4509 lock.release()
4509 lock.release()
4510 # moving revision from public to draft may hide them
4510 # moving revision from public to draft may hide them
4511 # We have to check result on an unfiltered repository
4511 # We have to check result on an unfiltered repository
4512 unfi = repo.unfiltered()
4512 unfi = repo.unfiltered()
4513 newdata = repo._phasecache.getphaserevs(unfi)
4513 newdata = repo._phasecache.getphaserevs(unfi)
4514 changes = sum(o != newdata[i] for i, o in enumerate(olddata))
4514 changes = sum(o != newdata[i] for i, o in enumerate(olddata))
4515 cl = unfi.changelog
4515 cl = unfi.changelog
4516 rejected = [n for n in nodes
4516 rejected = [n for n in nodes
4517 if newdata[cl.rev(n)] < targetphase]
4517 if newdata[cl.rev(n)] < targetphase]
4518 if rejected:
4518 if rejected:
4519 ui.warn(_('cannot move %i changesets to a higher '
4519 ui.warn(_('cannot move %i changesets to a higher '
4520 'phase, use --force\n') % len(rejected))
4520 'phase, use --force\n') % len(rejected))
4521 ret = 1
4521 ret = 1
4522 if changes:
4522 if changes:
4523 msg = _('phase changed for %i changesets\n') % changes
4523 msg = _('phase changed for %i changesets\n') % changes
4524 if ret:
4524 if ret:
4525 ui.status(msg)
4525 ui.status(msg)
4526 else:
4526 else:
4527 ui.note(msg)
4527 ui.note(msg)
4528 else:
4528 else:
4529 ui.warn(_('no phases changed\n'))
4529 ui.warn(_('no phases changed\n'))
4530 ret = 1
4530 ret = 1
4531 return ret
4531 return ret
4532
4532
4533 def postincoming(ui, repo, modheads, optupdate, checkout):
4533 def postincoming(ui, repo, modheads, optupdate, checkout):
4534 if modheads == 0:
4534 if modheads == 0:
4535 return
4535 return
4536 if optupdate:
4536 if optupdate:
4537 checkout, movemarkfrom = bookmarks.calculateupdate(ui, repo, checkout)
4537 checkout, movemarkfrom = bookmarks.calculateupdate(ui, repo, checkout)
4538 try:
4538 try:
4539 ret = hg.update(repo, checkout)
4539 ret = hg.update(repo, checkout)
4540 except util.Abort, inst:
4540 except util.Abort, inst:
4541 ui.warn(_("not updating: %s\n") % str(inst))
4541 ui.warn(_("not updating: %s\n") % str(inst))
4542 if inst.hint:
4542 if inst.hint:
4543 ui.warn(_("(%s)\n") % inst.hint)
4543 ui.warn(_("(%s)\n") % inst.hint)
4544 return 0
4544 return 0
4545 if not ret and not checkout:
4545 if not ret and not checkout:
4546 if bookmarks.update(repo, [movemarkfrom], repo['.'].node()):
4546 if bookmarks.update(repo, [movemarkfrom], repo['.'].node()):
4547 ui.status(_("updating bookmark %s\n") % repo._bookmarkcurrent)
4547 ui.status(_("updating bookmark %s\n") % repo._bookmarkcurrent)
4548 return ret
4548 return ret
4549 if modheads > 1:
4549 if modheads > 1:
4550 currentbranchheads = len(repo.branchheads())
4550 currentbranchheads = len(repo.branchheads())
4551 if currentbranchheads == modheads:
4551 if currentbranchheads == modheads:
4552 ui.status(_("(run 'hg heads' to see heads, 'hg merge' to merge)\n"))
4552 ui.status(_("(run 'hg heads' to see heads, 'hg merge' to merge)\n"))
4553 elif currentbranchheads > 1:
4553 elif currentbranchheads > 1:
4554 ui.status(_("(run 'hg heads .' to see heads, 'hg merge' to "
4554 ui.status(_("(run 'hg heads .' to see heads, 'hg merge' to "
4555 "merge)\n"))
4555 "merge)\n"))
4556 else:
4556 else:
4557 ui.status(_("(run 'hg heads' to see heads)\n"))
4557 ui.status(_("(run 'hg heads' to see heads)\n"))
4558 else:
4558 else:
4559 ui.status(_("(run 'hg update' to get a working copy)\n"))
4559 ui.status(_("(run 'hg update' to get a working copy)\n"))
4560
4560
4561 @command('^pull',
4561 @command('^pull',
4562 [('u', 'update', None,
4562 [('u', 'update', None,
4563 _('update to new branch head if changesets were pulled')),
4563 _('update to new branch head if changesets were pulled')),
4564 ('f', 'force', None, _('run even when remote repository is unrelated')),
4564 ('f', 'force', None, _('run even when remote repository is unrelated')),
4565 ('r', 'rev', [], _('a remote changeset intended to be added'), _('REV')),
4565 ('r', 'rev', [], _('a remote changeset intended to be added'), _('REV')),
4566 ('B', 'bookmark', [], _("bookmark to pull"), _('BOOKMARK')),
4566 ('B', 'bookmark', [], _("bookmark to pull"), _('BOOKMARK')),
4567 ('b', 'branch', [], _('a specific branch you would like to pull'),
4567 ('b', 'branch', [], _('a specific branch you would like to pull'),
4568 _('BRANCH')),
4568 _('BRANCH')),
4569 ] + remoteopts,
4569 ] + remoteopts,
4570 _('[-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]'))
4570 _('[-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]'))
4571 def pull(ui, repo, source="default", **opts):
4571 def pull(ui, repo, source="default", **opts):
4572 """pull changes from the specified source
4572 """pull changes from the specified source
4573
4573
4574 Pull changes from a remote repository to a local one.
4574 Pull changes from a remote repository to a local one.
4575
4575
4576 This finds all changes from the repository at the specified path
4576 This finds all changes from the repository at the specified path
4577 or URL and adds them to a local repository (the current one unless
4577 or URL and adds them to a local repository (the current one unless
4578 -R is specified). By default, this does not update the copy of the
4578 -R is specified). By default, this does not update the copy of the
4579 project in the working directory.
4579 project in the working directory.
4580
4580
4581 Use :hg:`incoming` if you want to see what would have been added
4581 Use :hg:`incoming` if you want to see what would have been added
4582 by a pull at the time you issued this command. If you then decide
4582 by a pull at the time you issued this command. If you then decide
4583 to add those changes to the repository, you should use :hg:`pull
4583 to add those changes to the repository, you should use :hg:`pull
4584 -r X` where ``X`` is the last changeset listed by :hg:`incoming`.
4584 -r X` where ``X`` is the last changeset listed by :hg:`incoming`.
4585
4585
4586 If SOURCE is omitted, the 'default' path will be used.
4586 If SOURCE is omitted, the 'default' path will be used.
4587 See :hg:`help urls` for more information.
4587 See :hg:`help urls` for more information.
4588
4588
4589 Returns 0 on success, 1 if an update had unresolved files.
4589 Returns 0 on success, 1 if an update had unresolved files.
4590 """
4590 """
4591 source, branches = hg.parseurl(ui.expandpath(source), opts.get('branch'))
4591 source, branches = hg.parseurl(ui.expandpath(source), opts.get('branch'))
4592 other = hg.peer(repo, opts, source)
4592 other = hg.peer(repo, opts, source)
4593 try:
4593 try:
4594 ui.status(_('pulling from %s\n') % util.hidepassword(source))
4594 ui.status(_('pulling from %s\n') % util.hidepassword(source))
4595 revs, checkout = hg.addbranchrevs(repo, other, branches,
4595 revs, checkout = hg.addbranchrevs(repo, other, branches,
4596 opts.get('rev'))
4596 opts.get('rev'))
4597
4597
4598 remotebookmarks = other.listkeys('bookmarks')
4598 remotebookmarks = other.listkeys('bookmarks')
4599
4599
4600 if opts.get('bookmark'):
4600 if opts.get('bookmark'):
4601 if not revs:
4601 if not revs:
4602 revs = []
4602 revs = []
4603 for b in opts['bookmark']:
4603 for b in opts['bookmark']:
4604 if b not in remotebookmarks:
4604 if b not in remotebookmarks:
4605 raise util.Abort(_('remote bookmark %s not found!') % b)
4605 raise util.Abort(_('remote bookmark %s not found!') % b)
4606 revs.append(remotebookmarks[b])
4606 revs.append(remotebookmarks[b])
4607
4607
4608 if revs:
4608 if revs:
4609 try:
4609 try:
4610 revs = [other.lookup(rev) for rev in revs]
4610 revs = [other.lookup(rev) for rev in revs]
4611 except error.CapabilityError:
4611 except error.CapabilityError:
4612 err = _("other repository doesn't support revision lookup, "
4612 err = _("other repository doesn't support revision lookup, "
4613 "so a rev cannot be specified.")
4613 "so a rev cannot be specified.")
4614 raise util.Abort(err)
4614 raise util.Abort(err)
4615
4615
4616 modheads = repo.pull(other, heads=revs, force=opts.get('force'))
4616 modheads = repo.pull(other, heads=revs, force=opts.get('force'))
4617 bookmarks.updatefromremote(ui, repo, remotebookmarks, source)
4617 bookmarks.updatefromremote(ui, repo, remotebookmarks, source)
4618 if checkout:
4618 if checkout:
4619 checkout = str(repo.changelog.rev(other.lookup(checkout)))
4619 checkout = str(repo.changelog.rev(other.lookup(checkout)))
4620 repo._subtoppath = source
4620 repo._subtoppath = source
4621 try:
4621 try:
4622 ret = postincoming(ui, repo, modheads, opts.get('update'), checkout)
4622 ret = postincoming(ui, repo, modheads, opts.get('update'), checkout)
4623
4623
4624 finally:
4624 finally:
4625 del repo._subtoppath
4625 del repo._subtoppath
4626
4626
4627 # update specified bookmarks
4627 # update specified bookmarks
4628 if opts.get('bookmark'):
4628 if opts.get('bookmark'):
4629 marks = repo._bookmarks
4629 marks = repo._bookmarks
4630 for b in opts['bookmark']:
4630 for b in opts['bookmark']:
4631 # explicit pull overrides local bookmark if any
4631 # explicit pull overrides local bookmark if any
4632 ui.status(_("importing bookmark %s\n") % b)
4632 ui.status(_("importing bookmark %s\n") % b)
4633 marks[b] = repo[remotebookmarks[b]].node()
4633 marks[b] = repo[remotebookmarks[b]].node()
4634 marks.write()
4634 marks.write()
4635 finally:
4635 finally:
4636 other.close()
4636 other.close()
4637 return ret
4637 return ret
4638
4638
4639 @command('^push',
4639 @command('^push',
4640 [('f', 'force', None, _('force push')),
4640 [('f', 'force', None, _('force push')),
4641 ('r', 'rev', [],
4641 ('r', 'rev', [],
4642 _('a changeset intended to be included in the destination'),
4642 _('a changeset intended to be included in the destination'),
4643 _('REV')),
4643 _('REV')),
4644 ('B', 'bookmark', [], _("bookmark to push"), _('BOOKMARK')),
4644 ('B', 'bookmark', [], _("bookmark to push"), _('BOOKMARK')),
4645 ('b', 'branch', [],
4645 ('b', 'branch', [],
4646 _('a specific branch you would like to push'), _('BRANCH')),
4646 _('a specific branch you would like to push'), _('BRANCH')),
4647 ('', 'new-branch', False, _('allow pushing a new branch')),
4647 ('', 'new-branch', False, _('allow pushing a new branch')),
4648 ] + remoteopts,
4648 ] + remoteopts,
4649 _('[-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]'))
4649 _('[-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]'))
4650 def push(ui, repo, dest=None, **opts):
4650 def push(ui, repo, dest=None, **opts):
4651 """push changes to the specified destination
4651 """push changes to the specified destination
4652
4652
4653 Push changesets from the local repository to the specified
4653 Push changesets from the local repository to the specified
4654 destination.
4654 destination.
4655
4655
4656 This operation is symmetrical to pull: it is identical to a pull
4656 This operation is symmetrical to pull: it is identical to a pull
4657 in the destination repository from the current one.
4657 in the destination repository from the current one.
4658
4658
4659 By default, push will not allow creation of new heads at the
4659 By default, push will not allow creation of new heads at the
4660 destination, since multiple heads would make it unclear which head
4660 destination, since multiple heads would make it unclear which head
4661 to use. In this situation, it is recommended to pull and merge
4661 to use. In this situation, it is recommended to pull and merge
4662 before pushing.
4662 before pushing.
4663
4663
4664 Use --new-branch if you want to allow push to create a new named
4664 Use --new-branch if you want to allow push to create a new named
4665 branch that is not present at the destination. This allows you to
4665 branch that is not present at the destination. This allows you to
4666 only create a new branch without forcing other changes.
4666 only create a new branch without forcing other changes.
4667
4667
4668 .. note::
4668 .. note::
4669
4669
4670 Extra care should be taken with the -f/--force option,
4670 Extra care should be taken with the -f/--force option,
4671 which will push all new heads on all branches, an action which will
4671 which will push all new heads on all branches, an action which will
4672 almost always cause confusion for collaborators.
4672 almost always cause confusion for collaborators.
4673
4673
4674 If -r/--rev is used, the specified revision and all its ancestors
4674 If -r/--rev is used, the specified revision and all its ancestors
4675 will be pushed to the remote repository.
4675 will be pushed to the remote repository.
4676
4676
4677 If -B/--bookmark is used, the specified bookmarked revision, its
4677 If -B/--bookmark is used, the specified bookmarked revision, its
4678 ancestors, and the bookmark will be pushed to the remote
4678 ancestors, and the bookmark will be pushed to the remote
4679 repository.
4679 repository.
4680
4680
4681 Please see :hg:`help urls` for important details about ``ssh://``
4681 Please see :hg:`help urls` for important details about ``ssh://``
4682 URLs. If DESTINATION is omitted, a default path will be used.
4682 URLs. If DESTINATION is omitted, a default path will be used.
4683
4683
4684 Returns 0 if push was successful, 1 if nothing to push.
4684 Returns 0 if push was successful, 1 if nothing to push.
4685 """
4685 """
4686
4686
4687 if opts.get('bookmark'):
4687 if opts.get('bookmark'):
4688 ui.setconfig('bookmarks', 'pushing', opts['bookmark'])
4688 ui.setconfig('bookmarks', 'pushing', opts['bookmark'])
4689 for b in opts['bookmark']:
4689 for b in opts['bookmark']:
4690 # translate -B options to -r so changesets get pushed
4690 # translate -B options to -r so changesets get pushed
4691 if b in repo._bookmarks:
4691 if b in repo._bookmarks:
4692 opts.setdefault('rev', []).append(b)
4692 opts.setdefault('rev', []).append(b)
4693 else:
4693 else:
4694 # if we try to push a deleted bookmark, translate it to null
4694 # if we try to push a deleted bookmark, translate it to null
4695 # this lets simultaneous -r, -b options continue working
4695 # this lets simultaneous -r, -b options continue working
4696 opts.setdefault('rev', []).append("null")
4696 opts.setdefault('rev', []).append("null")
4697
4697
4698 dest = ui.expandpath(dest or 'default-push', dest or 'default')
4698 dest = ui.expandpath(dest or 'default-push', dest or 'default')
4699 dest, branches = hg.parseurl(dest, opts.get('branch'))
4699 dest, branches = hg.parseurl(dest, opts.get('branch'))
4700 ui.status(_('pushing to %s\n') % util.hidepassword(dest))
4700 ui.status(_('pushing to %s\n') % util.hidepassword(dest))
4701 revs, checkout = hg.addbranchrevs(repo, repo, branches, opts.get('rev'))
4701 revs, checkout = hg.addbranchrevs(repo, repo, branches, opts.get('rev'))
4702 try:
4702 try:
4703 other = hg.peer(repo, opts, dest)
4703 other = hg.peer(repo, opts, dest)
4704 except error.RepoError:
4704 except error.RepoError:
4705 if dest == "default-push":
4705 if dest == "default-push":
4706 raise util.Abort(_("default repository not configured!"),
4706 raise util.Abort(_("default repository not configured!"),
4707 hint=_('see the "path" section in "hg help config"'))
4707 hint=_('see the "path" section in "hg help config"'))
4708 else:
4708 else:
4709 raise
4709 raise
4710
4710
4711 if revs:
4711 if revs:
4712 revs = [repo.lookup(r) for r in scmutil.revrange(repo, revs)]
4712 revs = [repo.lookup(r) for r in scmutil.revrange(repo, revs)]
4713
4713
4714 repo._subtoppath = dest
4714 repo._subtoppath = dest
4715 try:
4715 try:
4716 # push subrepos depth-first for coherent ordering
4716 # push subrepos depth-first for coherent ordering
4717 c = repo['']
4717 c = repo['']
4718 subs = c.substate # only repos that are committed
4718 subs = c.substate # only repos that are committed
4719 for s in sorted(subs):
4719 for s in sorted(subs):
4720 if c.sub(s).push(opts) == 0:
4720 if c.sub(s).push(opts) == 0:
4721 return False
4721 return False
4722 finally:
4722 finally:
4723 del repo._subtoppath
4723 del repo._subtoppath
4724 result = repo.push(other, opts.get('force'), revs=revs,
4724 result = repo.push(other, opts.get('force'), revs=revs,
4725 newbranch=opts.get('new_branch'))
4725 newbranch=opts.get('new_branch'))
4726
4726
4727 result = not result
4727 result = not result
4728
4728
4729 if opts.get('bookmark'):
4729 if opts.get('bookmark'):
4730 bresult = bookmarks.pushtoremote(ui, repo, other, opts['bookmark'])
4730 bresult = bookmarks.pushtoremote(ui, repo, other, opts['bookmark'])
4731 if bresult == 2:
4731 if bresult == 2:
4732 return 2
4732 return 2
4733 if not result and bresult:
4733 if not result and bresult:
4734 result = 2
4734 result = 2
4735
4735
4736 return result
4736 return result
4737
4737
4738 @command('recover', [])
4738 @command('recover', [])
4739 def recover(ui, repo):
4739 def recover(ui, repo):
4740 """roll back an interrupted transaction
4740 """roll back an interrupted transaction
4741
4741
4742 Recover from an interrupted commit or pull.
4742 Recover from an interrupted commit or pull.
4743
4743
4744 This command tries to fix the repository status after an
4744 This command tries to fix the repository status after an
4745 interrupted operation. It should only be necessary when Mercurial
4745 interrupted operation. It should only be necessary when Mercurial
4746 suggests it.
4746 suggests it.
4747
4747
4748 Returns 0 if successful, 1 if nothing to recover or verify fails.
4748 Returns 0 if successful, 1 if nothing to recover or verify fails.
4749 """
4749 """
4750 if repo.recover():
4750 if repo.recover():
4751 return hg.verify(repo)
4751 return hg.verify(repo)
4752 return 1
4752 return 1
4753
4753
4754 @command('^remove|rm',
4754 @command('^remove|rm',
4755 [('A', 'after', None, _('record delete for missing files')),
4755 [('A', 'after', None, _('record delete for missing files')),
4756 ('f', 'force', None,
4756 ('f', 'force', None,
4757 _('remove (and delete) file even if added or modified')),
4757 _('remove (and delete) file even if added or modified')),
4758 ] + walkopts,
4758 ] + walkopts,
4759 _('[OPTION]... FILE...'))
4759 _('[OPTION]... FILE...'))
4760 def remove(ui, repo, *pats, **opts):
4760 def remove(ui, repo, *pats, **opts):
4761 """remove the specified files on the next commit
4761 """remove the specified files on the next commit
4762
4762
4763 Schedule the indicated files for removal from the current branch.
4763 Schedule the indicated files for removal from the current branch.
4764
4764
4765 This command schedules the files to be removed at the next commit.
4765 This command schedules the files to be removed at the next commit.
4766 To undo a remove before that, see :hg:`revert`. To undo added
4766 To undo a remove before that, see :hg:`revert`. To undo added
4767 files, see :hg:`forget`.
4767 files, see :hg:`forget`.
4768
4768
4769 .. container:: verbose
4769 .. container:: verbose
4770
4770
4771 -A/--after can be used to remove only files that have already
4771 -A/--after can be used to remove only files that have already
4772 been deleted, -f/--force can be used to force deletion, and -Af
4772 been deleted, -f/--force can be used to force deletion, and -Af
4773 can be used to remove files from the next revision without
4773 can be used to remove files from the next revision without
4774 deleting them from the working directory.
4774 deleting them from the working directory.
4775
4775
4776 The following table details the behavior of remove for different
4776 The following table details the behavior of remove for different
4777 file states (columns) and option combinations (rows). The file
4777 file states (columns) and option combinations (rows). The file
4778 states are Added [A], Clean [C], Modified [M] and Missing [!]
4778 states are Added [A], Clean [C], Modified [M] and Missing [!]
4779 (as reported by :hg:`status`). The actions are Warn, Remove
4779 (as reported by :hg:`status`). The actions are Warn, Remove
4780 (from branch) and Delete (from disk):
4780 (from branch) and Delete (from disk):
4781
4781
4782 ========= == == == ==
4782 ========= == == == ==
4783 opt/state A C M !
4783 opt/state A C M !
4784 ========= == == == ==
4784 ========= == == == ==
4785 none W RD W R
4785 none W RD W R
4786 -f R RD RD R
4786 -f R RD RD R
4787 -A W W W R
4787 -A W W W R
4788 -Af R R R R
4788 -Af R R R R
4789 ========= == == == ==
4789 ========= == == == ==
4790
4790
4791 Note that remove never deletes files in Added [A] state from the
4791 Note that remove never deletes files in Added [A] state from the
4792 working directory, not even if option --force is specified.
4792 working directory, not even if option --force is specified.
4793
4793
4794 Returns 0 on success, 1 if any warnings encountered.
4794 Returns 0 on success, 1 if any warnings encountered.
4795 """
4795 """
4796
4796
4797 ret = 0
4797 ret = 0
4798 after, force = opts.get('after'), opts.get('force')
4798 after, force = opts.get('after'), opts.get('force')
4799 if not pats and not after:
4799 if not pats and not after:
4800 raise util.Abort(_('no files specified'))
4800 raise util.Abort(_('no files specified'))
4801
4801
4802 m = scmutil.match(repo[None], pats, opts)
4802 m = scmutil.match(repo[None], pats, opts)
4803 s = repo.status(match=m, clean=True)
4803 s = repo.status(match=m, clean=True)
4804 modified, added, deleted, clean = s[0], s[1], s[3], s[6]
4804 modified, added, deleted, clean = s[0], s[1], s[3], s[6]
4805
4805
4806 # warn about failure to delete explicit files/dirs
4806 # warn about failure to delete explicit files/dirs
4807 wctx = repo[None]
4807 wctx = repo[None]
4808 for f in m.files():
4808 for f in m.files():
4809 if f in repo.dirstate or f in wctx.dirs():
4809 if f in repo.dirstate or f in wctx.dirs():
4810 continue
4810 continue
4811 if os.path.exists(m.rel(f)):
4811 if os.path.exists(m.rel(f)):
4812 if os.path.isdir(m.rel(f)):
4812 if os.path.isdir(m.rel(f)):
4813 ui.warn(_('not removing %s: no tracked files\n') % m.rel(f))
4813 ui.warn(_('not removing %s: no tracked files\n') % m.rel(f))
4814 else:
4814 else:
4815 ui.warn(_('not removing %s: file is untracked\n') % m.rel(f))
4815 ui.warn(_('not removing %s: file is untracked\n') % m.rel(f))
4816 # missing files will generate a warning elsewhere
4816 # missing files will generate a warning elsewhere
4817 ret = 1
4817 ret = 1
4818
4818
4819 if force:
4819 if force:
4820 list = modified + deleted + clean + added
4820 list = modified + deleted + clean + added
4821 elif after:
4821 elif after:
4822 list = deleted
4822 list = deleted
4823 for f in modified + added + clean:
4823 for f in modified + added + clean:
4824 ui.warn(_('not removing %s: file still exists\n') % m.rel(f))
4824 ui.warn(_('not removing %s: file still exists\n') % m.rel(f))
4825 ret = 1
4825 ret = 1
4826 else:
4826 else:
4827 list = deleted + clean
4827 list = deleted + clean
4828 for f in modified:
4828 for f in modified:
4829 ui.warn(_('not removing %s: file is modified (use -f'
4829 ui.warn(_('not removing %s: file is modified (use -f'
4830 ' to force removal)\n') % m.rel(f))
4830 ' to force removal)\n') % m.rel(f))
4831 ret = 1
4831 ret = 1
4832 for f in added:
4832 for f in added:
4833 ui.warn(_('not removing %s: file has been marked for add'
4833 ui.warn(_('not removing %s: file has been marked for add'
4834 ' (use forget to undo)\n') % m.rel(f))
4834 ' (use forget to undo)\n') % m.rel(f))
4835 ret = 1
4835 ret = 1
4836
4836
4837 for f in sorted(list):
4837 for f in sorted(list):
4838 if ui.verbose or not m.exact(f):
4838 if ui.verbose or not m.exact(f):
4839 ui.status(_('removing %s\n') % m.rel(f))
4839 ui.status(_('removing %s\n') % m.rel(f))
4840
4840
4841 wlock = repo.wlock()
4841 wlock = repo.wlock()
4842 try:
4842 try:
4843 if not after:
4843 if not after:
4844 for f in list:
4844 for f in list:
4845 if f in added:
4845 if f in added:
4846 continue # we never unlink added files on remove
4846 continue # we never unlink added files on remove
4847 util.unlinkpath(repo.wjoin(f), ignoremissing=True)
4847 util.unlinkpath(repo.wjoin(f), ignoremissing=True)
4848 repo[None].forget(list)
4848 repo[None].forget(list)
4849 finally:
4849 finally:
4850 wlock.release()
4850 wlock.release()
4851
4851
4852 return ret
4852 return ret
4853
4853
4854 @command('rename|move|mv',
4854 @command('rename|move|mv',
4855 [('A', 'after', None, _('record a rename that has already occurred')),
4855 [('A', 'after', None, _('record a rename that has already occurred')),
4856 ('f', 'force', None, _('forcibly copy over an existing managed file')),
4856 ('f', 'force', None, _('forcibly copy over an existing managed file')),
4857 ] + walkopts + dryrunopts,
4857 ] + walkopts + dryrunopts,
4858 _('[OPTION]... SOURCE... DEST'))
4858 _('[OPTION]... SOURCE... DEST'))
4859 def rename(ui, repo, *pats, **opts):
4859 def rename(ui, repo, *pats, **opts):
4860 """rename files; equivalent of copy + remove
4860 """rename files; equivalent of copy + remove
4861
4861
4862 Mark dest as copies of sources; mark sources for deletion. If dest
4862 Mark dest as copies of sources; mark sources for deletion. If dest
4863 is a directory, copies are put in that directory. If dest is a
4863 is a directory, copies are put in that directory. If dest is a
4864 file, there can only be one source.
4864 file, there can only be one source.
4865
4865
4866 By default, this command copies the contents of files as they
4866 By default, this command copies the contents of files as they
4867 exist in the working directory. If invoked with -A/--after, the
4867 exist in the working directory. If invoked with -A/--after, the
4868 operation is recorded, but no copying is performed.
4868 operation is recorded, but no copying is performed.
4869
4869
4870 This command takes effect at the next commit. To undo a rename
4870 This command takes effect at the next commit. To undo a rename
4871 before that, see :hg:`revert`.
4871 before that, see :hg:`revert`.
4872
4872
4873 Returns 0 on success, 1 if errors are encountered.
4873 Returns 0 on success, 1 if errors are encountered.
4874 """
4874 """
4875 wlock = repo.wlock(False)
4875 wlock = repo.wlock(False)
4876 try:
4876 try:
4877 return cmdutil.copy(ui, repo, pats, opts, rename=True)
4877 return cmdutil.copy(ui, repo, pats, opts, rename=True)
4878 finally:
4878 finally:
4879 wlock.release()
4879 wlock.release()
4880
4880
4881 @command('resolve',
4881 @command('resolve',
4882 [('a', 'all', None, _('select all unresolved files')),
4882 [('a', 'all', None, _('select all unresolved files')),
4883 ('l', 'list', None, _('list state of files needing merge')),
4883 ('l', 'list', None, _('list state of files needing merge')),
4884 ('m', 'mark', None, _('mark files as resolved')),
4884 ('m', 'mark', None, _('mark files as resolved')),
4885 ('u', 'unmark', None, _('mark files as unresolved')),
4885 ('u', 'unmark', None, _('mark files as unresolved')),
4886 ('n', 'no-status', None, _('hide status prefix'))]
4886 ('n', 'no-status', None, _('hide status prefix'))]
4887 + mergetoolopts + walkopts,
4887 + mergetoolopts + walkopts,
4888 _('[OPTION]... [FILE]...'))
4888 _('[OPTION]... [FILE]...'))
4889 def resolve(ui, repo, *pats, **opts):
4889 def resolve(ui, repo, *pats, **opts):
4890 """redo merges or set/view the merge status of files
4890 """redo merges or set/view the merge status of files
4891
4891
4892 Merges with unresolved conflicts are often the result of
4892 Merges with unresolved conflicts are often the result of
4893 non-interactive merging using the ``internal:merge`` configuration
4893 non-interactive merging using the ``internal:merge`` configuration
4894 setting, or a command-line merge tool like ``diff3``. The resolve
4894 setting, or a command-line merge tool like ``diff3``. The resolve
4895 command is used to manage the files involved in a merge, after
4895 command is used to manage the files involved in a merge, after
4896 :hg:`merge` has been run, and before :hg:`commit` is run (i.e. the
4896 :hg:`merge` has been run, and before :hg:`commit` is run (i.e. the
4897 working directory must have two parents). See :hg:`help
4897 working directory must have two parents). See :hg:`help
4898 merge-tools` for information on configuring merge tools.
4898 merge-tools` for information on configuring merge tools.
4899
4899
4900 The resolve command can be used in the following ways:
4900 The resolve command can be used in the following ways:
4901
4901
4902 - :hg:`resolve [--tool TOOL] FILE...`: attempt to re-merge the specified
4902 - :hg:`resolve [--tool TOOL] FILE...`: attempt to re-merge the specified
4903 files, discarding any previous merge attempts. Re-merging is not
4903 files, discarding any previous merge attempts. Re-merging is not
4904 performed for files already marked as resolved. Use ``--all/-a``
4904 performed for files already marked as resolved. Use ``--all/-a``
4905 to select all unresolved files. ``--tool`` can be used to specify
4905 to select all unresolved files. ``--tool`` can be used to specify
4906 the merge tool used for the given files. It overrides the HGMERGE
4906 the merge tool used for the given files. It overrides the HGMERGE
4907 environment variable and your configuration files. Previous file
4907 environment variable and your configuration files. Previous file
4908 contents are saved with a ``.orig`` suffix.
4908 contents are saved with a ``.orig`` suffix.
4909
4909
4910 - :hg:`resolve -m [FILE]`: mark a file as having been resolved
4910 - :hg:`resolve -m [FILE]`: mark a file as having been resolved
4911 (e.g. after having manually fixed-up the files). The default is
4911 (e.g. after having manually fixed-up the files). The default is
4912 to mark all unresolved files.
4912 to mark all unresolved files.
4913
4913
4914 - :hg:`resolve -u [FILE]...`: mark a file as unresolved. The
4914 - :hg:`resolve -u [FILE]...`: mark a file as unresolved. The
4915 default is to mark all resolved files.
4915 default is to mark all resolved files.
4916
4916
4917 - :hg:`resolve -l`: list files which had or still have conflicts.
4917 - :hg:`resolve -l`: list files which had or still have conflicts.
4918 In the printed list, ``U`` = unresolved and ``R`` = resolved.
4918 In the printed list, ``U`` = unresolved and ``R`` = resolved.
4919
4919
4920 Note that Mercurial will not let you commit files with unresolved
4920 Note that Mercurial will not let you commit files with unresolved
4921 merge conflicts. You must use :hg:`resolve -m ...` before you can
4921 merge conflicts. You must use :hg:`resolve -m ...` before you can
4922 commit after a conflicting merge.
4922 commit after a conflicting merge.
4923
4923
4924 Returns 0 on success, 1 if any files fail a resolve attempt.
4924 Returns 0 on success, 1 if any files fail a resolve attempt.
4925 """
4925 """
4926
4926
4927 all, mark, unmark, show, nostatus = \
4927 all, mark, unmark, show, nostatus = \
4928 [opts.get(o) for o in 'all mark unmark list no_status'.split()]
4928 [opts.get(o) for o in 'all mark unmark list no_status'.split()]
4929
4929
4930 if (show and (mark or unmark)) or (mark and unmark):
4930 if (show and (mark or unmark)) or (mark and unmark):
4931 raise util.Abort(_("too many options specified"))
4931 raise util.Abort(_("too many options specified"))
4932 if pats and all:
4932 if pats and all:
4933 raise util.Abort(_("can't specify --all and patterns"))
4933 raise util.Abort(_("can't specify --all and patterns"))
4934 if not (all or pats or show or mark or unmark):
4934 if not (all or pats or show or mark or unmark):
4935 raise util.Abort(_('no files or directories specified; '
4935 raise util.Abort(_('no files or directories specified; '
4936 'use --all to remerge all files'))
4936 'use --all to remerge all files'))
4937
4937
4938 ms = mergemod.mergestate(repo)
4938 ms = mergemod.mergestate(repo)
4939 m = scmutil.match(repo[None], pats, opts)
4939 m = scmutil.match(repo[None], pats, opts)
4940 ret = 0
4940 ret = 0
4941
4941
4942 for f in ms:
4942 for f in ms:
4943 if m(f):
4943 if m(f):
4944 if show:
4944 if show:
4945 if nostatus:
4945 if nostatus:
4946 ui.write("%s\n" % f)
4946 ui.write("%s\n" % f)
4947 else:
4947 else:
4948 ui.write("%s %s\n" % (ms[f].upper(), f),
4948 ui.write("%s %s\n" % (ms[f].upper(), f),
4949 label='resolve.' +
4949 label='resolve.' +
4950 {'u': 'unresolved', 'r': 'resolved'}[ms[f]])
4950 {'u': 'unresolved', 'r': 'resolved'}[ms[f]])
4951 elif mark:
4951 elif mark:
4952 ms.mark(f, "r")
4952 ms.mark(f, "r")
4953 elif unmark:
4953 elif unmark:
4954 ms.mark(f, "u")
4954 ms.mark(f, "u")
4955 else:
4955 else:
4956 wctx = repo[None]
4956 wctx = repo[None]
4957
4957
4958 # backup pre-resolve (merge uses .orig for its own purposes)
4958 # backup pre-resolve (merge uses .orig for its own purposes)
4959 a = repo.wjoin(f)
4959 a = repo.wjoin(f)
4960 util.copyfile(a, a + ".resolve")
4960 util.copyfile(a, a + ".resolve")
4961
4961
4962 try:
4962 try:
4963 # resolve file
4963 # resolve file
4964 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
4964 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
4965 if ms.resolve(f, wctx):
4965 if ms.resolve(f, wctx):
4966 ret = 1
4966 ret = 1
4967 finally:
4967 finally:
4968 ui.setconfig('ui', 'forcemerge', '')
4968 ui.setconfig('ui', 'forcemerge', '')
4969 ms.commit()
4969 ms.commit()
4970
4970
4971 # replace filemerge's .orig file with our resolve file
4971 # replace filemerge's .orig file with our resolve file
4972 util.rename(a + ".resolve", a + ".orig")
4972 util.rename(a + ".resolve", a + ".orig")
4973
4973
4974 ms.commit()
4974 ms.commit()
4975 return ret
4975 return ret
4976
4976
4977 @command('revert',
4977 @command('revert',
4978 [('a', 'all', None, _('revert all changes when no arguments given')),
4978 [('a', 'all', None, _('revert all changes when no arguments given')),
4979 ('d', 'date', '', _('tipmost revision matching date'), _('DATE')),
4979 ('d', 'date', '', _('tipmost revision matching date'), _('DATE')),
4980 ('r', 'rev', '', _('revert to the specified revision'), _('REV')),
4980 ('r', 'rev', '', _('revert to the specified revision'), _('REV')),
4981 ('C', 'no-backup', None, _('do not save backup copies of files')),
4981 ('C', 'no-backup', None, _('do not save backup copies of files')),
4982 ] + walkopts + dryrunopts,
4982 ] + walkopts + dryrunopts,
4983 _('[OPTION]... [-r REV] [NAME]...'))
4983 _('[OPTION]... [-r REV] [NAME]...'))
4984 def revert(ui, repo, *pats, **opts):
4984 def revert(ui, repo, *pats, **opts):
4985 """restore files to their checkout state
4985 """restore files to their checkout state
4986
4986
4987 .. note::
4987 .. note::
4988
4988
4989 To check out earlier revisions, you should use :hg:`update REV`.
4989 To check out earlier revisions, you should use :hg:`update REV`.
4990 To cancel an uncommitted merge (and lose your changes),
4990 To cancel an uncommitted merge (and lose your changes),
4991 use :hg:`update --clean .`.
4991 use :hg:`update --clean .`.
4992
4992
4993 With no revision specified, revert the specified files or directories
4993 With no revision specified, revert the specified files or directories
4994 to the contents they had in the parent of the working directory.
4994 to the contents they had in the parent of the working directory.
4995 This restores the contents of files to an unmodified
4995 This restores the contents of files to an unmodified
4996 state and unschedules adds, removes, copies, and renames. If the
4996 state and unschedules adds, removes, copies, and renames. If the
4997 working directory has two parents, you must explicitly specify a
4997 working directory has two parents, you must explicitly specify a
4998 revision.
4998 revision.
4999
4999
5000 Using the -r/--rev or -d/--date options, revert the given files or
5000 Using the -r/--rev or -d/--date options, revert the given files or
5001 directories to their states as of a specific revision. Because
5001 directories to their states as of a specific revision. Because
5002 revert does not change the working directory parents, this will
5002 revert does not change the working directory parents, this will
5003 cause these files to appear modified. This can be helpful to "back
5003 cause these files to appear modified. This can be helpful to "back
5004 out" some or all of an earlier change. See :hg:`backout` for a
5004 out" some or all of an earlier change. See :hg:`backout` for a
5005 related method.
5005 related method.
5006
5006
5007 Modified files are saved with a .orig suffix before reverting.
5007 Modified files are saved with a .orig suffix before reverting.
5008 To disable these backups, use --no-backup.
5008 To disable these backups, use --no-backup.
5009
5009
5010 See :hg:`help dates` for a list of formats valid for -d/--date.
5010 See :hg:`help dates` for a list of formats valid for -d/--date.
5011
5011
5012 Returns 0 on success.
5012 Returns 0 on success.
5013 """
5013 """
5014
5014
5015 if opts.get("date"):
5015 if opts.get("date"):
5016 if opts.get("rev"):
5016 if opts.get("rev"):
5017 raise util.Abort(_("you can't specify a revision and a date"))
5017 raise util.Abort(_("you can't specify a revision and a date"))
5018 opts["rev"] = cmdutil.finddate(ui, repo, opts["date"])
5018 opts["rev"] = cmdutil.finddate(ui, repo, opts["date"])
5019
5019
5020 parent, p2 = repo.dirstate.parents()
5020 parent, p2 = repo.dirstate.parents()
5021 if not opts.get('rev') and p2 != nullid:
5021 if not opts.get('rev') and p2 != nullid:
5022 # revert after merge is a trap for new users (issue2915)
5022 # revert after merge is a trap for new users (issue2915)
5023 raise util.Abort(_('uncommitted merge with no revision specified'),
5023 raise util.Abort(_('uncommitted merge with no revision specified'),
5024 hint=_('use "hg update" or see "hg help revert"'))
5024 hint=_('use "hg update" or see "hg help revert"'))
5025
5025
5026 ctx = scmutil.revsingle(repo, opts.get('rev'))
5026 ctx = scmutil.revsingle(repo, opts.get('rev'))
5027
5027
5028 if not pats and not opts.get('all'):
5028 if not pats and not opts.get('all'):
5029 msg = _("no files or directories specified")
5029 msg = _("no files or directories specified")
5030 if p2 != nullid:
5030 if p2 != nullid:
5031 hint = _("uncommitted merge, use --all to discard all changes,"
5031 hint = _("uncommitted merge, use --all to discard all changes,"
5032 " or 'hg update -C .' to abort the merge")
5032 " or 'hg update -C .' to abort the merge")
5033 raise util.Abort(msg, hint=hint)
5033 raise util.Abort(msg, hint=hint)
5034 dirty = util.any(repo.status())
5034 dirty = util.any(repo.status())
5035 node = ctx.node()
5035 node = ctx.node()
5036 if node != parent:
5036 if node != parent:
5037 if dirty:
5037 if dirty:
5038 hint = _("uncommitted changes, use --all to discard all"
5038 hint = _("uncommitted changes, use --all to discard all"
5039 " changes, or 'hg update %s' to update") % ctx.rev()
5039 " changes, or 'hg update %s' to update") % ctx.rev()
5040 else:
5040 else:
5041 hint = _("use --all to revert all files,"
5041 hint = _("use --all to revert all files,"
5042 " or 'hg update %s' to update") % ctx.rev()
5042 " or 'hg update %s' to update") % ctx.rev()
5043 elif dirty:
5043 elif dirty:
5044 hint = _("uncommitted changes, use --all to discard all changes")
5044 hint = _("uncommitted changes, use --all to discard all changes")
5045 else:
5045 else:
5046 hint = _("use --all to revert all files")
5046 hint = _("use --all to revert all files")
5047 raise util.Abort(msg, hint=hint)
5047 raise util.Abort(msg, hint=hint)
5048
5048
5049 return cmdutil.revert(ui, repo, ctx, (parent, p2), *pats, **opts)
5049 return cmdutil.revert(ui, repo, ctx, (parent, p2), *pats, **opts)
5050
5050
5051 @command('rollback', dryrunopts +
5051 @command('rollback', dryrunopts +
5052 [('f', 'force', False, _('ignore safety measures'))])
5052 [('f', 'force', False, _('ignore safety measures'))])
5053 def rollback(ui, repo, **opts):
5053 def rollback(ui, repo, **opts):
5054 """roll back the last transaction (DANGEROUS) (DEPRECATED)
5054 """roll back the last transaction (DANGEROUS) (DEPRECATED)
5055
5055
5056 Please use :hg:`commit --amend` instead of rollback to correct
5056 Please use :hg:`commit --amend` instead of rollback to correct
5057 mistakes in the last commit.
5057 mistakes in the last commit.
5058
5058
5059 This command should be used with care. There is only one level of
5059 This command should be used with care. There is only one level of
5060 rollback, and there is no way to undo a rollback. It will also
5060 rollback, and there is no way to undo a rollback. It will also
5061 restore the dirstate at the time of the last transaction, losing
5061 restore the dirstate at the time of the last transaction, losing
5062 any dirstate changes since that time. This command does not alter
5062 any dirstate changes since that time. This command does not alter
5063 the working directory.
5063 the working directory.
5064
5064
5065 Transactions are used to encapsulate the effects of all commands
5065 Transactions are used to encapsulate the effects of all commands
5066 that create new changesets or propagate existing changesets into a
5066 that create new changesets or propagate existing changesets into a
5067 repository.
5067 repository.
5068
5068
5069 .. container:: verbose
5069 .. container:: verbose
5070
5070
5071 For example, the following commands are transactional, and their
5071 For example, the following commands are transactional, and their
5072 effects can be rolled back:
5072 effects can be rolled back:
5073
5073
5074 - commit
5074 - commit
5075 - import
5075 - import
5076 - pull
5076 - pull
5077 - push (with this repository as the destination)
5077 - push (with this repository as the destination)
5078 - unbundle
5078 - unbundle
5079
5079
5080 To avoid permanent data loss, rollback will refuse to rollback a
5080 To avoid permanent data loss, rollback will refuse to rollback a
5081 commit transaction if it isn't checked out. Use --force to
5081 commit transaction if it isn't checked out. Use --force to
5082 override this protection.
5082 override this protection.
5083
5083
5084 This command is not intended for use on public repositories. Once
5084 This command is not intended for use on public repositories. Once
5085 changes are visible for pull by other users, rolling a transaction
5085 changes are visible for pull by other users, rolling a transaction
5086 back locally is ineffective (someone else may already have pulled
5086 back locally is ineffective (someone else may already have pulled
5087 the changes). Furthermore, a race is possible with readers of the
5087 the changes). Furthermore, a race is possible with readers of the
5088 repository; for example an in-progress pull from the repository
5088 repository; for example an in-progress pull from the repository
5089 may fail if a rollback is performed.
5089 may fail if a rollback is performed.
5090
5090
5091 Returns 0 on success, 1 if no rollback data is available.
5091 Returns 0 on success, 1 if no rollback data is available.
5092 """
5092 """
5093 return repo.rollback(dryrun=opts.get('dry_run'),
5093 return repo.rollback(dryrun=opts.get('dry_run'),
5094 force=opts.get('force'))
5094 force=opts.get('force'))
5095
5095
5096 @command('root', [])
5096 @command('root', [])
5097 def root(ui, repo):
5097 def root(ui, repo):
5098 """print the root (top) of the current working directory
5098 """print the root (top) of the current working directory
5099
5099
5100 Print the root directory of the current repository.
5100 Print the root directory of the current repository.
5101
5101
5102 Returns 0 on success.
5102 Returns 0 on success.
5103 """
5103 """
5104 ui.write(repo.root + "\n")
5104 ui.write(repo.root + "\n")
5105
5105
5106 @command('^serve',
5106 @command('^serve',
5107 [('A', 'accesslog', '', _('name of access log file to write to'),
5107 [('A', 'accesslog', '', _('name of access log file to write to'),
5108 _('FILE')),
5108 _('FILE')),
5109 ('d', 'daemon', None, _('run server in background')),
5109 ('d', 'daemon', None, _('run server in background')),
5110 ('', 'daemon-pipefds', '', _('used internally by daemon mode'), _('NUM')),
5110 ('', 'daemon-pipefds', '', _('used internally by daemon mode'), _('NUM')),
5111 ('E', 'errorlog', '', _('name of error log file to write to'), _('FILE')),
5111 ('E', 'errorlog', '', _('name of error log file to write to'), _('FILE')),
5112 # use string type, then we can check if something was passed
5112 # use string type, then we can check if something was passed
5113 ('p', 'port', '', _('port to listen on (default: 8000)'), _('PORT')),
5113 ('p', 'port', '', _('port to listen on (default: 8000)'), _('PORT')),
5114 ('a', 'address', '', _('address to listen on (default: all interfaces)'),
5114 ('a', 'address', '', _('address to listen on (default: all interfaces)'),
5115 _('ADDR')),
5115 _('ADDR')),
5116 ('', 'prefix', '', _('prefix path to serve from (default: server root)'),
5116 ('', 'prefix', '', _('prefix path to serve from (default: server root)'),
5117 _('PREFIX')),
5117 _('PREFIX')),
5118 ('n', 'name', '',
5118 ('n', 'name', '',
5119 _('name to show in web pages (default: working directory)'), _('NAME')),
5119 _('name to show in web pages (default: working directory)'), _('NAME')),
5120 ('', 'web-conf', '',
5120 ('', 'web-conf', '',
5121 _('name of the hgweb config file (see "hg help hgweb")'), _('FILE')),
5121 _('name of the hgweb config file (see "hg help hgweb")'), _('FILE')),
5122 ('', 'webdir-conf', '', _('name of the hgweb config file (DEPRECATED)'),
5122 ('', 'webdir-conf', '', _('name of the hgweb config file (DEPRECATED)'),
5123 _('FILE')),
5123 _('FILE')),
5124 ('', 'pid-file', '', _('name of file to write process ID to'), _('FILE')),
5124 ('', 'pid-file', '', _('name of file to write process ID to'), _('FILE')),
5125 ('', 'stdio', None, _('for remote clients')),
5125 ('', 'stdio', None, _('for remote clients')),
5126 ('', 'cmdserver', '', _('for remote clients'), _('MODE')),
5126 ('', 'cmdserver', '', _('for remote clients'), _('MODE')),
5127 ('t', 'templates', '', _('web templates to use'), _('TEMPLATE')),
5127 ('t', 'templates', '', _('web templates to use'), _('TEMPLATE')),
5128 ('', 'style', '', _('template style to use'), _('STYLE')),
5128 ('', 'style', '', _('template style to use'), _('STYLE')),
5129 ('6', 'ipv6', None, _('use IPv6 in addition to IPv4')),
5129 ('6', 'ipv6', None, _('use IPv6 in addition to IPv4')),
5130 ('', 'certificate', '', _('SSL certificate file'), _('FILE'))],
5130 ('', 'certificate', '', _('SSL certificate file'), _('FILE'))],
5131 _('[OPTION]...'))
5131 _('[OPTION]...'))
5132 def serve(ui, repo, **opts):
5132 def serve(ui, repo, **opts):
5133 """start stand-alone webserver
5133 """start stand-alone webserver
5134
5134
5135 Start a local HTTP repository browser and pull server. You can use
5135 Start a local HTTP repository browser and pull server. You can use
5136 this for ad-hoc sharing and browsing of repositories. It is
5136 this for ad-hoc sharing and browsing of repositories. It is
5137 recommended to use a real web server to serve a repository for
5137 recommended to use a real web server to serve a repository for
5138 longer periods of time.
5138 longer periods of time.
5139
5139
5140 Please note that the server does not implement access control.
5140 Please note that the server does not implement access control.
5141 This means that, by default, anybody can read from the server and
5141 This means that, by default, anybody can read from the server and
5142 nobody can write to it by default. Set the ``web.allow_push``
5142 nobody can write to it by default. Set the ``web.allow_push``
5143 option to ``*`` to allow everybody to push to the server. You
5143 option to ``*`` to allow everybody to push to the server. You
5144 should use a real web server if you need to authenticate users.
5144 should use a real web server if you need to authenticate users.
5145
5145
5146 By default, the server logs accesses to stdout and errors to
5146 By default, the server logs accesses to stdout and errors to
5147 stderr. Use the -A/--accesslog and -E/--errorlog options to log to
5147 stderr. Use the -A/--accesslog and -E/--errorlog options to log to
5148 files.
5148 files.
5149
5149
5150 To have the server choose a free port number to listen on, specify
5150 To have the server choose a free port number to listen on, specify
5151 a port number of 0; in this case, the server will print the port
5151 a port number of 0; in this case, the server will print the port
5152 number it uses.
5152 number it uses.
5153
5153
5154 Returns 0 on success.
5154 Returns 0 on success.
5155 """
5155 """
5156
5156
5157 if opts["stdio"] and opts["cmdserver"]:
5157 if opts["stdio"] and opts["cmdserver"]:
5158 raise util.Abort(_("cannot use --stdio with --cmdserver"))
5158 raise util.Abort(_("cannot use --stdio with --cmdserver"))
5159
5159
5160 def checkrepo():
5160 def checkrepo():
5161 if repo is None:
5161 if repo is None:
5162 raise error.RepoError(_("there is no Mercurial repository here"
5162 raise error.RepoError(_("there is no Mercurial repository here"
5163 " (.hg not found)"))
5163 " (.hg not found)"))
5164
5164
5165 if opts["stdio"]:
5165 if opts["stdio"]:
5166 checkrepo()
5166 checkrepo()
5167 s = sshserver.sshserver(ui, repo)
5167 s = sshserver.sshserver(ui, repo)
5168 s.serve_forever()
5168 s.serve_forever()
5169
5169
5170 if opts["cmdserver"]:
5170 if opts["cmdserver"]:
5171 s = commandserver.server(ui, repo, opts["cmdserver"])
5171 s = commandserver.server(ui, repo, opts["cmdserver"])
5172 return s.serve()
5172 return s.serve()
5173
5173
5174 # this way we can check if something was given in the command-line
5174 # this way we can check if something was given in the command-line
5175 if opts.get('port'):
5175 if opts.get('port'):
5176 opts['port'] = util.getport(opts.get('port'))
5176 opts['port'] = util.getport(opts.get('port'))
5177
5177
5178 baseui = repo and repo.baseui or ui
5178 baseui = repo and repo.baseui or ui
5179 optlist = ("name templates style address port prefix ipv6"
5179 optlist = ("name templates style address port prefix ipv6"
5180 " accesslog errorlog certificate encoding")
5180 " accesslog errorlog certificate encoding")
5181 for o in optlist.split():
5181 for o in optlist.split():
5182 val = opts.get(o, '')
5182 val = opts.get(o, '')
5183 if val in (None, ''): # should check against default options instead
5183 if val in (None, ''): # should check against default options instead
5184 continue
5184 continue
5185 baseui.setconfig("web", o, val)
5185 baseui.setconfig("web", o, val)
5186 if repo and repo.ui != baseui:
5186 if repo and repo.ui != baseui:
5187 repo.ui.setconfig("web", o, val)
5187 repo.ui.setconfig("web", o, val)
5188
5188
5189 o = opts.get('web_conf') or opts.get('webdir_conf')
5189 o = opts.get('web_conf') or opts.get('webdir_conf')
5190 if not o:
5190 if not o:
5191 if not repo:
5191 if not repo:
5192 raise error.RepoError(_("there is no Mercurial repository"
5192 raise error.RepoError(_("there is no Mercurial repository"
5193 " here (.hg not found)"))
5193 " here (.hg not found)"))
5194 o = repo
5194 o = repo
5195
5195
5196 app = hgweb.hgweb(o, baseui=baseui)
5196 app = hgweb.hgweb(o, baseui=baseui)
5197 service = httpservice(ui, app, opts)
5197 service = httpservice(ui, app, opts)
5198 cmdutil.service(opts, initfn=service.init, runfn=service.run)
5198 cmdutil.service(opts, initfn=service.init, runfn=service.run)
5199
5199
5200 class httpservice(object):
5200 class httpservice(object):
5201 def __init__(self, ui, app, opts):
5201 def __init__(self, ui, app, opts):
5202 self.ui = ui
5202 self.ui = ui
5203 self.app = app
5203 self.app = app
5204 self.opts = opts
5204 self.opts = opts
5205
5205
5206 def init(self):
5206 def init(self):
5207 util.setsignalhandler()
5207 util.setsignalhandler()
5208 self.httpd = hgweb_server.create_server(self.ui, self.app)
5208 self.httpd = hgweb_server.create_server(self.ui, self.app)
5209
5209
5210 if self.opts['port'] and not self.ui.verbose:
5210 if self.opts['port'] and not self.ui.verbose:
5211 return
5211 return
5212
5212
5213 if self.httpd.prefix:
5213 if self.httpd.prefix:
5214 prefix = self.httpd.prefix.strip('/') + '/'
5214 prefix = self.httpd.prefix.strip('/') + '/'
5215 else:
5215 else:
5216 prefix = ''
5216 prefix = ''
5217
5217
5218 port = ':%d' % self.httpd.port
5218 port = ':%d' % self.httpd.port
5219 if port == ':80':
5219 if port == ':80':
5220 port = ''
5220 port = ''
5221
5221
5222 bindaddr = self.httpd.addr
5222 bindaddr = self.httpd.addr
5223 if bindaddr == '0.0.0.0':
5223 if bindaddr == '0.0.0.0':
5224 bindaddr = '*'
5224 bindaddr = '*'
5225 elif ':' in bindaddr: # IPv6
5225 elif ':' in bindaddr: # IPv6
5226 bindaddr = '[%s]' % bindaddr
5226 bindaddr = '[%s]' % bindaddr
5227
5227
5228 fqaddr = self.httpd.fqaddr
5228 fqaddr = self.httpd.fqaddr
5229 if ':' in fqaddr:
5229 if ':' in fqaddr:
5230 fqaddr = '[%s]' % fqaddr
5230 fqaddr = '[%s]' % fqaddr
5231 if self.opts['port']:
5231 if self.opts['port']:
5232 write = self.ui.status
5232 write = self.ui.status
5233 else:
5233 else:
5234 write = self.ui.write
5234 write = self.ui.write
5235 write(_('listening at http://%s%s/%s (bound to %s:%d)\n') %
5235 write(_('listening at http://%s%s/%s (bound to %s:%d)\n') %
5236 (fqaddr, port, prefix, bindaddr, self.httpd.port))
5236 (fqaddr, port, prefix, bindaddr, self.httpd.port))
5237
5237
5238 def run(self):
5238 def run(self):
5239 self.httpd.serve_forever()
5239 self.httpd.serve_forever()
5240
5240
5241
5241
5242 @command('^status|st',
5242 @command('^status|st',
5243 [('A', 'all', None, _('show status of all files')),
5243 [('A', 'all', None, _('show status of all files')),
5244 ('m', 'modified', None, _('show only modified files')),
5244 ('m', 'modified', None, _('show only modified files')),
5245 ('a', 'added', None, _('show only added files')),
5245 ('a', 'added', None, _('show only added files')),
5246 ('r', 'removed', None, _('show only removed files')),
5246 ('r', 'removed', None, _('show only removed files')),
5247 ('d', 'deleted', None, _('show only deleted (but tracked) files')),
5247 ('d', 'deleted', None, _('show only deleted (but tracked) files')),
5248 ('c', 'clean', None, _('show only files without changes')),
5248 ('c', 'clean', None, _('show only files without changes')),
5249 ('u', 'unknown', None, _('show only unknown (not tracked) files')),
5249 ('u', 'unknown', None, _('show only unknown (not tracked) files')),
5250 ('i', 'ignored', None, _('show only ignored files')),
5250 ('i', 'ignored', None, _('show only ignored files')),
5251 ('n', 'no-status', None, _('hide status prefix')),
5251 ('n', 'no-status', None, _('hide status prefix')),
5252 ('C', 'copies', None, _('show source of copied files')),
5252 ('C', 'copies', None, _('show source of copied files')),
5253 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
5253 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
5254 ('', 'rev', [], _('show difference from revision'), _('REV')),
5254 ('', 'rev', [], _('show difference from revision'), _('REV')),
5255 ('', 'change', '', _('list the changed files of a revision'), _('REV')),
5255 ('', 'change', '', _('list the changed files of a revision'), _('REV')),
5256 ] + walkopts + subrepoopts,
5256 ] + walkopts + subrepoopts,
5257 _('[OPTION]... [FILE]...'))
5257 _('[OPTION]... [FILE]...'))
5258 def status(ui, repo, *pats, **opts):
5258 def status(ui, repo, *pats, **opts):
5259 """show changed files in the working directory
5259 """show changed files in the working directory
5260
5260
5261 Show status of files in the repository. If names are given, only
5261 Show status of files in the repository. If names are given, only
5262 files that match are shown. Files that are clean or ignored or
5262 files that match are shown. Files that are clean or ignored or
5263 the source of a copy/move operation, are not listed unless
5263 the source of a copy/move operation, are not listed unless
5264 -c/--clean, -i/--ignored, -C/--copies or -A/--all are given.
5264 -c/--clean, -i/--ignored, -C/--copies or -A/--all are given.
5265 Unless options described with "show only ..." are given, the
5265 Unless options described with "show only ..." are given, the
5266 options -mardu are used.
5266 options -mardu are used.
5267
5267
5268 Option -q/--quiet hides untracked (unknown and ignored) files
5268 Option -q/--quiet hides untracked (unknown and ignored) files
5269 unless explicitly requested with -u/--unknown or -i/--ignored.
5269 unless explicitly requested with -u/--unknown or -i/--ignored.
5270
5270
5271 .. note::
5271 .. note::
5272
5272
5273 status may appear to disagree with diff if permissions have
5273 status may appear to disagree with diff if permissions have
5274 changed or a merge has occurred. The standard diff format does
5274 changed or a merge has occurred. The standard diff format does
5275 not report permission changes and diff only reports changes
5275 not report permission changes and diff only reports changes
5276 relative to one merge parent.
5276 relative to one merge parent.
5277
5277
5278 If one revision is given, it is used as the base revision.
5278 If one revision is given, it is used as the base revision.
5279 If two revisions are given, the differences between them are
5279 If two revisions are given, the differences between them are
5280 shown. The --change option can also be used as a shortcut to list
5280 shown. The --change option can also be used as a shortcut to list
5281 the changed files of a revision from its first parent.
5281 the changed files of a revision from its first parent.
5282
5282
5283 The codes used to show the status of files are::
5283 The codes used to show the status of files are::
5284
5284
5285 M = modified
5285 M = modified
5286 A = added
5286 A = added
5287 R = removed
5287 R = removed
5288 C = clean
5288 C = clean
5289 ! = missing (deleted by non-hg command, but still tracked)
5289 ! = missing (deleted by non-hg command, but still tracked)
5290 ? = not tracked
5290 ? = not tracked
5291 I = ignored
5291 I = ignored
5292 = origin of the previous file listed as A (added)
5292 = origin of the previous file (with --copies)
5293
5293
5294 .. container:: verbose
5294 .. container:: verbose
5295
5295
5296 Examples:
5296 Examples:
5297
5297
5298 - show changes in the working directory relative to a
5298 - show changes in the working directory relative to a
5299 changeset::
5299 changeset::
5300
5300
5301 hg status --rev 9353
5301 hg status --rev 9353
5302
5302
5303 - show all changes including copies in an existing changeset::
5303 - show all changes including copies in an existing changeset::
5304
5304
5305 hg status --copies --change 9353
5305 hg status --copies --change 9353
5306
5306
5307 - get a NUL separated list of added files, suitable for xargs::
5307 - get a NUL separated list of added files, suitable for xargs::
5308
5308
5309 hg status -an0
5309 hg status -an0
5310
5310
5311 Returns 0 on success.
5311 Returns 0 on success.
5312 """
5312 """
5313
5313
5314 revs = opts.get('rev')
5314 revs = opts.get('rev')
5315 change = opts.get('change')
5315 change = opts.get('change')
5316
5316
5317 if revs and change:
5317 if revs and change:
5318 msg = _('cannot specify --rev and --change at the same time')
5318 msg = _('cannot specify --rev and --change at the same time')
5319 raise util.Abort(msg)
5319 raise util.Abort(msg)
5320 elif change:
5320 elif change:
5321 node2 = scmutil.revsingle(repo, change, None).node()
5321 node2 = scmutil.revsingle(repo, change, None).node()
5322 node1 = repo[node2].p1().node()
5322 node1 = repo[node2].p1().node()
5323 else:
5323 else:
5324 node1, node2 = scmutil.revpair(repo, revs)
5324 node1, node2 = scmutil.revpair(repo, revs)
5325
5325
5326 cwd = (pats and repo.getcwd()) or ''
5326 cwd = (pats and repo.getcwd()) or ''
5327 end = opts.get('print0') and '\0' or '\n'
5327 end = opts.get('print0') and '\0' or '\n'
5328 copy = {}
5328 copy = {}
5329 states = 'modified added removed deleted unknown ignored clean'.split()
5329 states = 'modified added removed deleted unknown ignored clean'.split()
5330 show = [k for k in states if opts.get(k)]
5330 show = [k for k in states if opts.get(k)]
5331 if opts.get('all'):
5331 if opts.get('all'):
5332 show += ui.quiet and (states[:4] + ['clean']) or states
5332 show += ui.quiet and (states[:4] + ['clean']) or states
5333 if not show:
5333 if not show:
5334 show = ui.quiet and states[:4] or states[:5]
5334 show = ui.quiet and states[:4] or states[:5]
5335
5335
5336 stat = repo.status(node1, node2, scmutil.match(repo[node2], pats, opts),
5336 stat = repo.status(node1, node2, scmutil.match(repo[node2], pats, opts),
5337 'ignored' in show, 'clean' in show, 'unknown' in show,
5337 'ignored' in show, 'clean' in show, 'unknown' in show,
5338 opts.get('subrepos'))
5338 opts.get('subrepos'))
5339 changestates = zip(states, 'MAR!?IC', stat)
5339 changestates = zip(states, 'MAR!?IC', stat)
5340
5340
5341 if (opts.get('all') or opts.get('copies')) and not opts.get('no_status'):
5341 if (opts.get('all') or opts.get('copies')) and not opts.get('no_status'):
5342 copy = copies.pathcopies(repo[node1], repo[node2])
5342 copy = copies.pathcopies(repo[node1], repo[node2])
5343
5343
5344 fm = ui.formatter('status', opts)
5344 fm = ui.formatter('status', opts)
5345 fmt = '%s' + end
5345 fmt = '%s' + end
5346 showchar = not opts.get('no_status')
5346 showchar = not opts.get('no_status')
5347
5347
5348 for state, char, files in changestates:
5348 for state, char, files in changestates:
5349 if state in show:
5349 if state in show:
5350 label = 'status.' + state
5350 label = 'status.' + state
5351 for f in files:
5351 for f in files:
5352 fm.startitem()
5352 fm.startitem()
5353 fm.condwrite(showchar, 'status', '%s ', char, label=label)
5353 fm.condwrite(showchar, 'status', '%s ', char, label=label)
5354 fm.write('path', fmt, repo.pathto(f, cwd), label=label)
5354 fm.write('path', fmt, repo.pathto(f, cwd), label=label)
5355 if f in copy:
5355 if f in copy:
5356 fm.write("copy", ' %s' + end, repo.pathto(copy[f], cwd),
5356 fm.write("copy", ' %s' + end, repo.pathto(copy[f], cwd),
5357 label='status.copied')
5357 label='status.copied')
5358 fm.end()
5358 fm.end()
5359
5359
5360 @command('^summary|sum',
5360 @command('^summary|sum',
5361 [('', 'remote', None, _('check for push and pull'))], '[--remote]')
5361 [('', 'remote', None, _('check for push and pull'))], '[--remote]')
5362 def summary(ui, repo, **opts):
5362 def summary(ui, repo, **opts):
5363 """summarize working directory state
5363 """summarize working directory state
5364
5364
5365 This generates a brief summary of the working directory state,
5365 This generates a brief summary of the working directory state,
5366 including parents, branch, commit status, and available updates.
5366 including parents, branch, commit status, and available updates.
5367
5367
5368 With the --remote option, this will check the default paths for
5368 With the --remote option, this will check the default paths for
5369 incoming and outgoing changes. This can be time-consuming.
5369 incoming and outgoing changes. This can be time-consuming.
5370
5370
5371 Returns 0 on success.
5371 Returns 0 on success.
5372 """
5372 """
5373
5373
5374 ctx = repo[None]
5374 ctx = repo[None]
5375 parents = ctx.parents()
5375 parents = ctx.parents()
5376 pnode = parents[0].node()
5376 pnode = parents[0].node()
5377 marks = []
5377 marks = []
5378
5378
5379 for p in parents:
5379 for p in parents:
5380 # label with log.changeset (instead of log.parent) since this
5380 # label with log.changeset (instead of log.parent) since this
5381 # shows a working directory parent *changeset*:
5381 # shows a working directory parent *changeset*:
5382 # i18n: column positioning for "hg summary"
5382 # i18n: column positioning for "hg summary"
5383 ui.write(_('parent: %d:%s ') % (p.rev(), str(p)),
5383 ui.write(_('parent: %d:%s ') % (p.rev(), str(p)),
5384 label='log.changeset changeset.%s' % p.phasestr())
5384 label='log.changeset changeset.%s' % p.phasestr())
5385 ui.write(' '.join(p.tags()), label='log.tag')
5385 ui.write(' '.join(p.tags()), label='log.tag')
5386 if p.bookmarks():
5386 if p.bookmarks():
5387 marks.extend(p.bookmarks())
5387 marks.extend(p.bookmarks())
5388 if p.rev() == -1:
5388 if p.rev() == -1:
5389 if not len(repo):
5389 if not len(repo):
5390 ui.write(_(' (empty repository)'))
5390 ui.write(_(' (empty repository)'))
5391 else:
5391 else:
5392 ui.write(_(' (no revision checked out)'))
5392 ui.write(_(' (no revision checked out)'))
5393 ui.write('\n')
5393 ui.write('\n')
5394 if p.description():
5394 if p.description():
5395 ui.status(' ' + p.description().splitlines()[0].strip() + '\n',
5395 ui.status(' ' + p.description().splitlines()[0].strip() + '\n',
5396 label='log.summary')
5396 label='log.summary')
5397
5397
5398 branch = ctx.branch()
5398 branch = ctx.branch()
5399 bheads = repo.branchheads(branch)
5399 bheads = repo.branchheads(branch)
5400 # i18n: column positioning for "hg summary"
5400 # i18n: column positioning for "hg summary"
5401 m = _('branch: %s\n') % branch
5401 m = _('branch: %s\n') % branch
5402 if branch != 'default':
5402 if branch != 'default':
5403 ui.write(m, label='log.branch')
5403 ui.write(m, label='log.branch')
5404 else:
5404 else:
5405 ui.status(m, label='log.branch')
5405 ui.status(m, label='log.branch')
5406
5406
5407 if marks:
5407 if marks:
5408 current = repo._bookmarkcurrent
5408 current = repo._bookmarkcurrent
5409 # i18n: column positioning for "hg summary"
5409 # i18n: column positioning for "hg summary"
5410 ui.write(_('bookmarks:'), label='log.bookmark')
5410 ui.write(_('bookmarks:'), label='log.bookmark')
5411 if current is not None:
5411 if current is not None:
5412 if current in marks:
5412 if current in marks:
5413 ui.write(' *' + current, label='bookmarks.current')
5413 ui.write(' *' + current, label='bookmarks.current')
5414 marks.remove(current)
5414 marks.remove(current)
5415 else:
5415 else:
5416 ui.write(' [%s]' % current, label='bookmarks.current')
5416 ui.write(' [%s]' % current, label='bookmarks.current')
5417 for m in marks:
5417 for m in marks:
5418 ui.write(' ' + m, label='log.bookmark')
5418 ui.write(' ' + m, label='log.bookmark')
5419 ui.write('\n', label='log.bookmark')
5419 ui.write('\n', label='log.bookmark')
5420
5420
5421 st = list(repo.status(unknown=True))[:6]
5421 st = list(repo.status(unknown=True))[:6]
5422
5422
5423 c = repo.dirstate.copies()
5423 c = repo.dirstate.copies()
5424 copied, renamed = [], []
5424 copied, renamed = [], []
5425 for d, s in c.iteritems():
5425 for d, s in c.iteritems():
5426 if s in st[2]:
5426 if s in st[2]:
5427 st[2].remove(s)
5427 st[2].remove(s)
5428 renamed.append(d)
5428 renamed.append(d)
5429 else:
5429 else:
5430 copied.append(d)
5430 copied.append(d)
5431 if d in st[1]:
5431 if d in st[1]:
5432 st[1].remove(d)
5432 st[1].remove(d)
5433 st.insert(3, renamed)
5433 st.insert(3, renamed)
5434 st.insert(4, copied)
5434 st.insert(4, copied)
5435
5435
5436 ms = mergemod.mergestate(repo)
5436 ms = mergemod.mergestate(repo)
5437 st.append([f for f in ms if ms[f] == 'u'])
5437 st.append([f for f in ms if ms[f] == 'u'])
5438
5438
5439 subs = [s for s in ctx.substate if ctx.sub(s).dirty()]
5439 subs = [s for s in ctx.substate if ctx.sub(s).dirty()]
5440 st.append(subs)
5440 st.append(subs)
5441
5441
5442 labels = [ui.label(_('%d modified'), 'status.modified'),
5442 labels = [ui.label(_('%d modified'), 'status.modified'),
5443 ui.label(_('%d added'), 'status.added'),
5443 ui.label(_('%d added'), 'status.added'),
5444 ui.label(_('%d removed'), 'status.removed'),
5444 ui.label(_('%d removed'), 'status.removed'),
5445 ui.label(_('%d renamed'), 'status.copied'),
5445 ui.label(_('%d renamed'), 'status.copied'),
5446 ui.label(_('%d copied'), 'status.copied'),
5446 ui.label(_('%d copied'), 'status.copied'),
5447 ui.label(_('%d deleted'), 'status.deleted'),
5447 ui.label(_('%d deleted'), 'status.deleted'),
5448 ui.label(_('%d unknown'), 'status.unknown'),
5448 ui.label(_('%d unknown'), 'status.unknown'),
5449 ui.label(_('%d ignored'), 'status.ignored'),
5449 ui.label(_('%d ignored'), 'status.ignored'),
5450 ui.label(_('%d unresolved'), 'resolve.unresolved'),
5450 ui.label(_('%d unresolved'), 'resolve.unresolved'),
5451 ui.label(_('%d subrepos'), 'status.modified')]
5451 ui.label(_('%d subrepos'), 'status.modified')]
5452 t = []
5452 t = []
5453 for s, l in zip(st, labels):
5453 for s, l in zip(st, labels):
5454 if s:
5454 if s:
5455 t.append(l % len(s))
5455 t.append(l % len(s))
5456
5456
5457 t = ', '.join(t)
5457 t = ', '.join(t)
5458 cleanworkdir = False
5458 cleanworkdir = False
5459
5459
5460 if repo.vfs.exists('updatestate'):
5460 if repo.vfs.exists('updatestate'):
5461 t += _(' (interrupted update)')
5461 t += _(' (interrupted update)')
5462 elif len(parents) > 1:
5462 elif len(parents) > 1:
5463 t += _(' (merge)')
5463 t += _(' (merge)')
5464 elif branch != parents[0].branch():
5464 elif branch != parents[0].branch():
5465 t += _(' (new branch)')
5465 t += _(' (new branch)')
5466 elif (parents[0].closesbranch() and
5466 elif (parents[0].closesbranch() and
5467 pnode in repo.branchheads(branch, closed=True)):
5467 pnode in repo.branchheads(branch, closed=True)):
5468 t += _(' (head closed)')
5468 t += _(' (head closed)')
5469 elif not (st[0] or st[1] or st[2] or st[3] or st[4] or st[9]):
5469 elif not (st[0] or st[1] or st[2] or st[3] or st[4] or st[9]):
5470 t += _(' (clean)')
5470 t += _(' (clean)')
5471 cleanworkdir = True
5471 cleanworkdir = True
5472 elif pnode not in bheads:
5472 elif pnode not in bheads:
5473 t += _(' (new branch head)')
5473 t += _(' (new branch head)')
5474
5474
5475 if cleanworkdir:
5475 if cleanworkdir:
5476 # i18n: column positioning for "hg summary"
5476 # i18n: column positioning for "hg summary"
5477 ui.status(_('commit: %s\n') % t.strip())
5477 ui.status(_('commit: %s\n') % t.strip())
5478 else:
5478 else:
5479 # i18n: column positioning for "hg summary"
5479 # i18n: column positioning for "hg summary"
5480 ui.write(_('commit: %s\n') % t.strip())
5480 ui.write(_('commit: %s\n') % t.strip())
5481
5481
5482 # all ancestors of branch heads - all ancestors of parent = new csets
5482 # all ancestors of branch heads - all ancestors of parent = new csets
5483 new = len(repo.changelog.findmissing([ctx.node() for ctx in parents],
5483 new = len(repo.changelog.findmissing([ctx.node() for ctx in parents],
5484 bheads))
5484 bheads))
5485
5485
5486 if new == 0:
5486 if new == 0:
5487 # i18n: column positioning for "hg summary"
5487 # i18n: column positioning for "hg summary"
5488 ui.status(_('update: (current)\n'))
5488 ui.status(_('update: (current)\n'))
5489 elif pnode not in bheads:
5489 elif pnode not in bheads:
5490 # i18n: column positioning for "hg summary"
5490 # i18n: column positioning for "hg summary"
5491 ui.write(_('update: %d new changesets (update)\n') % new)
5491 ui.write(_('update: %d new changesets (update)\n') % new)
5492 else:
5492 else:
5493 # i18n: column positioning for "hg summary"
5493 # i18n: column positioning for "hg summary"
5494 ui.write(_('update: %d new changesets, %d branch heads (merge)\n') %
5494 ui.write(_('update: %d new changesets, %d branch heads (merge)\n') %
5495 (new, len(bheads)))
5495 (new, len(bheads)))
5496
5496
5497 cmdutil.summaryhooks(ui, repo)
5497 cmdutil.summaryhooks(ui, repo)
5498
5498
5499 if opts.get('remote'):
5499 if opts.get('remote'):
5500 t = []
5500 t = []
5501 source, branches = hg.parseurl(ui.expandpath('default'))
5501 source, branches = hg.parseurl(ui.expandpath('default'))
5502 sbranch = branches[0]
5502 sbranch = branches[0]
5503 other = hg.peer(repo, {}, source)
5503 other = hg.peer(repo, {}, source)
5504 revs, checkout = hg.addbranchrevs(repo, other, branches, None)
5504 revs, checkout = hg.addbranchrevs(repo, other, branches, None)
5505 if revs:
5505 if revs:
5506 revs = [other.lookup(rev) for rev in revs]
5506 revs = [other.lookup(rev) for rev in revs]
5507 ui.debug('comparing with %s\n' % util.hidepassword(source))
5507 ui.debug('comparing with %s\n' % util.hidepassword(source))
5508 repo.ui.pushbuffer()
5508 repo.ui.pushbuffer()
5509 commoninc = discovery.findcommonincoming(repo, other, heads=revs)
5509 commoninc = discovery.findcommonincoming(repo, other, heads=revs)
5510 _common, incoming, _rheads = commoninc
5510 _common, incoming, _rheads = commoninc
5511 repo.ui.popbuffer()
5511 repo.ui.popbuffer()
5512 if incoming:
5512 if incoming:
5513 t.append(_('1 or more incoming'))
5513 t.append(_('1 or more incoming'))
5514
5514
5515 dest, branches = hg.parseurl(ui.expandpath('default-push', 'default'))
5515 dest, branches = hg.parseurl(ui.expandpath('default-push', 'default'))
5516 dbranch = branches[0]
5516 dbranch = branches[0]
5517 revs, checkout = hg.addbranchrevs(repo, repo, branches, None)
5517 revs, checkout = hg.addbranchrevs(repo, repo, branches, None)
5518 if source != dest:
5518 if source != dest:
5519 other = hg.peer(repo, {}, dest)
5519 other = hg.peer(repo, {}, dest)
5520 ui.debug('comparing with %s\n' % util.hidepassword(dest))
5520 ui.debug('comparing with %s\n' % util.hidepassword(dest))
5521 if (source != dest or (sbranch is not None and sbranch != dbranch)):
5521 if (source != dest or (sbranch is not None and sbranch != dbranch)):
5522 commoninc = None
5522 commoninc = None
5523 if revs:
5523 if revs:
5524 revs = [repo.lookup(rev) for rev in revs]
5524 revs = [repo.lookup(rev) for rev in revs]
5525 repo.ui.pushbuffer()
5525 repo.ui.pushbuffer()
5526 outgoing = discovery.findcommonoutgoing(repo, other, onlyheads=revs,
5526 outgoing = discovery.findcommonoutgoing(repo, other, onlyheads=revs,
5527 commoninc=commoninc)
5527 commoninc=commoninc)
5528 repo.ui.popbuffer()
5528 repo.ui.popbuffer()
5529 o = outgoing.missing
5529 o = outgoing.missing
5530 if o:
5530 if o:
5531 t.append(_('%d outgoing') % len(o))
5531 t.append(_('%d outgoing') % len(o))
5532 if 'bookmarks' in other.listkeys('namespaces'):
5532 if 'bookmarks' in other.listkeys('namespaces'):
5533 lmarks = repo.listkeys('bookmarks')
5533 lmarks = repo.listkeys('bookmarks')
5534 rmarks = other.listkeys('bookmarks')
5534 rmarks = other.listkeys('bookmarks')
5535 diff = set(rmarks) - set(lmarks)
5535 diff = set(rmarks) - set(lmarks)
5536 if len(diff) > 0:
5536 if len(diff) > 0:
5537 t.append(_('%d incoming bookmarks') % len(diff))
5537 t.append(_('%d incoming bookmarks') % len(diff))
5538 diff = set(lmarks) - set(rmarks)
5538 diff = set(lmarks) - set(rmarks)
5539 if len(diff) > 0:
5539 if len(diff) > 0:
5540 t.append(_('%d outgoing bookmarks') % len(diff))
5540 t.append(_('%d outgoing bookmarks') % len(diff))
5541
5541
5542 if t:
5542 if t:
5543 # i18n: column positioning for "hg summary"
5543 # i18n: column positioning for "hg summary"
5544 ui.write(_('remote: %s\n') % (', '.join(t)))
5544 ui.write(_('remote: %s\n') % (', '.join(t)))
5545 else:
5545 else:
5546 # i18n: column positioning for "hg summary"
5546 # i18n: column positioning for "hg summary"
5547 ui.status(_('remote: (synced)\n'))
5547 ui.status(_('remote: (synced)\n'))
5548
5548
5549 @command('tag',
5549 @command('tag',
5550 [('f', 'force', None, _('force tag')),
5550 [('f', 'force', None, _('force tag')),
5551 ('l', 'local', None, _('make the tag local')),
5551 ('l', 'local', None, _('make the tag local')),
5552 ('r', 'rev', '', _('revision to tag'), _('REV')),
5552 ('r', 'rev', '', _('revision to tag'), _('REV')),
5553 ('', 'remove', None, _('remove a tag')),
5553 ('', 'remove', None, _('remove a tag')),
5554 # -l/--local is already there, commitopts cannot be used
5554 # -l/--local is already there, commitopts cannot be used
5555 ('e', 'edit', None, _('edit commit message')),
5555 ('e', 'edit', None, _('edit commit message')),
5556 ('m', 'message', '', _('use <text> as commit message'), _('TEXT')),
5556 ('m', 'message', '', _('use <text> as commit message'), _('TEXT')),
5557 ] + commitopts2,
5557 ] + commitopts2,
5558 _('[-f] [-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME...'))
5558 _('[-f] [-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME...'))
5559 def tag(ui, repo, name1, *names, **opts):
5559 def tag(ui, repo, name1, *names, **opts):
5560 """add one or more tags for the current or given revision
5560 """add one or more tags for the current or given revision
5561
5561
5562 Name a particular revision using <name>.
5562 Name a particular revision using <name>.
5563
5563
5564 Tags are used to name particular revisions of the repository and are
5564 Tags are used to name particular revisions of the repository and are
5565 very useful to compare different revisions, to go back to significant
5565 very useful to compare different revisions, to go back to significant
5566 earlier versions or to mark branch points as releases, etc. Changing
5566 earlier versions or to mark branch points as releases, etc. Changing
5567 an existing tag is normally disallowed; use -f/--force to override.
5567 an existing tag is normally disallowed; use -f/--force to override.
5568
5568
5569 If no revision is given, the parent of the working directory is
5569 If no revision is given, the parent of the working directory is
5570 used.
5570 used.
5571
5571
5572 To facilitate version control, distribution, and merging of tags,
5572 To facilitate version control, distribution, and merging of tags,
5573 they are stored as a file named ".hgtags" which is managed similarly
5573 they are stored as a file named ".hgtags" which is managed similarly
5574 to other project files and can be hand-edited if necessary. This
5574 to other project files and can be hand-edited if necessary. This
5575 also means that tagging creates a new commit. The file
5575 also means that tagging creates a new commit. The file
5576 ".hg/localtags" is used for local tags (not shared among
5576 ".hg/localtags" is used for local tags (not shared among
5577 repositories).
5577 repositories).
5578
5578
5579 Tag commits are usually made at the head of a branch. If the parent
5579 Tag commits are usually made at the head of a branch. If the parent
5580 of the working directory is not a branch head, :hg:`tag` aborts; use
5580 of the working directory is not a branch head, :hg:`tag` aborts; use
5581 -f/--force to force the tag commit to be based on a non-head
5581 -f/--force to force the tag commit to be based on a non-head
5582 changeset.
5582 changeset.
5583
5583
5584 See :hg:`help dates` for a list of formats valid for -d/--date.
5584 See :hg:`help dates` for a list of formats valid for -d/--date.
5585
5585
5586 Since tag names have priority over branch names during revision
5586 Since tag names have priority over branch names during revision
5587 lookup, using an existing branch name as a tag name is discouraged.
5587 lookup, using an existing branch name as a tag name is discouraged.
5588
5588
5589 Returns 0 on success.
5589 Returns 0 on success.
5590 """
5590 """
5591 wlock = lock = None
5591 wlock = lock = None
5592 try:
5592 try:
5593 wlock = repo.wlock()
5593 wlock = repo.wlock()
5594 lock = repo.lock()
5594 lock = repo.lock()
5595 rev_ = "."
5595 rev_ = "."
5596 names = [t.strip() for t in (name1,) + names]
5596 names = [t.strip() for t in (name1,) + names]
5597 if len(names) != len(set(names)):
5597 if len(names) != len(set(names)):
5598 raise util.Abort(_('tag names must be unique'))
5598 raise util.Abort(_('tag names must be unique'))
5599 for n in names:
5599 for n in names:
5600 scmutil.checknewlabel(repo, n, 'tag')
5600 scmutil.checknewlabel(repo, n, 'tag')
5601 if not n:
5601 if not n:
5602 raise util.Abort(_('tag names cannot consist entirely of '
5602 raise util.Abort(_('tag names cannot consist entirely of '
5603 'whitespace'))
5603 'whitespace'))
5604 if opts.get('rev') and opts.get('remove'):
5604 if opts.get('rev') and opts.get('remove'):
5605 raise util.Abort(_("--rev and --remove are incompatible"))
5605 raise util.Abort(_("--rev and --remove are incompatible"))
5606 if opts.get('rev'):
5606 if opts.get('rev'):
5607 rev_ = opts['rev']
5607 rev_ = opts['rev']
5608 message = opts.get('message')
5608 message = opts.get('message')
5609 if opts.get('remove'):
5609 if opts.get('remove'):
5610 expectedtype = opts.get('local') and 'local' or 'global'
5610 expectedtype = opts.get('local') and 'local' or 'global'
5611 for n in names:
5611 for n in names:
5612 if not repo.tagtype(n):
5612 if not repo.tagtype(n):
5613 raise util.Abort(_("tag '%s' does not exist") % n)
5613 raise util.Abort(_("tag '%s' does not exist") % n)
5614 if repo.tagtype(n) != expectedtype:
5614 if repo.tagtype(n) != expectedtype:
5615 if expectedtype == 'global':
5615 if expectedtype == 'global':
5616 raise util.Abort(_("tag '%s' is not a global tag") % n)
5616 raise util.Abort(_("tag '%s' is not a global tag") % n)
5617 else:
5617 else:
5618 raise util.Abort(_("tag '%s' is not a local tag") % n)
5618 raise util.Abort(_("tag '%s' is not a local tag") % n)
5619 rev_ = nullid
5619 rev_ = nullid
5620 if not message:
5620 if not message:
5621 # we don't translate commit messages
5621 # we don't translate commit messages
5622 message = 'Removed tag %s' % ', '.join(names)
5622 message = 'Removed tag %s' % ', '.join(names)
5623 elif not opts.get('force'):
5623 elif not opts.get('force'):
5624 for n in names:
5624 for n in names:
5625 if n in repo.tags():
5625 if n in repo.tags():
5626 raise util.Abort(_("tag '%s' already exists "
5626 raise util.Abort(_("tag '%s' already exists "
5627 "(use -f to force)") % n)
5627 "(use -f to force)") % n)
5628 if not opts.get('local'):
5628 if not opts.get('local'):
5629 p1, p2 = repo.dirstate.parents()
5629 p1, p2 = repo.dirstate.parents()
5630 if p2 != nullid:
5630 if p2 != nullid:
5631 raise util.Abort(_('uncommitted merge'))
5631 raise util.Abort(_('uncommitted merge'))
5632 bheads = repo.branchheads()
5632 bheads = repo.branchheads()
5633 if not opts.get('force') and bheads and p1 not in bheads:
5633 if not opts.get('force') and bheads and p1 not in bheads:
5634 raise util.Abort(_('not at a branch head (use -f to force)'))
5634 raise util.Abort(_('not at a branch head (use -f to force)'))
5635 r = scmutil.revsingle(repo, rev_).node()
5635 r = scmutil.revsingle(repo, rev_).node()
5636
5636
5637 if not message:
5637 if not message:
5638 # we don't translate commit messages
5638 # we don't translate commit messages
5639 message = ('Added tag %s for changeset %s' %
5639 message = ('Added tag %s for changeset %s' %
5640 (', '.join(names), short(r)))
5640 (', '.join(names), short(r)))
5641
5641
5642 date = opts.get('date')
5642 date = opts.get('date')
5643 if date:
5643 if date:
5644 date = util.parsedate(date)
5644 date = util.parsedate(date)
5645
5645
5646 if opts.get('edit'):
5646 if opts.get('edit'):
5647 message = ui.edit(message, ui.username())
5647 message = ui.edit(message, ui.username())
5648
5648
5649 # don't allow tagging the null rev
5649 # don't allow tagging the null rev
5650 if (not opts.get('remove') and
5650 if (not opts.get('remove') and
5651 scmutil.revsingle(repo, rev_).rev() == nullrev):
5651 scmutil.revsingle(repo, rev_).rev() == nullrev):
5652 raise util.Abort(_("cannot tag null revision"))
5652 raise util.Abort(_("cannot tag null revision"))
5653
5653
5654 repo.tag(names, r, message, opts.get('local'), opts.get('user'), date)
5654 repo.tag(names, r, message, opts.get('local'), opts.get('user'), date)
5655 finally:
5655 finally:
5656 release(lock, wlock)
5656 release(lock, wlock)
5657
5657
5658 @command('tags', [], '')
5658 @command('tags', [], '')
5659 def tags(ui, repo, **opts):
5659 def tags(ui, repo, **opts):
5660 """list repository tags
5660 """list repository tags
5661
5661
5662 This lists both regular and local tags. When the -v/--verbose
5662 This lists both regular and local tags. When the -v/--verbose
5663 switch is used, a third column "local" is printed for local tags.
5663 switch is used, a third column "local" is printed for local tags.
5664
5664
5665 Returns 0 on success.
5665 Returns 0 on success.
5666 """
5666 """
5667
5667
5668 fm = ui.formatter('tags', opts)
5668 fm = ui.formatter('tags', opts)
5669 hexfunc = ui.debugflag and hex or short
5669 hexfunc = ui.debugflag and hex or short
5670 tagtype = ""
5670 tagtype = ""
5671
5671
5672 for t, n in reversed(repo.tagslist()):
5672 for t, n in reversed(repo.tagslist()):
5673 hn = hexfunc(n)
5673 hn = hexfunc(n)
5674 label = 'tags.normal'
5674 label = 'tags.normal'
5675 tagtype = ''
5675 tagtype = ''
5676 if repo.tagtype(t) == 'local':
5676 if repo.tagtype(t) == 'local':
5677 label = 'tags.local'
5677 label = 'tags.local'
5678 tagtype = 'local'
5678 tagtype = 'local'
5679
5679
5680 fm.startitem()
5680 fm.startitem()
5681 fm.write('tag', '%s', t, label=label)
5681 fm.write('tag', '%s', t, label=label)
5682 fmt = " " * (30 - encoding.colwidth(t)) + ' %5d:%s'
5682 fmt = " " * (30 - encoding.colwidth(t)) + ' %5d:%s'
5683 fm.condwrite(not ui.quiet, 'rev id', fmt,
5683 fm.condwrite(not ui.quiet, 'rev id', fmt,
5684 repo.changelog.rev(n), hn, label=label)
5684 repo.changelog.rev(n), hn, label=label)
5685 fm.condwrite(ui.verbose and tagtype, 'type', ' %s',
5685 fm.condwrite(ui.verbose and tagtype, 'type', ' %s',
5686 tagtype, label=label)
5686 tagtype, label=label)
5687 fm.plain('\n')
5687 fm.plain('\n')
5688 fm.end()
5688 fm.end()
5689
5689
5690 @command('tip',
5690 @command('tip',
5691 [('p', 'patch', None, _('show patch')),
5691 [('p', 'patch', None, _('show patch')),
5692 ('g', 'git', None, _('use git extended diff format')),
5692 ('g', 'git', None, _('use git extended diff format')),
5693 ] + templateopts,
5693 ] + templateopts,
5694 _('[-p] [-g]'))
5694 _('[-p] [-g]'))
5695 def tip(ui, repo, **opts):
5695 def tip(ui, repo, **opts):
5696 """show the tip revision (DEPRECATED)
5696 """show the tip revision (DEPRECATED)
5697
5697
5698 The tip revision (usually just called the tip) is the changeset
5698 The tip revision (usually just called the tip) is the changeset
5699 most recently added to the repository (and therefore the most
5699 most recently added to the repository (and therefore the most
5700 recently changed head).
5700 recently changed head).
5701
5701
5702 If you have just made a commit, that commit will be the tip. If
5702 If you have just made a commit, that commit will be the tip. If
5703 you have just pulled changes from another repository, the tip of
5703 you have just pulled changes from another repository, the tip of
5704 that repository becomes the current tip. The "tip" tag is special
5704 that repository becomes the current tip. The "tip" tag is special
5705 and cannot be renamed or assigned to a different changeset.
5705 and cannot be renamed or assigned to a different changeset.
5706
5706
5707 This command is deprecated, please use :hg:`heads` instead.
5707 This command is deprecated, please use :hg:`heads` instead.
5708
5708
5709 Returns 0 on success.
5709 Returns 0 on success.
5710 """
5710 """
5711 displayer = cmdutil.show_changeset(ui, repo, opts)
5711 displayer = cmdutil.show_changeset(ui, repo, opts)
5712 displayer.show(repo['tip'])
5712 displayer.show(repo['tip'])
5713 displayer.close()
5713 displayer.close()
5714
5714
5715 @command('unbundle',
5715 @command('unbundle',
5716 [('u', 'update', None,
5716 [('u', 'update', None,
5717 _('update to new branch head if changesets were unbundled'))],
5717 _('update to new branch head if changesets were unbundled'))],
5718 _('[-u] FILE...'))
5718 _('[-u] FILE...'))
5719 def unbundle(ui, repo, fname1, *fnames, **opts):
5719 def unbundle(ui, repo, fname1, *fnames, **opts):
5720 """apply one or more changegroup files
5720 """apply one or more changegroup files
5721
5721
5722 Apply one or more compressed changegroup files generated by the
5722 Apply one or more compressed changegroup files generated by the
5723 bundle command.
5723 bundle command.
5724
5724
5725 Returns 0 on success, 1 if an update has unresolved files.
5725 Returns 0 on success, 1 if an update has unresolved files.
5726 """
5726 """
5727 fnames = (fname1,) + fnames
5727 fnames = (fname1,) + fnames
5728
5728
5729 lock = repo.lock()
5729 lock = repo.lock()
5730 wc = repo['.']
5730 wc = repo['.']
5731 try:
5731 try:
5732 for fname in fnames:
5732 for fname in fnames:
5733 f = hg.openpath(ui, fname)
5733 f = hg.openpath(ui, fname)
5734 gen = changegroup.readbundle(f, fname)
5734 gen = changegroup.readbundle(f, fname)
5735 modheads = repo.addchangegroup(gen, 'unbundle', 'bundle:' + fname)
5735 modheads = repo.addchangegroup(gen, 'unbundle', 'bundle:' + fname)
5736 finally:
5736 finally:
5737 lock.release()
5737 lock.release()
5738 bookmarks.updatecurrentbookmark(repo, wc.node(), wc.branch())
5738 bookmarks.updatecurrentbookmark(repo, wc.node(), wc.branch())
5739 return postincoming(ui, repo, modheads, opts.get('update'), None)
5739 return postincoming(ui, repo, modheads, opts.get('update'), None)
5740
5740
5741 @command('^update|up|checkout|co',
5741 @command('^update|up|checkout|co',
5742 [('C', 'clean', None, _('discard uncommitted changes (no backup)')),
5742 [('C', 'clean', None, _('discard uncommitted changes (no backup)')),
5743 ('c', 'check', None,
5743 ('c', 'check', None,
5744 _('update across branches if no uncommitted changes')),
5744 _('update across branches if no uncommitted changes')),
5745 ('d', 'date', '', _('tipmost revision matching date'), _('DATE')),
5745 ('d', 'date', '', _('tipmost revision matching date'), _('DATE')),
5746 ('r', 'rev', '', _('revision'), _('REV'))],
5746 ('r', 'rev', '', _('revision'), _('REV'))],
5747 _('[-c] [-C] [-d DATE] [[-r] REV]'))
5747 _('[-c] [-C] [-d DATE] [[-r] REV]'))
5748 def update(ui, repo, node=None, rev=None, clean=False, date=None, check=False):
5748 def update(ui, repo, node=None, rev=None, clean=False, date=None, check=False):
5749 """update working directory (or switch revisions)
5749 """update working directory (or switch revisions)
5750
5750
5751 Update the repository's working directory to the specified
5751 Update the repository's working directory to the specified
5752 changeset. If no changeset is specified, update to the tip of the
5752 changeset. If no changeset is specified, update to the tip of the
5753 current named branch and move the current bookmark (see :hg:`help
5753 current named branch and move the current bookmark (see :hg:`help
5754 bookmarks`).
5754 bookmarks`).
5755
5755
5756 Update sets the working directory's parent revision to the specified
5756 Update sets the working directory's parent revision to the specified
5757 changeset (see :hg:`help parents`).
5757 changeset (see :hg:`help parents`).
5758
5758
5759 If the changeset is not a descendant or ancestor of the working
5759 If the changeset is not a descendant or ancestor of the working
5760 directory's parent, the update is aborted. With the -c/--check
5760 directory's parent, the update is aborted. With the -c/--check
5761 option, the working directory is checked for uncommitted changes; if
5761 option, the working directory is checked for uncommitted changes; if
5762 none are found, the working directory is updated to the specified
5762 none are found, the working directory is updated to the specified
5763 changeset.
5763 changeset.
5764
5764
5765 .. container:: verbose
5765 .. container:: verbose
5766
5766
5767 The following rules apply when the working directory contains
5767 The following rules apply when the working directory contains
5768 uncommitted changes:
5768 uncommitted changes:
5769
5769
5770 1. If neither -c/--check nor -C/--clean is specified, and if
5770 1. If neither -c/--check nor -C/--clean is specified, and if
5771 the requested changeset is an ancestor or descendant of
5771 the requested changeset is an ancestor or descendant of
5772 the working directory's parent, the uncommitted changes
5772 the working directory's parent, the uncommitted changes
5773 are merged into the requested changeset and the merged
5773 are merged into the requested changeset and the merged
5774 result is left uncommitted. If the requested changeset is
5774 result is left uncommitted. If the requested changeset is
5775 not an ancestor or descendant (that is, it is on another
5775 not an ancestor or descendant (that is, it is on another
5776 branch), the update is aborted and the uncommitted changes
5776 branch), the update is aborted and the uncommitted changes
5777 are preserved.
5777 are preserved.
5778
5778
5779 2. With the -c/--check option, the update is aborted and the
5779 2. With the -c/--check option, the update is aborted and the
5780 uncommitted changes are preserved.
5780 uncommitted changes are preserved.
5781
5781
5782 3. With the -C/--clean option, uncommitted changes are discarded and
5782 3. With the -C/--clean option, uncommitted changes are discarded and
5783 the working directory is updated to the requested changeset.
5783 the working directory is updated to the requested changeset.
5784
5784
5785 To cancel an uncommitted merge (and lose your changes), use
5785 To cancel an uncommitted merge (and lose your changes), use
5786 :hg:`update --clean .`.
5786 :hg:`update --clean .`.
5787
5787
5788 Use null as the changeset to remove the working directory (like
5788 Use null as the changeset to remove the working directory (like
5789 :hg:`clone -U`).
5789 :hg:`clone -U`).
5790
5790
5791 If you want to revert just one file to an older revision, use
5791 If you want to revert just one file to an older revision, use
5792 :hg:`revert [-r REV] NAME`.
5792 :hg:`revert [-r REV] NAME`.
5793
5793
5794 See :hg:`help dates` for a list of formats valid for -d/--date.
5794 See :hg:`help dates` for a list of formats valid for -d/--date.
5795
5795
5796 Returns 0 on success, 1 if there are unresolved files.
5796 Returns 0 on success, 1 if there are unresolved files.
5797 """
5797 """
5798 if rev and node:
5798 if rev and node:
5799 raise util.Abort(_("please specify just one revision"))
5799 raise util.Abort(_("please specify just one revision"))
5800
5800
5801 if rev is None or rev == '':
5801 if rev is None or rev == '':
5802 rev = node
5802 rev = node
5803
5803
5804 cmdutil.clearunfinished(repo)
5804 cmdutil.clearunfinished(repo)
5805
5805
5806 # with no argument, we also move the current bookmark, if any
5806 # with no argument, we also move the current bookmark, if any
5807 rev, movemarkfrom = bookmarks.calculateupdate(ui, repo, rev)
5807 rev, movemarkfrom = bookmarks.calculateupdate(ui, repo, rev)
5808
5808
5809 # if we defined a bookmark, we have to remember the original bookmark name
5809 # if we defined a bookmark, we have to remember the original bookmark name
5810 brev = rev
5810 brev = rev
5811 rev = scmutil.revsingle(repo, rev, rev).rev()
5811 rev = scmutil.revsingle(repo, rev, rev).rev()
5812
5812
5813 if check and clean:
5813 if check and clean:
5814 raise util.Abort(_("cannot specify both -c/--check and -C/--clean"))
5814 raise util.Abort(_("cannot specify both -c/--check and -C/--clean"))
5815
5815
5816 if date:
5816 if date:
5817 if rev is not None:
5817 if rev is not None:
5818 raise util.Abort(_("you can't specify a revision and a date"))
5818 raise util.Abort(_("you can't specify a revision and a date"))
5819 rev = cmdutil.finddate(ui, repo, date)
5819 rev = cmdutil.finddate(ui, repo, date)
5820
5820
5821 if check:
5821 if check:
5822 c = repo[None]
5822 c = repo[None]
5823 if c.dirty(merge=False, branch=False, missing=True):
5823 if c.dirty(merge=False, branch=False, missing=True):
5824 raise util.Abort(_("uncommitted changes"))
5824 raise util.Abort(_("uncommitted changes"))
5825 if rev is None:
5825 if rev is None:
5826 rev = repo[repo[None].branch()].rev()
5826 rev = repo[repo[None].branch()].rev()
5827 mergemod._checkunknown(repo, repo[None], repo[rev])
5827 mergemod._checkunknown(repo, repo[None], repo[rev])
5828
5828
5829 if clean:
5829 if clean:
5830 ret = hg.clean(repo, rev)
5830 ret = hg.clean(repo, rev)
5831 else:
5831 else:
5832 ret = hg.update(repo, rev)
5832 ret = hg.update(repo, rev)
5833
5833
5834 if not ret and movemarkfrom:
5834 if not ret and movemarkfrom:
5835 if bookmarks.update(repo, [movemarkfrom], repo['.'].node()):
5835 if bookmarks.update(repo, [movemarkfrom], repo['.'].node()):
5836 ui.status(_("updating bookmark %s\n") % repo._bookmarkcurrent)
5836 ui.status(_("updating bookmark %s\n") % repo._bookmarkcurrent)
5837 elif brev in repo._bookmarks:
5837 elif brev in repo._bookmarks:
5838 bookmarks.setcurrent(repo, brev)
5838 bookmarks.setcurrent(repo, brev)
5839 elif brev:
5839 elif brev:
5840 bookmarks.unsetcurrent(repo)
5840 bookmarks.unsetcurrent(repo)
5841
5841
5842 return ret
5842 return ret
5843
5843
5844 @command('verify', [])
5844 @command('verify', [])
5845 def verify(ui, repo):
5845 def verify(ui, repo):
5846 """verify the integrity of the repository
5846 """verify the integrity of the repository
5847
5847
5848 Verify the integrity of the current repository.
5848 Verify the integrity of the current repository.
5849
5849
5850 This will perform an extensive check of the repository's
5850 This will perform an extensive check of the repository's
5851 integrity, validating the hashes and checksums of each entry in
5851 integrity, validating the hashes and checksums of each entry in
5852 the changelog, manifest, and tracked files, as well as the
5852 the changelog, manifest, and tracked files, as well as the
5853 integrity of their crosslinks and indices.
5853 integrity of their crosslinks and indices.
5854
5854
5855 Please see http://mercurial.selenic.com/wiki/RepositoryCorruption
5855 Please see http://mercurial.selenic.com/wiki/RepositoryCorruption
5856 for more information about recovery from corruption of the
5856 for more information about recovery from corruption of the
5857 repository.
5857 repository.
5858
5858
5859 Returns 0 on success, 1 if errors are encountered.
5859 Returns 0 on success, 1 if errors are encountered.
5860 """
5860 """
5861 return hg.verify(repo)
5861 return hg.verify(repo)
5862
5862
5863 @command('version', [])
5863 @command('version', [])
5864 def version_(ui):
5864 def version_(ui):
5865 """output version and copyright information"""
5865 """output version and copyright information"""
5866 ui.write(_("Mercurial Distributed SCM (version %s)\n")
5866 ui.write(_("Mercurial Distributed SCM (version %s)\n")
5867 % util.version())
5867 % util.version())
5868 ui.status(_(
5868 ui.status(_(
5869 "(see http://mercurial.selenic.com for more information)\n"
5869 "(see http://mercurial.selenic.com for more information)\n"
5870 "\nCopyright (C) 2005-2014 Matt Mackall and others\n"
5870 "\nCopyright (C) 2005-2014 Matt Mackall and others\n"
5871 "This is free software; see the source for copying conditions. "
5871 "This is free software; see the source for copying conditions. "
5872 "There is NO\nwarranty; "
5872 "There is NO\nwarranty; "
5873 "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
5873 "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
5874 ))
5874 ))
5875
5875
5876 norepo = ("clone init version help debugcommands debugcomplete"
5876 norepo = ("clone init version help debugcommands debugcomplete"
5877 " debugdate debuginstall debugfsinfo debugpushkey debugwireargs"
5877 " debugdate debuginstall debugfsinfo debugpushkey debugwireargs"
5878 " debugknown debuggetbundle debugbundle")
5878 " debugknown debuggetbundle debugbundle")
5879 optionalrepo = ("identify paths serve config showconfig debugancestor debugdag"
5879 optionalrepo = ("identify paths serve config showconfig debugancestor debugdag"
5880 " debugdata debugindex debugindexdot debugrevlog")
5880 " debugdata debugindex debugindexdot debugrevlog")
5881 inferrepo = ("add addremove annotate cat commit diff grep forget log parents"
5881 inferrepo = ("add addremove annotate cat commit diff grep forget log parents"
5882 " remove resolve status debugwalk")
5882 " remove resolve status debugwalk")
@@ -1,2003 +1,2003 b''
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 pull pull changes from the specified source
18 pull pull changes from the specified source
19 push push changes to the specified destination
19 push push changes to the specified destination
20 remove remove the specified files on the next commit
20 remove remove the specified files on the next commit
21 serve start stand-alone webserver
21 serve start stand-alone webserver
22 status show changed files in the working directory
22 status show changed files in the working directory
23 summary summarize working directory state
23 summary summarize working directory state
24 update update working directory (or switch revisions)
24 update update working directory (or switch revisions)
25
25
26 use "hg help" for the full list of commands or "hg -v" for details
26 use "hg help" for the full list of commands or "hg -v" for details
27
27
28 $ hg -q
28 $ hg -q
29 add add the specified files on the next commit
29 add add the specified files on the next commit
30 annotate show changeset information by line for each file
30 annotate show changeset information by line for each file
31 clone make a copy of an existing repository
31 clone make a copy of an existing repository
32 commit commit the specified files or all outstanding changes
32 commit commit the specified files or all outstanding changes
33 diff diff repository (or selected files)
33 diff diff repository (or selected files)
34 export dump the header and diffs for one or more changesets
34 export dump the header and diffs for one or more changesets
35 forget forget the specified files on the next commit
35 forget forget the specified files on the next commit
36 init create a new repository in the given directory
36 init create a new repository in the given directory
37 log show revision history of entire repository or files
37 log show revision history of entire repository or files
38 merge merge working directory with another revision
38 merge merge working directory with another revision
39 pull pull changes from the specified source
39 pull pull changes from the specified source
40 push push changes to the specified destination
40 push push changes to the specified destination
41 remove remove the specified files on the next commit
41 remove remove the specified files on the next commit
42 serve start stand-alone webserver
42 serve start stand-alone webserver
43 status show changed files in the working directory
43 status show changed files in the working directory
44 summary summarize working directory state
44 summary summarize working directory state
45 update update working directory (or switch revisions)
45 update update working directory (or switch revisions)
46
46
47 $ hg help
47 $ hg help
48 Mercurial Distributed SCM
48 Mercurial Distributed SCM
49
49
50 list of commands:
50 list of commands:
51
51
52 add add the specified files on the next commit
52 add add the specified files on the next commit
53 addremove add all new files, delete all missing files
53 addremove add all new files, delete all missing files
54 annotate show changeset information by line for each file
54 annotate show changeset information by line for each file
55 archive create an unversioned archive of a repository revision
55 archive create an unversioned archive of a repository revision
56 backout reverse effect of earlier changeset
56 backout reverse effect of earlier changeset
57 bisect subdivision search of changesets
57 bisect subdivision search of changesets
58 bookmarks track a line of development with movable markers
58 bookmarks track a line of development with movable markers
59 branch set or show the current branch name
59 branch set or show the current branch name
60 branches list repository named branches
60 branches list repository named branches
61 bundle create a changegroup file
61 bundle create a changegroup file
62 cat output the current or given revision of files
62 cat output the current or given revision of files
63 clone make a copy of an existing repository
63 clone make a copy of an existing repository
64 commit commit the specified files or all outstanding changes
64 commit commit the specified files or all outstanding changes
65 config show combined config settings from all hgrc files
65 config show combined config settings from all hgrc files
66 copy mark files as copied for the next commit
66 copy mark files as copied for the next commit
67 diff diff repository (or selected files)
67 diff diff repository (or selected files)
68 export dump the header and diffs for one or more changesets
68 export dump the header and diffs for one or more changesets
69 forget forget the specified files on the next commit
69 forget forget the specified files on the next commit
70 graft copy changes from other branches onto the current branch
70 graft copy changes from other branches onto the current branch
71 grep search for a pattern in specified files and revisions
71 grep search for a pattern in specified files and revisions
72 heads show branch heads
72 heads show branch heads
73 help show help for a given topic or a help overview
73 help show help for a given topic or a help overview
74 identify identify the working copy or specified revision
74 identify identify the working copy or specified revision
75 import import an ordered set of patches
75 import import an ordered set of patches
76 incoming show new changesets found in source
76 incoming show new changesets found in source
77 init create a new repository in the given directory
77 init create a new repository in the given directory
78 locate locate files matching specific patterns
78 locate locate files matching specific patterns
79 log show revision history of entire repository or files
79 log show revision history of entire repository or files
80 manifest output the current or given revision of the project manifest
80 manifest output the current or given revision of the project manifest
81 merge merge working directory with another revision
81 merge merge working directory with another revision
82 outgoing show changesets not found in the destination
82 outgoing show changesets not found in the destination
83 parents show the parents of the working directory or revision
83 parents show the parents of the working directory or revision
84 paths show aliases for remote repositories
84 paths show aliases for remote repositories
85 phase set or show the current phase name
85 phase set or show the current phase name
86 pull pull changes from the specified source
86 pull pull changes from the specified source
87 push push changes to the specified destination
87 push push changes to the specified destination
88 recover roll back an interrupted transaction
88 recover roll back an interrupted transaction
89 remove remove the specified files on the next commit
89 remove remove the specified files on the next commit
90 rename rename files; equivalent of copy + remove
90 rename rename files; equivalent of copy + remove
91 resolve redo merges or set/view the merge status of files
91 resolve redo merges or set/view the merge status of files
92 revert restore files to their checkout state
92 revert restore files to their checkout state
93 root print the root (top) of the current working directory
93 root print the root (top) of the current working directory
94 serve start stand-alone webserver
94 serve start stand-alone webserver
95 status show changed files in the working directory
95 status show changed files in the working directory
96 summary summarize working directory state
96 summary summarize working directory state
97 tag add one or more tags for the current or given revision
97 tag add one or more tags for the current or given revision
98 tags list repository tags
98 tags list repository tags
99 unbundle apply one or more changegroup files
99 unbundle apply one or more changegroup files
100 update update working directory (or switch revisions)
100 update update working directory (or switch revisions)
101 verify verify the integrity of the repository
101 verify verify the integrity of the repository
102 version output version and copyright information
102 version output version and copyright information
103
103
104 additional help topics:
104 additional help topics:
105
105
106 config Configuration Files
106 config Configuration Files
107 dates Date Formats
107 dates Date Formats
108 diffs Diff Formats
108 diffs Diff Formats
109 environment Environment Variables
109 environment Environment Variables
110 extensions Using Additional Features
110 extensions Using Additional Features
111 filesets Specifying File Sets
111 filesets Specifying File Sets
112 glossary Glossary
112 glossary Glossary
113 hgignore Syntax for Mercurial Ignore Files
113 hgignore Syntax for Mercurial Ignore Files
114 hgweb Configuring hgweb
114 hgweb Configuring hgweb
115 merge-tools Merge Tools
115 merge-tools Merge Tools
116 multirevs Specifying Multiple Revisions
116 multirevs Specifying Multiple Revisions
117 patterns File Name Patterns
117 patterns File Name Patterns
118 phases Working with Phases
118 phases Working with Phases
119 revisions Specifying Single Revisions
119 revisions Specifying Single Revisions
120 revsets Specifying Revision Sets
120 revsets Specifying Revision Sets
121 subrepos Subrepositories
121 subrepos Subrepositories
122 templating Template Usage
122 templating Template Usage
123 urls URL Paths
123 urls URL Paths
124
124
125 use "hg -v help" to show builtin aliases and global options
125 use "hg -v help" to show builtin aliases and global options
126
126
127 $ hg -q help
127 $ hg -q help
128 add add the specified files on the next commit
128 add add the specified files on the next commit
129 addremove add all new files, delete all missing files
129 addremove add all new files, delete all missing files
130 annotate show changeset information by line for each file
130 annotate show changeset information by line for each file
131 archive create an unversioned archive of a repository revision
131 archive create an unversioned archive of a repository revision
132 backout reverse effect of earlier changeset
132 backout reverse effect of earlier changeset
133 bisect subdivision search of changesets
133 bisect subdivision search of changesets
134 bookmarks track a line of development with movable markers
134 bookmarks track a line of development with movable markers
135 branch set or show the current branch name
135 branch set or show the current branch name
136 branches list repository named branches
136 branches list repository named branches
137 bundle create a changegroup file
137 bundle create a changegroup file
138 cat output the current or given revision of files
138 cat output the current or given revision of files
139 clone make a copy of an existing repository
139 clone make a copy of an existing repository
140 commit commit the specified files or all outstanding changes
140 commit commit the specified files or all outstanding changes
141 config show combined config settings from all hgrc files
141 config show combined config settings from all hgrc files
142 copy mark files as copied for the next commit
142 copy mark files as copied for the next commit
143 diff diff repository (or selected files)
143 diff diff repository (or selected files)
144 export dump the header and diffs for one or more changesets
144 export dump the header and diffs for one or more changesets
145 forget forget the specified files on the next commit
145 forget forget the specified files on the next commit
146 graft copy changes from other branches onto the current branch
146 graft copy changes from other branches onto the current branch
147 grep search for a pattern in specified files and revisions
147 grep search for a pattern in specified files and revisions
148 heads show branch heads
148 heads show branch heads
149 help show help for a given topic or a help overview
149 help show help for a given topic or a help overview
150 identify identify the working copy or specified revision
150 identify identify the working copy or specified revision
151 import import an ordered set of patches
151 import import an ordered set of patches
152 incoming show new changesets found in source
152 incoming show new changesets found in source
153 init create a new repository in the given directory
153 init create a new repository in the given directory
154 locate locate files matching specific patterns
154 locate locate files matching specific patterns
155 log show revision history of entire repository or files
155 log show revision history of entire repository or files
156 manifest output the current or given revision of the project manifest
156 manifest output the current or given revision of the project manifest
157 merge merge working directory with another revision
157 merge merge working directory with another revision
158 outgoing show changesets not found in the destination
158 outgoing show changesets not found in the destination
159 parents show the parents of the working directory or revision
159 parents show the parents of the working directory or revision
160 paths show aliases for remote repositories
160 paths show aliases for remote repositories
161 phase set or show the current phase name
161 phase set or show the current phase name
162 pull pull changes from the specified source
162 pull pull changes from the specified source
163 push push changes to the specified destination
163 push push changes to the specified destination
164 recover roll back an interrupted transaction
164 recover roll back an interrupted transaction
165 remove remove the specified files on the next commit
165 remove remove the specified files on the next commit
166 rename rename files; equivalent of copy + remove
166 rename rename files; equivalent of copy + remove
167 resolve redo merges or set/view the merge status of files
167 resolve redo merges or set/view the merge status of files
168 revert restore files to their checkout state
168 revert restore files to their checkout state
169 root print the root (top) of the current working directory
169 root print the root (top) of the current working directory
170 serve start stand-alone webserver
170 serve start stand-alone webserver
171 status show changed files in the working directory
171 status show changed files in the working directory
172 summary summarize working directory state
172 summary summarize working directory state
173 tag add one or more tags for the current or given revision
173 tag add one or more tags for the current or given revision
174 tags list repository tags
174 tags list repository tags
175 unbundle apply one or more changegroup files
175 unbundle apply one or more changegroup files
176 update update working directory (or switch revisions)
176 update update working directory (or switch revisions)
177 verify verify the integrity of the repository
177 verify verify the integrity of the repository
178 version output version and copyright information
178 version output version and copyright information
179
179
180 additional help topics:
180 additional help topics:
181
181
182 config Configuration Files
182 config Configuration Files
183 dates Date Formats
183 dates Date Formats
184 diffs Diff Formats
184 diffs Diff Formats
185 environment Environment Variables
185 environment Environment Variables
186 extensions Using Additional Features
186 extensions Using Additional Features
187 filesets Specifying File Sets
187 filesets Specifying File Sets
188 glossary Glossary
188 glossary Glossary
189 hgignore Syntax for Mercurial Ignore Files
189 hgignore Syntax for Mercurial Ignore Files
190 hgweb Configuring hgweb
190 hgweb Configuring hgweb
191 merge-tools Merge Tools
191 merge-tools Merge Tools
192 multirevs Specifying Multiple Revisions
192 multirevs Specifying Multiple Revisions
193 patterns File Name Patterns
193 patterns File Name Patterns
194 phases Working with Phases
194 phases Working with Phases
195 revisions Specifying Single Revisions
195 revisions Specifying Single Revisions
196 revsets Specifying Revision Sets
196 revsets Specifying Revision Sets
197 subrepos Subrepositories
197 subrepos Subrepositories
198 templating Template Usage
198 templating Template Usage
199 urls URL Paths
199 urls URL Paths
200
200
201 Test extension help:
201 Test extension help:
202 $ hg help extensions --config extensions.rebase= --config extensions.children=
202 $ hg help extensions --config extensions.rebase= --config extensions.children=
203 Using Additional Features
203 Using Additional Features
204 """""""""""""""""""""""""
204 """""""""""""""""""""""""
205
205
206 Mercurial has the ability to add new features through the use of
206 Mercurial has the ability to add new features through the use of
207 extensions. Extensions may add new commands, add options to existing
207 extensions. Extensions may add new commands, add options to existing
208 commands, change the default behavior of commands, or implement hooks.
208 commands, change the default behavior of commands, or implement hooks.
209
209
210 To enable the "foo" extension, either shipped with Mercurial or in the
210 To enable the "foo" extension, either shipped with Mercurial or in the
211 Python search path, create an entry for it in your configuration file,
211 Python search path, create an entry for it in your configuration file,
212 like this:
212 like this:
213
213
214 [extensions]
214 [extensions]
215 foo =
215 foo =
216
216
217 You may also specify the full path to an extension:
217 You may also specify the full path to an extension:
218
218
219 [extensions]
219 [extensions]
220 myfeature = ~/.hgext/myfeature.py
220 myfeature = ~/.hgext/myfeature.py
221
221
222 See "hg help config" for more information on configuration files.
222 See "hg help config" for more information on configuration files.
223
223
224 Extensions are not loaded by default for a variety of reasons: they can
224 Extensions are not loaded by default for a variety of reasons: they can
225 increase startup overhead; they may be meant for advanced usage only; they
225 increase startup overhead; they may be meant for advanced usage only; they
226 may provide potentially dangerous abilities (such as letting you destroy
226 may provide potentially dangerous abilities (such as letting you destroy
227 or modify history); they might not be ready for prime time; or they may
227 or modify history); they might not be ready for prime time; or they may
228 alter some usual behaviors of stock Mercurial. It is thus up to the user
228 alter some usual behaviors of stock Mercurial. It is thus up to the user
229 to activate extensions as needed.
229 to activate extensions as needed.
230
230
231 To explicitly disable an extension enabled in a configuration file of
231 To explicitly disable an extension enabled in a configuration file of
232 broader scope, prepend its path with !:
232 broader scope, prepend its path with !:
233
233
234 [extensions]
234 [extensions]
235 # disabling extension bar residing in /path/to/extension/bar.py
235 # disabling extension bar residing in /path/to/extension/bar.py
236 bar = !/path/to/extension/bar.py
236 bar = !/path/to/extension/bar.py
237 # ditto, but no path was supplied for extension baz
237 # ditto, but no path was supplied for extension baz
238 baz = !
238 baz = !
239
239
240 enabled extensions:
240 enabled extensions:
241
241
242 children command to display child changesets (DEPRECATED)
242 children command to display child changesets (DEPRECATED)
243 rebase command to move sets of revisions to a different ancestor
243 rebase command to move sets of revisions to a different ancestor
244
244
245 disabled extensions:
245 disabled extensions:
246
246
247 acl hooks for controlling repository access
247 acl hooks for controlling repository access
248 blackbox log repository events to a blackbox for debugging
248 blackbox log repository events to a blackbox for debugging
249 bugzilla hooks for integrating with the Bugzilla bug tracker
249 bugzilla hooks for integrating with the Bugzilla bug tracker
250 churn command to display statistics about repository history
250 churn command to display statistics about repository history
251 color colorize output from some commands
251 color colorize output from some commands
252 convert import revisions from foreign VCS repositories into
252 convert import revisions from foreign VCS repositories into
253 Mercurial
253 Mercurial
254 eol automatically manage newlines in repository files
254 eol automatically manage newlines in repository files
255 extdiff command to allow external programs to compare revisions
255 extdiff command to allow external programs to compare revisions
256 factotum http authentication with factotum
256 factotum http authentication with factotum
257 gpg commands to sign and verify changesets
257 gpg commands to sign and verify changesets
258 hgcia hooks for integrating with the CIA.vc notification service
258 hgcia hooks for integrating with the CIA.vc notification service
259 hgk browse the repository in a graphical way
259 hgk browse the repository in a graphical way
260 highlight syntax highlighting for hgweb (requires Pygments)
260 highlight syntax highlighting for hgweb (requires Pygments)
261 histedit interactive history editing
261 histedit interactive history editing
262 keyword expand keywords in tracked files
262 keyword expand keywords in tracked files
263 largefiles track large binary files
263 largefiles track large binary files
264 mq manage a stack of patches
264 mq manage a stack of patches
265 notify hooks for sending email push notifications
265 notify hooks for sending email push notifications
266 pager browse command output with an external pager
266 pager browse command output with an external pager
267 patchbomb command to send changesets as (a series of) patch emails
267 patchbomb command to send changesets as (a series of) patch emails
268 progress show progress bars for some actions
268 progress show progress bars for some actions
269 purge command to delete untracked files from the working
269 purge command to delete untracked files from the working
270 directory
270 directory
271 record commands to interactively select changes for
271 record commands to interactively select changes for
272 commit/qrefresh
272 commit/qrefresh
273 relink recreates hardlinks between repository clones
273 relink recreates hardlinks between repository clones
274 schemes extend schemes with shortcuts to repository swarms
274 schemes extend schemes with shortcuts to repository swarms
275 share share a common history between several working directories
275 share share a common history between several working directories
276 shelve save and restore changes to the working directory
276 shelve save and restore changes to the working directory
277 strip strip changesets and their descendents from history
277 strip strip changesets and their descendents from history
278 transplant command to transplant changesets from another branch
278 transplant command to transplant changesets from another branch
279 win32mbcs allow the use of MBCS paths with problematic encodings
279 win32mbcs allow the use of MBCS paths with problematic encodings
280 zeroconf discover and advertise repositories on the local network
280 zeroconf discover and advertise repositories on the local network
281 Test short command list with verbose option
281 Test short command list with verbose option
282
282
283 $ hg -v help shortlist
283 $ hg -v help shortlist
284 Mercurial Distributed SCM
284 Mercurial Distributed SCM
285
285
286 basic commands:
286 basic commands:
287
287
288 add add the specified files on the next commit
288 add add the specified files on the next commit
289 annotate, blame
289 annotate, blame
290 show changeset information by line for each file
290 show changeset information by line for each file
291 clone make a copy of an existing repository
291 clone make a copy of an existing repository
292 commit, ci commit the specified files or all outstanding changes
292 commit, ci commit the specified files or all outstanding changes
293 diff diff repository (or selected files)
293 diff diff repository (or selected files)
294 export dump the header and diffs for one or more changesets
294 export dump the header and diffs for one or more changesets
295 forget forget the specified files on the next commit
295 forget forget the specified files on the next commit
296 init create a new repository in the given directory
296 init create a new repository in the given directory
297 log, history show revision history of entire repository or files
297 log, history show revision history of entire repository or files
298 merge merge working directory with another revision
298 merge merge working directory with another revision
299 pull pull changes from the specified source
299 pull pull changes from the specified source
300 push push changes to the specified destination
300 push push changes to the specified destination
301 remove, rm remove the specified files on the next commit
301 remove, rm remove the specified files on the next commit
302 serve start stand-alone webserver
302 serve start stand-alone webserver
303 status, st show changed files in the working directory
303 status, st show changed files in the working directory
304 summary, sum summarize working directory state
304 summary, sum summarize working directory state
305 update, up, checkout, co
305 update, up, checkout, co
306 update working directory (or switch revisions)
306 update working directory (or switch revisions)
307
307
308 global options:
308 global options:
309
309
310 -R --repository REPO repository root directory or name of overlay bundle
310 -R --repository REPO repository root directory or name of overlay bundle
311 file
311 file
312 --cwd DIR change working directory
312 --cwd DIR change working directory
313 -y --noninteractive do not prompt, automatically pick the first choice for
313 -y --noninteractive do not prompt, automatically pick the first choice for
314 all prompts
314 all prompts
315 -q --quiet suppress output
315 -q --quiet suppress output
316 -v --verbose enable additional output
316 -v --verbose enable additional output
317 --config CONFIG [+] set/override config option (use 'section.name=value')
317 --config CONFIG [+] set/override config option (use 'section.name=value')
318 --debug enable debugging output
318 --debug enable debugging output
319 --debugger start debugger
319 --debugger start debugger
320 --encoding ENCODE set the charset encoding (default: ascii)
320 --encoding ENCODE set the charset encoding (default: ascii)
321 --encodingmode MODE set the charset encoding mode (default: strict)
321 --encodingmode MODE set the charset encoding mode (default: strict)
322 --traceback always print a traceback on exception
322 --traceback always print a traceback on exception
323 --time time how long the command takes
323 --time time how long the command takes
324 --profile print command execution profile
324 --profile print command execution profile
325 --version output version information and exit
325 --version output version information and exit
326 -h --help display help and exit
326 -h --help display help and exit
327 --hidden consider hidden changesets
327 --hidden consider hidden changesets
328
328
329 [+] marked option can be specified multiple times
329 [+] marked option can be specified multiple times
330
330
331 use "hg help" for the full list of commands
331 use "hg help" for the full list of commands
332
332
333 $ hg add -h
333 $ hg add -h
334 hg add [OPTION]... [FILE]...
334 hg add [OPTION]... [FILE]...
335
335
336 add the specified files on the next commit
336 add the specified files on the next commit
337
337
338 Schedule files to be version controlled and added to the repository.
338 Schedule files to be version controlled and added to the repository.
339
339
340 The files will be added to the repository at the next commit. To undo an
340 The files will be added to the repository at the next commit. To undo an
341 add before that, see "hg forget".
341 add before that, see "hg forget".
342
342
343 If no names are given, add all files to the repository.
343 If no names are given, add all files to the repository.
344
344
345 Returns 0 if all files are successfully added.
345 Returns 0 if all files are successfully added.
346
346
347 options:
347 options:
348
348
349 -I --include PATTERN [+] include names matching the given patterns
349 -I --include PATTERN [+] include names matching the given patterns
350 -X --exclude PATTERN [+] exclude names matching the given patterns
350 -X --exclude PATTERN [+] exclude names matching the given patterns
351 -S --subrepos recurse into subrepositories
351 -S --subrepos recurse into subrepositories
352 -n --dry-run do not perform actions, just print output
352 -n --dry-run do not perform actions, just print output
353
353
354 [+] marked option can be specified multiple times
354 [+] marked option can be specified multiple times
355
355
356 use "hg -v help add" to show more complete help and the global options
356 use "hg -v help add" to show more complete help and the global options
357
357
358 Verbose help for add
358 Verbose help for add
359
359
360 $ hg add -hv
360 $ hg add -hv
361 hg add [OPTION]... [FILE]...
361 hg add [OPTION]... [FILE]...
362
362
363 add the specified files on the next commit
363 add the specified files on the next commit
364
364
365 Schedule files to be version controlled and added to the repository.
365 Schedule files to be version controlled and added to the repository.
366
366
367 The files will be added to the repository at the next commit. To undo an
367 The files will be added to the repository at the next commit. To undo an
368 add before that, see "hg forget".
368 add before that, see "hg forget".
369
369
370 If no names are given, add all files to the repository.
370 If no names are given, add all files to the repository.
371
371
372 An example showing how new (unknown) files are added automatically by "hg
372 An example showing how new (unknown) files are added automatically by "hg
373 add":
373 add":
374
374
375 $ ls
375 $ ls
376 foo.c
376 foo.c
377 $ hg status
377 $ hg status
378 ? foo.c
378 ? foo.c
379 $ hg add
379 $ hg add
380 adding foo.c
380 adding foo.c
381 $ hg status
381 $ hg status
382 A foo.c
382 A foo.c
383
383
384 Returns 0 if all files are successfully added.
384 Returns 0 if all files are successfully added.
385
385
386 options:
386 options:
387
387
388 -I --include PATTERN [+] include names matching the given patterns
388 -I --include PATTERN [+] include names matching the given patterns
389 -X --exclude PATTERN [+] exclude names matching the given patterns
389 -X --exclude PATTERN [+] exclude names matching the given patterns
390 -S --subrepos recurse into subrepositories
390 -S --subrepos recurse into subrepositories
391 -n --dry-run do not perform actions, just print output
391 -n --dry-run do not perform actions, just print output
392
392
393 [+] marked option can be specified multiple times
393 [+] marked option can be specified multiple times
394
394
395 global options:
395 global options:
396
396
397 -R --repository REPO repository root directory or name of overlay bundle
397 -R --repository REPO repository root directory or name of overlay bundle
398 file
398 file
399 --cwd DIR change working directory
399 --cwd DIR change working directory
400 -y --noninteractive do not prompt, automatically pick the first choice for
400 -y --noninteractive do not prompt, automatically pick the first choice for
401 all prompts
401 all prompts
402 -q --quiet suppress output
402 -q --quiet suppress output
403 -v --verbose enable additional output
403 -v --verbose enable additional output
404 --config CONFIG [+] set/override config option (use 'section.name=value')
404 --config CONFIG [+] set/override config option (use 'section.name=value')
405 --debug enable debugging output
405 --debug enable debugging output
406 --debugger start debugger
406 --debugger start debugger
407 --encoding ENCODE set the charset encoding (default: ascii)
407 --encoding ENCODE set the charset encoding (default: ascii)
408 --encodingmode MODE set the charset encoding mode (default: strict)
408 --encodingmode MODE set the charset encoding mode (default: strict)
409 --traceback always print a traceback on exception
409 --traceback always print a traceback on exception
410 --time time how long the command takes
410 --time time how long the command takes
411 --profile print command execution profile
411 --profile print command execution profile
412 --version output version information and exit
412 --version output version information and exit
413 -h --help display help and exit
413 -h --help display help and exit
414 --hidden consider hidden changesets
414 --hidden consider hidden changesets
415
415
416 [+] marked option can be specified multiple times
416 [+] marked option can be specified multiple times
417
417
418 Test help option with version option
418 Test help option with version option
419
419
420 $ hg add -h --version
420 $ hg add -h --version
421 Mercurial Distributed SCM (version *) (glob)
421 Mercurial Distributed SCM (version *) (glob)
422 (see http://mercurial.selenic.com for more information)
422 (see http://mercurial.selenic.com for more information)
423
423
424 Copyright (C) 2005-2014 Matt Mackall and others
424 Copyright (C) 2005-2014 Matt Mackall and others
425 This is free software; see the source for copying conditions. There is NO
425 This is free software; see the source for copying conditions. There is NO
426 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
426 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
427
427
428 $ hg add --skjdfks
428 $ hg add --skjdfks
429 hg add: option --skjdfks not recognized
429 hg add: option --skjdfks not recognized
430 hg add [OPTION]... [FILE]...
430 hg add [OPTION]... [FILE]...
431
431
432 add the specified files on the next commit
432 add the specified files on the next commit
433
433
434 options:
434 options:
435
435
436 -I --include PATTERN [+] include names matching the given patterns
436 -I --include PATTERN [+] include names matching the given patterns
437 -X --exclude PATTERN [+] exclude names matching the given patterns
437 -X --exclude PATTERN [+] exclude names matching the given patterns
438 -S --subrepos recurse into subrepositories
438 -S --subrepos recurse into subrepositories
439 -n --dry-run do not perform actions, just print output
439 -n --dry-run do not perform actions, just print output
440
440
441 [+] marked option can be specified multiple times
441 [+] marked option can be specified multiple times
442
442
443 use "hg help add" to show the full help text
443 use "hg help add" to show the full help text
444 [255]
444 [255]
445
445
446 Test ambiguous command help
446 Test ambiguous command help
447
447
448 $ hg help ad
448 $ hg help ad
449 list of commands:
449 list of commands:
450
450
451 add add the specified files on the next commit
451 add add the specified files on the next commit
452 addremove add all new files, delete all missing files
452 addremove add all new files, delete all missing files
453
453
454 use "hg -v help ad" to show builtin aliases and global options
454 use "hg -v help ad" to show builtin aliases and global options
455
455
456 Test command without options
456 Test command without options
457
457
458 $ hg help verify
458 $ hg help verify
459 hg verify
459 hg verify
460
460
461 verify the integrity of the repository
461 verify the integrity of the repository
462
462
463 Verify the integrity of the current repository.
463 Verify the integrity of the current repository.
464
464
465 This will perform an extensive check of the repository's integrity,
465 This will perform an extensive check of the repository's integrity,
466 validating the hashes and checksums of each entry in the changelog,
466 validating the hashes and checksums of each entry in the changelog,
467 manifest, and tracked files, as well as the integrity of their crosslinks
467 manifest, and tracked files, as well as the integrity of their crosslinks
468 and indices.
468 and indices.
469
469
470 Please see http://mercurial.selenic.com/wiki/RepositoryCorruption for more
470 Please see http://mercurial.selenic.com/wiki/RepositoryCorruption for more
471 information about recovery from corruption of the repository.
471 information about recovery from corruption of the repository.
472
472
473 Returns 0 on success, 1 if errors are encountered.
473 Returns 0 on success, 1 if errors are encountered.
474
474
475 use "hg -v help verify" to show the global options
475 use "hg -v help verify" to show the global options
476
476
477 $ hg help diff
477 $ hg help diff
478 hg diff [OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...
478 hg diff [OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...
479
479
480 diff repository (or selected files)
480 diff repository (or selected files)
481
481
482 Show differences between revisions for the specified files.
482 Show differences between revisions for the specified files.
483
483
484 Differences between files are shown using the unified diff format.
484 Differences between files are shown using the unified diff format.
485
485
486 Note:
486 Note:
487 diff may generate unexpected results for merges, as it will default to
487 diff may generate unexpected results for merges, as it will default to
488 comparing against the working directory's first parent changeset if no
488 comparing against the working directory's first parent changeset if no
489 revisions are specified.
489 revisions are specified.
490
490
491 When two revision arguments are given, then changes are shown between
491 When two revision arguments are given, then changes are shown between
492 those revisions. If only one revision is specified then that revision is
492 those revisions. If only one revision is specified then that revision is
493 compared to the working directory, and, when no revisions are specified,
493 compared to the working directory, and, when no revisions are specified,
494 the working directory files are compared to its parent.
494 the working directory files are compared to its parent.
495
495
496 Alternatively you can specify -c/--change with a revision to see the
496 Alternatively you can specify -c/--change with a revision to see the
497 changes in that changeset relative to its first parent.
497 changes in that changeset relative to its first parent.
498
498
499 Without the -a/--text option, diff will avoid generating diffs of files it
499 Without the -a/--text option, diff will avoid generating diffs of files it
500 detects as binary. With -a, diff will generate a diff anyway, probably
500 detects as binary. With -a, diff will generate a diff anyway, probably
501 with undesirable results.
501 with undesirable results.
502
502
503 Use the -g/--git option to generate diffs in the git extended diff format.
503 Use the -g/--git option to generate diffs in the git extended diff format.
504 For more information, read "hg help diffs".
504 For more information, read "hg help diffs".
505
505
506 Returns 0 on success.
506 Returns 0 on success.
507
507
508 options:
508 options:
509
509
510 -r --rev REV [+] revision
510 -r --rev REV [+] revision
511 -c --change REV change made by revision
511 -c --change REV change made by revision
512 -a --text treat all files as text
512 -a --text treat all files as text
513 -g --git use git extended diff format
513 -g --git use git extended diff format
514 --nodates omit dates from diff headers
514 --nodates omit dates from diff headers
515 -p --show-function show which function each change is in
515 -p --show-function show which function each change is in
516 --reverse produce a diff that undoes the changes
516 --reverse produce a diff that undoes the changes
517 -w --ignore-all-space ignore white space when comparing lines
517 -w --ignore-all-space ignore white space when comparing lines
518 -b --ignore-space-change ignore changes in the amount of white space
518 -b --ignore-space-change ignore changes in the amount of white space
519 -B --ignore-blank-lines ignore changes whose lines are all blank
519 -B --ignore-blank-lines ignore changes whose lines are all blank
520 -U --unified NUM number of lines of context to show
520 -U --unified NUM number of lines of context to show
521 --stat output diffstat-style summary of changes
521 --stat output diffstat-style summary of changes
522 -I --include PATTERN [+] include names matching the given patterns
522 -I --include PATTERN [+] include names matching the given patterns
523 -X --exclude PATTERN [+] exclude names matching the given patterns
523 -X --exclude PATTERN [+] exclude names matching the given patterns
524 -S --subrepos recurse into subrepositories
524 -S --subrepos recurse into subrepositories
525
525
526 [+] marked option can be specified multiple times
526 [+] marked option can be specified multiple times
527
527
528 use "hg -v help diff" to show more complete help and the global options
528 use "hg -v help diff" to show more complete help and the global options
529
529
530 $ hg help status
530 $ hg help status
531 hg status [OPTION]... [FILE]...
531 hg status [OPTION]... [FILE]...
532
532
533 aliases: st
533 aliases: st
534
534
535 show changed files in the working directory
535 show changed files in the working directory
536
536
537 Show status of files in the repository. If names are given, only files
537 Show status of files in the repository. If names are given, only files
538 that match are shown. Files that are clean or ignored or the source of a
538 that match are shown. Files that are clean or ignored or the source of a
539 copy/move operation, are not listed unless -c/--clean, -i/--ignored,
539 copy/move operation, are not listed unless -c/--clean, -i/--ignored,
540 -C/--copies or -A/--all are given. Unless options described with "show
540 -C/--copies or -A/--all are given. Unless options described with "show
541 only ..." are given, the options -mardu are used.
541 only ..." are given, the options -mardu are used.
542
542
543 Option -q/--quiet hides untracked (unknown and ignored) files unless
543 Option -q/--quiet hides untracked (unknown and ignored) files unless
544 explicitly requested with -u/--unknown or -i/--ignored.
544 explicitly requested with -u/--unknown or -i/--ignored.
545
545
546 Note:
546 Note:
547 status may appear to disagree with diff if permissions have changed or
547 status may appear to disagree with diff if permissions have changed or
548 a merge has occurred. The standard diff format does not report
548 a merge has occurred. The standard diff format does not report
549 permission changes and diff only reports changes relative to one merge
549 permission changes and diff only reports changes relative to one merge
550 parent.
550 parent.
551
551
552 If one revision is given, it is used as the base revision. If two
552 If one revision is given, it is used as the base revision. If two
553 revisions are given, the differences between them are shown. The --change
553 revisions are given, the differences between them are shown. The --change
554 option can also be used as a shortcut to list the changed files of a
554 option can also be used as a shortcut to list the changed files of a
555 revision from its first parent.
555 revision from its first parent.
556
556
557 The codes used to show the status of files are:
557 The codes used to show the status of files are:
558
558
559 M = modified
559 M = modified
560 A = added
560 A = added
561 R = removed
561 R = removed
562 C = clean
562 C = clean
563 ! = missing (deleted by non-hg command, but still tracked)
563 ! = missing (deleted by non-hg command, but still tracked)
564 ? = not tracked
564 ? = not tracked
565 I = ignored
565 I = ignored
566 = origin of the previous file listed as A (added)
566 = origin of the previous file (with --copies)
567
567
568 Returns 0 on success.
568 Returns 0 on success.
569
569
570 options:
570 options:
571
571
572 -A --all show status of all files
572 -A --all show status of all files
573 -m --modified show only modified files
573 -m --modified show only modified files
574 -a --added show only added files
574 -a --added show only added files
575 -r --removed show only removed files
575 -r --removed show only removed files
576 -d --deleted show only deleted (but tracked) files
576 -d --deleted show only deleted (but tracked) files
577 -c --clean show only files without changes
577 -c --clean show only files without changes
578 -u --unknown show only unknown (not tracked) files
578 -u --unknown show only unknown (not tracked) files
579 -i --ignored show only ignored files
579 -i --ignored show only ignored files
580 -n --no-status hide status prefix
580 -n --no-status hide status prefix
581 -C --copies show source of copied files
581 -C --copies show source of copied files
582 -0 --print0 end filenames with NUL, for use with xargs
582 -0 --print0 end filenames with NUL, for use with xargs
583 --rev REV [+] show difference from revision
583 --rev REV [+] show difference from revision
584 --change REV list the changed files of a revision
584 --change REV list the changed files of a revision
585 -I --include PATTERN [+] include names matching the given patterns
585 -I --include PATTERN [+] include names matching the given patterns
586 -X --exclude PATTERN [+] exclude names matching the given patterns
586 -X --exclude PATTERN [+] exclude names matching the given patterns
587 -S --subrepos recurse into subrepositories
587 -S --subrepos recurse into subrepositories
588
588
589 [+] marked option can be specified multiple times
589 [+] marked option can be specified multiple times
590
590
591 use "hg -v help status" to show more complete help and the global options
591 use "hg -v help status" to show more complete help and the global options
592
592
593 $ hg -q help status
593 $ hg -q help status
594 hg status [OPTION]... [FILE]...
594 hg status [OPTION]... [FILE]...
595
595
596 show changed files in the working directory
596 show changed files in the working directory
597
597
598 $ hg help foo
598 $ hg help foo
599 hg: unknown command 'foo'
599 hg: unknown command 'foo'
600 Mercurial Distributed SCM
600 Mercurial Distributed SCM
601
601
602 basic commands:
602 basic commands:
603
603
604 add add the specified files on the next commit
604 add add the specified files on the next commit
605 annotate show changeset information by line for each file
605 annotate show changeset information by line for each file
606 clone make a copy of an existing repository
606 clone make a copy of an existing repository
607 commit commit the specified files or all outstanding changes
607 commit commit the specified files or all outstanding changes
608 diff diff repository (or selected files)
608 diff diff repository (or selected files)
609 export dump the header and diffs for one or more changesets
609 export dump the header and diffs for one or more changesets
610 forget forget the specified files on the next commit
610 forget forget the specified files on the next commit
611 init create a new repository in the given directory
611 init create a new repository in the given directory
612 log show revision history of entire repository or files
612 log show revision history of entire repository or files
613 merge merge working directory with another revision
613 merge merge working directory with another revision
614 pull pull changes from the specified source
614 pull pull changes from the specified source
615 push push changes to the specified destination
615 push push changes to the specified destination
616 remove remove the specified files on the next commit
616 remove remove the specified files on the next commit
617 serve start stand-alone webserver
617 serve start stand-alone webserver
618 status show changed files in the working directory
618 status show changed files in the working directory
619 summary summarize working directory state
619 summary summarize working directory state
620 update update working directory (or switch revisions)
620 update update working directory (or switch revisions)
621
621
622 use "hg help" for the full list of commands or "hg -v" for details
622 use "hg help" for the full list of commands or "hg -v" for details
623 [255]
623 [255]
624
624
625 $ hg skjdfks
625 $ hg skjdfks
626 hg: unknown command 'skjdfks'
626 hg: unknown command 'skjdfks'
627 Mercurial Distributed SCM
627 Mercurial Distributed SCM
628
628
629 basic commands:
629 basic commands:
630
630
631 add add the specified files on the next commit
631 add add the specified files on the next commit
632 annotate show changeset information by line for each file
632 annotate show changeset information by line for each file
633 clone make a copy of an existing repository
633 clone make a copy of an existing repository
634 commit commit the specified files or all outstanding changes
634 commit commit the specified files or all outstanding changes
635 diff diff repository (or selected files)
635 diff diff repository (or selected files)
636 export dump the header and diffs for one or more changesets
636 export dump the header and diffs for one or more changesets
637 forget forget the specified files on the next commit
637 forget forget the specified files on the next commit
638 init create a new repository in the given directory
638 init create a new repository in the given directory
639 log show revision history of entire repository or files
639 log show revision history of entire repository or files
640 merge merge working directory with another revision
640 merge merge working directory with another revision
641 pull pull changes from the specified source
641 pull pull changes from the specified source
642 push push changes to the specified destination
642 push push changes to the specified destination
643 remove remove the specified files on the next commit
643 remove remove the specified files on the next commit
644 serve start stand-alone webserver
644 serve start stand-alone webserver
645 status show changed files in the working directory
645 status show changed files in the working directory
646 summary summarize working directory state
646 summary summarize working directory state
647 update update working directory (or switch revisions)
647 update update working directory (or switch revisions)
648
648
649 use "hg help" for the full list of commands or "hg -v" for details
649 use "hg help" for the full list of commands or "hg -v" for details
650 [255]
650 [255]
651
651
652 $ cat > helpext.py <<EOF
652 $ cat > helpext.py <<EOF
653 > import os
653 > import os
654 > from mercurial import commands
654 > from mercurial import commands
655 >
655 >
656 > def nohelp(ui, *args, **kwargs):
656 > def nohelp(ui, *args, **kwargs):
657 > pass
657 > pass
658 >
658 >
659 > cmdtable = {
659 > cmdtable = {
660 > "nohelp": (nohelp, [('', 'longdesc', 3, 'x'*90),
660 > "nohelp": (nohelp, [('', 'longdesc', 3, 'x'*90),
661 > ('n', '', None, 'normal desc'),
661 > ('n', '', None, 'normal desc'),
662 > ('', 'newline', '', 'line1\nline2'),
662 > ('', 'newline', '', 'line1\nline2'),
663 > ], "hg nohelp"),
663 > ], "hg nohelp"),
664 > }
664 > }
665 >
665 >
666 > commands.norepo += ' nohelp'
666 > commands.norepo += ' nohelp'
667 > EOF
667 > EOF
668 $ echo '[extensions]' >> $HGRCPATH
668 $ echo '[extensions]' >> $HGRCPATH
669 $ echo "helpext = `pwd`/helpext.py" >> $HGRCPATH
669 $ echo "helpext = `pwd`/helpext.py" >> $HGRCPATH
670
670
671 Test command with no help text
671 Test command with no help text
672
672
673 $ hg help nohelp
673 $ hg help nohelp
674 hg nohelp
674 hg nohelp
675
675
676 (no help text available)
676 (no help text available)
677
677
678 options:
678 options:
679
679
680 --longdesc VALUE xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
680 --longdesc VALUE xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
681 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx (default: 3)
681 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx (default: 3)
682 -n -- normal desc
682 -n -- normal desc
683 --newline VALUE line1 line2
683 --newline VALUE line1 line2
684
684
685 use "hg -v help nohelp" to show the global options
685 use "hg -v help nohelp" to show the global options
686
686
687 $ hg help -k nohelp
687 $ hg help -k nohelp
688 Commands:
688 Commands:
689
689
690 nohelp hg nohelp
690 nohelp hg nohelp
691
691
692 Extension Commands:
692 Extension Commands:
693
693
694 nohelp (no help text available)
694 nohelp (no help text available)
695
695
696 Test that default list of commands omits extension commands
696 Test that default list of commands omits extension commands
697
697
698 $ hg help
698 $ hg help
699 Mercurial Distributed SCM
699 Mercurial Distributed SCM
700
700
701 list of commands:
701 list of commands:
702
702
703 add add the specified files on the next commit
703 add add the specified files on the next commit
704 addremove add all new files, delete all missing files
704 addremove add all new files, delete all missing files
705 annotate show changeset information by line for each file
705 annotate show changeset information by line for each file
706 archive create an unversioned archive of a repository revision
706 archive create an unversioned archive of a repository revision
707 backout reverse effect of earlier changeset
707 backout reverse effect of earlier changeset
708 bisect subdivision search of changesets
708 bisect subdivision search of changesets
709 bookmarks track a line of development with movable markers
709 bookmarks track a line of development with movable markers
710 branch set or show the current branch name
710 branch set or show the current branch name
711 branches list repository named branches
711 branches list repository named branches
712 bundle create a changegroup file
712 bundle create a changegroup file
713 cat output the current or given revision of files
713 cat output the current or given revision of files
714 clone make a copy of an existing repository
714 clone make a copy of an existing repository
715 commit commit the specified files or all outstanding changes
715 commit commit the specified files or all outstanding changes
716 config show combined config settings from all hgrc files
716 config show combined config settings from all hgrc files
717 copy mark files as copied for the next commit
717 copy mark files as copied for the next commit
718 diff diff repository (or selected files)
718 diff diff repository (or selected files)
719 export dump the header and diffs for one or more changesets
719 export dump the header and diffs for one or more changesets
720 forget forget the specified files on the next commit
720 forget forget the specified files on the next commit
721 graft copy changes from other branches onto the current branch
721 graft copy changes from other branches onto the current branch
722 grep search for a pattern in specified files and revisions
722 grep search for a pattern in specified files and revisions
723 heads show branch heads
723 heads show branch heads
724 help show help for a given topic or a help overview
724 help show help for a given topic or a help overview
725 identify identify the working copy or specified revision
725 identify identify the working copy or specified revision
726 import import an ordered set of patches
726 import import an ordered set of patches
727 incoming show new changesets found in source
727 incoming show new changesets found in source
728 init create a new repository in the given directory
728 init create a new repository in the given directory
729 locate locate files matching specific patterns
729 locate locate files matching specific patterns
730 log show revision history of entire repository or files
730 log show revision history of entire repository or files
731 manifest output the current or given revision of the project manifest
731 manifest output the current or given revision of the project manifest
732 merge merge working directory with another revision
732 merge merge working directory with another revision
733 outgoing show changesets not found in the destination
733 outgoing show changesets not found in the destination
734 parents show the parents of the working directory or revision
734 parents show the parents of the working directory or revision
735 paths show aliases for remote repositories
735 paths show aliases for remote repositories
736 phase set or show the current phase name
736 phase set or show the current phase name
737 pull pull changes from the specified source
737 pull pull changes from the specified source
738 push push changes to the specified destination
738 push push changes to the specified destination
739 recover roll back an interrupted transaction
739 recover roll back an interrupted transaction
740 remove remove the specified files on the next commit
740 remove remove the specified files on the next commit
741 rename rename files; equivalent of copy + remove
741 rename rename files; equivalent of copy + remove
742 resolve redo merges or set/view the merge status of files
742 resolve redo merges or set/view the merge status of files
743 revert restore files to their checkout state
743 revert restore files to their checkout state
744 root print the root (top) of the current working directory
744 root print the root (top) of the current working directory
745 serve start stand-alone webserver
745 serve start stand-alone webserver
746 status show changed files in the working directory
746 status show changed files in the working directory
747 summary summarize working directory state
747 summary summarize working directory state
748 tag add one or more tags for the current or given revision
748 tag add one or more tags for the current or given revision
749 tags list repository tags
749 tags list repository tags
750 unbundle apply one or more changegroup files
750 unbundle apply one or more changegroup files
751 update update working directory (or switch revisions)
751 update update working directory (or switch revisions)
752 verify verify the integrity of the repository
752 verify verify the integrity of the repository
753 version output version and copyright information
753 version output version and copyright information
754
754
755 enabled extensions:
755 enabled extensions:
756
756
757 helpext (no help text available)
757 helpext (no help text available)
758
758
759 additional help topics:
759 additional help topics:
760
760
761 config Configuration Files
761 config Configuration Files
762 dates Date Formats
762 dates Date Formats
763 diffs Diff Formats
763 diffs Diff Formats
764 environment Environment Variables
764 environment Environment Variables
765 extensions Using Additional Features
765 extensions Using Additional Features
766 filesets Specifying File Sets
766 filesets Specifying File Sets
767 glossary Glossary
767 glossary Glossary
768 hgignore Syntax for Mercurial Ignore Files
768 hgignore Syntax for Mercurial Ignore Files
769 hgweb Configuring hgweb
769 hgweb Configuring hgweb
770 merge-tools Merge Tools
770 merge-tools Merge Tools
771 multirevs Specifying Multiple Revisions
771 multirevs Specifying Multiple Revisions
772 patterns File Name Patterns
772 patterns File Name Patterns
773 phases Working with Phases
773 phases Working with Phases
774 revisions Specifying Single Revisions
774 revisions Specifying Single Revisions
775 revsets Specifying Revision Sets
775 revsets Specifying Revision Sets
776 subrepos Subrepositories
776 subrepos Subrepositories
777 templating Template Usage
777 templating Template Usage
778 urls URL Paths
778 urls URL Paths
779
779
780 use "hg -v help" to show builtin aliases and global options
780 use "hg -v help" to show builtin aliases and global options
781
781
782
782
783
783
784 Test list of commands with command with no help text
784 Test list of commands with command with no help text
785
785
786 $ hg help helpext
786 $ hg help helpext
787 helpext extension - no help text available
787 helpext extension - no help text available
788
788
789 list of commands:
789 list of commands:
790
790
791 nohelp (no help text available)
791 nohelp (no help text available)
792
792
793 use "hg -v help helpext" to show builtin aliases and global options
793 use "hg -v help helpext" to show builtin aliases and global options
794
794
795 Test a help topic
795 Test a help topic
796
796
797 $ hg help revs
797 $ hg help revs
798 Specifying Single Revisions
798 Specifying Single Revisions
799 """""""""""""""""""""""""""
799 """""""""""""""""""""""""""
800
800
801 Mercurial supports several ways to specify individual revisions.
801 Mercurial supports several ways to specify individual revisions.
802
802
803 A plain integer is treated as a revision number. Negative integers are
803 A plain integer is treated as a revision number. Negative integers are
804 treated as sequential offsets from the tip, with -1 denoting the tip, -2
804 treated as sequential offsets from the tip, with -1 denoting the tip, -2
805 denoting the revision prior to the tip, and so forth.
805 denoting the revision prior to the tip, and so forth.
806
806
807 A 40-digit hexadecimal string is treated as a unique revision identifier.
807 A 40-digit hexadecimal string is treated as a unique revision identifier.
808
808
809 A hexadecimal string less than 40 characters long is treated as a unique
809 A hexadecimal string less than 40 characters long is treated as a unique
810 revision identifier and is referred to as a short-form identifier. A
810 revision identifier and is referred to as a short-form identifier. A
811 short-form identifier is only valid if it is the prefix of exactly one
811 short-form identifier is only valid if it is the prefix of exactly one
812 full-length identifier.
812 full-length identifier.
813
813
814 Any other string is treated as a bookmark, tag, or branch name. A bookmark
814 Any other string is treated as a bookmark, tag, or branch name. A bookmark
815 is a movable pointer to a revision. A tag is a permanent name associated
815 is a movable pointer to a revision. A tag is a permanent name associated
816 with a revision. A branch name denotes the tipmost open branch head of
816 with a revision. A branch name denotes the tipmost open branch head of
817 that branch - or if they are all closed, the tipmost closed head of the
817 that branch - or if they are all closed, the tipmost closed head of the
818 branch. Bookmark, tag, and branch names must not contain the ":"
818 branch. Bookmark, tag, and branch names must not contain the ":"
819 character.
819 character.
820
820
821 The reserved name "tip" always identifies the most recent revision.
821 The reserved name "tip" always identifies the most recent revision.
822
822
823 The reserved name "null" indicates the null revision. This is the revision
823 The reserved name "null" indicates the null revision. This is the revision
824 of an empty repository, and the parent of revision 0.
824 of an empty repository, and the parent of revision 0.
825
825
826 The reserved name "." indicates the working directory parent. If no
826 The reserved name "." indicates the working directory parent. If no
827 working directory is checked out, it is equivalent to null. If an
827 working directory is checked out, it is equivalent to null. If an
828 uncommitted merge is in progress, "." is the revision of the first parent.
828 uncommitted merge is in progress, "." is the revision of the first parent.
829
829
830 Test templating help
830 Test templating help
831
831
832 $ hg help templating | egrep '(desc|diffstat|firstline|nonempty) '
832 $ hg help templating | egrep '(desc|diffstat|firstline|nonempty) '
833 desc String. The text of the changeset description.
833 desc String. The text of the changeset description.
834 diffstat String. Statistics of changes with the following format:
834 diffstat String. Statistics of changes with the following format:
835 firstline Any text. Returns the first line of text.
835 firstline Any text. Returns the first line of text.
836 nonempty Any text. Returns '(none)' if the string is empty.
836 nonempty Any text. Returns '(none)' if the string is empty.
837
837
838 Test help hooks
838 Test help hooks
839
839
840 $ cat > helphook1.py <<EOF
840 $ cat > helphook1.py <<EOF
841 > from mercurial import help
841 > from mercurial import help
842 >
842 >
843 > def rewrite(topic, doc):
843 > def rewrite(topic, doc):
844 > return doc + '\nhelphook1\n'
844 > return doc + '\nhelphook1\n'
845 >
845 >
846 > def extsetup(ui):
846 > def extsetup(ui):
847 > help.addtopichook('revsets', rewrite)
847 > help.addtopichook('revsets', rewrite)
848 > EOF
848 > EOF
849 $ cat > helphook2.py <<EOF
849 $ cat > helphook2.py <<EOF
850 > from mercurial import help
850 > from mercurial import help
851 >
851 >
852 > def rewrite(topic, doc):
852 > def rewrite(topic, doc):
853 > return doc + '\nhelphook2\n'
853 > return doc + '\nhelphook2\n'
854 >
854 >
855 > def extsetup(ui):
855 > def extsetup(ui):
856 > help.addtopichook('revsets', rewrite)
856 > help.addtopichook('revsets', rewrite)
857 > EOF
857 > EOF
858 $ echo '[extensions]' >> $HGRCPATH
858 $ echo '[extensions]' >> $HGRCPATH
859 $ echo "helphook1 = `pwd`/helphook1.py" >> $HGRCPATH
859 $ echo "helphook1 = `pwd`/helphook1.py" >> $HGRCPATH
860 $ echo "helphook2 = `pwd`/helphook2.py" >> $HGRCPATH
860 $ echo "helphook2 = `pwd`/helphook2.py" >> $HGRCPATH
861 $ hg help revsets | grep helphook
861 $ hg help revsets | grep helphook
862 helphook1
862 helphook1
863 helphook2
863 helphook2
864
864
865 Test keyword search help
865 Test keyword search help
866
866
867 $ cat > prefixedname.py <<EOF
867 $ cat > prefixedname.py <<EOF
868 > '''matched against word "clone"
868 > '''matched against word "clone"
869 > '''
869 > '''
870 > EOF
870 > EOF
871 $ echo '[extensions]' >> $HGRCPATH
871 $ echo '[extensions]' >> $HGRCPATH
872 $ echo "dot.dot.prefixedname = `pwd`/prefixedname.py" >> $HGRCPATH
872 $ echo "dot.dot.prefixedname = `pwd`/prefixedname.py" >> $HGRCPATH
873 $ hg help -k clone
873 $ hg help -k clone
874 Topics:
874 Topics:
875
875
876 config Configuration Files
876 config Configuration Files
877 extensions Using Additional Features
877 extensions Using Additional Features
878 glossary Glossary
878 glossary Glossary
879 phases Working with Phases
879 phases Working with Phases
880 subrepos Subrepositories
880 subrepos Subrepositories
881 urls URL Paths
881 urls URL Paths
882
882
883 Commands:
883 Commands:
884
884
885 bookmarks track a line of development with movable markers
885 bookmarks track a line of development with movable markers
886 clone make a copy of an existing repository
886 clone make a copy of an existing repository
887 paths show aliases for remote repositories
887 paths show aliases for remote repositories
888 update update working directory (or switch revisions)
888 update update working directory (or switch revisions)
889
889
890 Extensions:
890 Extensions:
891
891
892 prefixedname matched against word "clone"
892 prefixedname matched against word "clone"
893 relink recreates hardlinks between repository clones
893 relink recreates hardlinks between repository clones
894
894
895 Extension Commands:
895 Extension Commands:
896
896
897 qclone clone main and patch repository at same time
897 qclone clone main and patch repository at same time
898
898
899 Test omit indicating for help
899 Test omit indicating for help
900
900
901 $ cat > addverboseitems.py <<EOF
901 $ cat > addverboseitems.py <<EOF
902 > '''extension to test omit indicating.
902 > '''extension to test omit indicating.
903 >
903 >
904 > This paragraph is never omitted (for extension)
904 > This paragraph is never omitted (for extension)
905 >
905 >
906 > .. container:: verbose
906 > .. container:: verbose
907 >
907 >
908 > This paragraph is omitted,
908 > This paragraph is omitted,
909 > if :hg:\`help\` is invoked witout \`\`-v\`\` (for extension)
909 > if :hg:\`help\` is invoked witout \`\`-v\`\` (for extension)
910 >
910 >
911 > This paragraph is never omitted, too (for extension)
911 > This paragraph is never omitted, too (for extension)
912 > '''
912 > '''
913 >
913 >
914 > from mercurial import help, commands
914 > from mercurial import help, commands
915 > testtopic = """This paragraph is never omitted (for topic).
915 > testtopic = """This paragraph is never omitted (for topic).
916 >
916 >
917 > .. container:: verbose
917 > .. container:: verbose
918 >
918 >
919 > This paragraph is omitted,
919 > This paragraph is omitted,
920 > if :hg:\`help\` is invoked witout \`\`-v\`\` (for topic)
920 > if :hg:\`help\` is invoked witout \`\`-v\`\` (for topic)
921 >
921 >
922 > This paragraph is never omitted, too (for topic)
922 > This paragraph is never omitted, too (for topic)
923 > """
923 > """
924 > def extsetup(ui):
924 > def extsetup(ui):
925 > help.helptable.append((["topic-containing-verbose"],
925 > help.helptable.append((["topic-containing-verbose"],
926 > "This is the topic to test omit indicating.",
926 > "This is the topic to test omit indicating.",
927 > lambda : testtopic))
927 > lambda : testtopic))
928 > EOF
928 > EOF
929 $ echo '[extensions]' >> $HGRCPATH
929 $ echo '[extensions]' >> $HGRCPATH
930 $ echo "addverboseitems = `pwd`/addverboseitems.py" >> $HGRCPATH
930 $ echo "addverboseitems = `pwd`/addverboseitems.py" >> $HGRCPATH
931 $ hg help addverboseitems
931 $ hg help addverboseitems
932 addverboseitems extension - extension to test omit indicating.
932 addverboseitems extension - extension to test omit indicating.
933
933
934 This paragraph is never omitted (for extension)
934 This paragraph is never omitted (for extension)
935
935
936 This paragraph is never omitted, too (for extension)
936 This paragraph is never omitted, too (for extension)
937
937
938 use "hg help -v addverboseitems" to show more complete help
938 use "hg help -v addverboseitems" to show more complete help
939
939
940 no commands defined
940 no commands defined
941 $ hg help -v addverboseitems
941 $ hg help -v addverboseitems
942 addverboseitems extension - extension to test omit indicating.
942 addverboseitems extension - extension to test omit indicating.
943
943
944 This paragraph is never omitted (for extension)
944 This paragraph is never omitted (for extension)
945
945
946 This paragraph is omitted, if "hg help" is invoked witout "-v" (for extension)
946 This paragraph is omitted, if "hg help" is invoked witout "-v" (for extension)
947
947
948 This paragraph is never omitted, too (for extension)
948 This paragraph is never omitted, too (for extension)
949
949
950 no commands defined
950 no commands defined
951 $ hg help topic-containing-verbose
951 $ hg help topic-containing-verbose
952 This is the topic to test omit indicating.
952 This is the topic to test omit indicating.
953 """"""""""""""""""""""""""""""""""""""""""
953 """"""""""""""""""""""""""""""""""""""""""
954
954
955 This paragraph is never omitted (for topic).
955 This paragraph is never omitted (for topic).
956
956
957 This paragraph is never omitted, too (for topic)
957 This paragraph is never omitted, too (for topic)
958
958
959 use "hg help -v topic-containing-verbose" to show more complete help
959 use "hg help -v topic-containing-verbose" to show more complete help
960 $ hg help -v topic-containing-verbose
960 $ hg help -v topic-containing-verbose
961 This is the topic to test omit indicating.
961 This is the topic to test omit indicating.
962 """"""""""""""""""""""""""""""""""""""""""
962 """"""""""""""""""""""""""""""""""""""""""
963
963
964 This paragraph is never omitted (for topic).
964 This paragraph is never omitted (for topic).
965
965
966 This paragraph is omitted, if "hg help" is invoked witout "-v" (for topic)
966 This paragraph is omitted, if "hg help" is invoked witout "-v" (for topic)
967
967
968 This paragraph is never omitted, too (for topic)
968 This paragraph is never omitted, too (for topic)
969
969
970 Test usage of section marks in help documents
970 Test usage of section marks in help documents
971
971
972 $ cd "$TESTDIR"/../doc
972 $ cd "$TESTDIR"/../doc
973 $ python check-seclevel.py
973 $ python check-seclevel.py
974 $ cd $TESTTMP
974 $ cd $TESTTMP
975
975
976 #if serve
976 #if serve
977
977
978 Test the help pages in hgweb.
978 Test the help pages in hgweb.
979
979
980 Dish up an empty repo; serve it cold.
980 Dish up an empty repo; serve it cold.
981
981
982 $ hg init "$TESTTMP/test"
982 $ hg init "$TESTTMP/test"
983 $ hg serve -R "$TESTTMP/test" -n test -p $HGPORT -d --pid-file=hg.pid
983 $ hg serve -R "$TESTTMP/test" -n test -p $HGPORT -d --pid-file=hg.pid
984 $ cat hg.pid >> $DAEMON_PIDS
984 $ cat hg.pid >> $DAEMON_PIDS
985
985
986 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT "help"
986 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT "help"
987 200 Script output follows
987 200 Script output follows
988
988
989 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
989 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
990 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
990 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
991 <head>
991 <head>
992 <link rel="icon" href="/static/hgicon.png" type="image/png" />
992 <link rel="icon" href="/static/hgicon.png" type="image/png" />
993 <meta name="robots" content="index, nofollow" />
993 <meta name="robots" content="index, nofollow" />
994 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
994 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
995 <script type="text/javascript" src="/static/mercurial.js"></script>
995 <script type="text/javascript" src="/static/mercurial.js"></script>
996
996
997 <title>Help: Index</title>
997 <title>Help: Index</title>
998 </head>
998 </head>
999 <body>
999 <body>
1000
1000
1001 <div class="container">
1001 <div class="container">
1002 <div class="menu">
1002 <div class="menu">
1003 <div class="logo">
1003 <div class="logo">
1004 <a href="http://mercurial.selenic.com/">
1004 <a href="http://mercurial.selenic.com/">
1005 <img src="/static/hglogo.png" alt="mercurial" /></a>
1005 <img src="/static/hglogo.png" alt="mercurial" /></a>
1006 </div>
1006 </div>
1007 <ul>
1007 <ul>
1008 <li><a href="/shortlog">log</a></li>
1008 <li><a href="/shortlog">log</a></li>
1009 <li><a href="/graph">graph</a></li>
1009 <li><a href="/graph">graph</a></li>
1010 <li><a href="/tags">tags</a></li>
1010 <li><a href="/tags">tags</a></li>
1011 <li><a href="/bookmarks">bookmarks</a></li>
1011 <li><a href="/bookmarks">bookmarks</a></li>
1012 <li><a href="/branches">branches</a></li>
1012 <li><a href="/branches">branches</a></li>
1013 </ul>
1013 </ul>
1014 <ul>
1014 <ul>
1015 <li class="active">help</li>
1015 <li class="active">help</li>
1016 </ul>
1016 </ul>
1017 </div>
1017 </div>
1018
1018
1019 <div class="main">
1019 <div class="main">
1020 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
1020 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
1021 <form class="search" action="/log">
1021 <form class="search" action="/log">
1022
1022
1023 <p><input name="rev" id="search1" type="text" size="30" /></p>
1023 <p><input name="rev" id="search1" type="text" size="30" /></p>
1024 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
1024 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
1025 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
1025 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
1026 </form>
1026 </form>
1027 <table class="bigtable">
1027 <table class="bigtable">
1028 <tr><td colspan="2"><h2><a name="main" href="#topics">Topics</a></h2></td></tr>
1028 <tr><td colspan="2"><h2><a name="main" href="#topics">Topics</a></h2></td></tr>
1029
1029
1030 <tr><td>
1030 <tr><td>
1031 <a href="/help/config">
1031 <a href="/help/config">
1032 config
1032 config
1033 </a>
1033 </a>
1034 </td><td>
1034 </td><td>
1035 Configuration Files
1035 Configuration Files
1036 </td></tr>
1036 </td></tr>
1037 <tr><td>
1037 <tr><td>
1038 <a href="/help/dates">
1038 <a href="/help/dates">
1039 dates
1039 dates
1040 </a>
1040 </a>
1041 </td><td>
1041 </td><td>
1042 Date Formats
1042 Date Formats
1043 </td></tr>
1043 </td></tr>
1044 <tr><td>
1044 <tr><td>
1045 <a href="/help/diffs">
1045 <a href="/help/diffs">
1046 diffs
1046 diffs
1047 </a>
1047 </a>
1048 </td><td>
1048 </td><td>
1049 Diff Formats
1049 Diff Formats
1050 </td></tr>
1050 </td></tr>
1051 <tr><td>
1051 <tr><td>
1052 <a href="/help/environment">
1052 <a href="/help/environment">
1053 environment
1053 environment
1054 </a>
1054 </a>
1055 </td><td>
1055 </td><td>
1056 Environment Variables
1056 Environment Variables
1057 </td></tr>
1057 </td></tr>
1058 <tr><td>
1058 <tr><td>
1059 <a href="/help/extensions">
1059 <a href="/help/extensions">
1060 extensions
1060 extensions
1061 </a>
1061 </a>
1062 </td><td>
1062 </td><td>
1063 Using Additional Features
1063 Using Additional Features
1064 </td></tr>
1064 </td></tr>
1065 <tr><td>
1065 <tr><td>
1066 <a href="/help/filesets">
1066 <a href="/help/filesets">
1067 filesets
1067 filesets
1068 </a>
1068 </a>
1069 </td><td>
1069 </td><td>
1070 Specifying File Sets
1070 Specifying File Sets
1071 </td></tr>
1071 </td></tr>
1072 <tr><td>
1072 <tr><td>
1073 <a href="/help/glossary">
1073 <a href="/help/glossary">
1074 glossary
1074 glossary
1075 </a>
1075 </a>
1076 </td><td>
1076 </td><td>
1077 Glossary
1077 Glossary
1078 </td></tr>
1078 </td></tr>
1079 <tr><td>
1079 <tr><td>
1080 <a href="/help/hgignore">
1080 <a href="/help/hgignore">
1081 hgignore
1081 hgignore
1082 </a>
1082 </a>
1083 </td><td>
1083 </td><td>
1084 Syntax for Mercurial Ignore Files
1084 Syntax for Mercurial Ignore Files
1085 </td></tr>
1085 </td></tr>
1086 <tr><td>
1086 <tr><td>
1087 <a href="/help/hgweb">
1087 <a href="/help/hgweb">
1088 hgweb
1088 hgweb
1089 </a>
1089 </a>
1090 </td><td>
1090 </td><td>
1091 Configuring hgweb
1091 Configuring hgweb
1092 </td></tr>
1092 </td></tr>
1093 <tr><td>
1093 <tr><td>
1094 <a href="/help/merge-tools">
1094 <a href="/help/merge-tools">
1095 merge-tools
1095 merge-tools
1096 </a>
1096 </a>
1097 </td><td>
1097 </td><td>
1098 Merge Tools
1098 Merge Tools
1099 </td></tr>
1099 </td></tr>
1100 <tr><td>
1100 <tr><td>
1101 <a href="/help/multirevs">
1101 <a href="/help/multirevs">
1102 multirevs
1102 multirevs
1103 </a>
1103 </a>
1104 </td><td>
1104 </td><td>
1105 Specifying Multiple Revisions
1105 Specifying Multiple Revisions
1106 </td></tr>
1106 </td></tr>
1107 <tr><td>
1107 <tr><td>
1108 <a href="/help/patterns">
1108 <a href="/help/patterns">
1109 patterns
1109 patterns
1110 </a>
1110 </a>
1111 </td><td>
1111 </td><td>
1112 File Name Patterns
1112 File Name Patterns
1113 </td></tr>
1113 </td></tr>
1114 <tr><td>
1114 <tr><td>
1115 <a href="/help/phases">
1115 <a href="/help/phases">
1116 phases
1116 phases
1117 </a>
1117 </a>
1118 </td><td>
1118 </td><td>
1119 Working with Phases
1119 Working with Phases
1120 </td></tr>
1120 </td></tr>
1121 <tr><td>
1121 <tr><td>
1122 <a href="/help/revisions">
1122 <a href="/help/revisions">
1123 revisions
1123 revisions
1124 </a>
1124 </a>
1125 </td><td>
1125 </td><td>
1126 Specifying Single Revisions
1126 Specifying Single Revisions
1127 </td></tr>
1127 </td></tr>
1128 <tr><td>
1128 <tr><td>
1129 <a href="/help/revsets">
1129 <a href="/help/revsets">
1130 revsets
1130 revsets
1131 </a>
1131 </a>
1132 </td><td>
1132 </td><td>
1133 Specifying Revision Sets
1133 Specifying Revision Sets
1134 </td></tr>
1134 </td></tr>
1135 <tr><td>
1135 <tr><td>
1136 <a href="/help/subrepos">
1136 <a href="/help/subrepos">
1137 subrepos
1137 subrepos
1138 </a>
1138 </a>
1139 </td><td>
1139 </td><td>
1140 Subrepositories
1140 Subrepositories
1141 </td></tr>
1141 </td></tr>
1142 <tr><td>
1142 <tr><td>
1143 <a href="/help/templating">
1143 <a href="/help/templating">
1144 templating
1144 templating
1145 </a>
1145 </a>
1146 </td><td>
1146 </td><td>
1147 Template Usage
1147 Template Usage
1148 </td></tr>
1148 </td></tr>
1149 <tr><td>
1149 <tr><td>
1150 <a href="/help/urls">
1150 <a href="/help/urls">
1151 urls
1151 urls
1152 </a>
1152 </a>
1153 </td><td>
1153 </td><td>
1154 URL Paths
1154 URL Paths
1155 </td></tr>
1155 </td></tr>
1156 <tr><td>
1156 <tr><td>
1157 <a href="/help/topic-containing-verbose">
1157 <a href="/help/topic-containing-verbose">
1158 topic-containing-verbose
1158 topic-containing-verbose
1159 </a>
1159 </a>
1160 </td><td>
1160 </td><td>
1161 This is the topic to test omit indicating.
1161 This is the topic to test omit indicating.
1162 </td></tr>
1162 </td></tr>
1163
1163
1164 <tr><td colspan="2"><h2><a name="main" href="#main">Main Commands</a></h2></td></tr>
1164 <tr><td colspan="2"><h2><a name="main" href="#main">Main Commands</a></h2></td></tr>
1165
1165
1166 <tr><td>
1166 <tr><td>
1167 <a href="/help/add">
1167 <a href="/help/add">
1168 add
1168 add
1169 </a>
1169 </a>
1170 </td><td>
1170 </td><td>
1171 add the specified files on the next commit
1171 add the specified files on the next commit
1172 </td></tr>
1172 </td></tr>
1173 <tr><td>
1173 <tr><td>
1174 <a href="/help/annotate">
1174 <a href="/help/annotate">
1175 annotate
1175 annotate
1176 </a>
1176 </a>
1177 </td><td>
1177 </td><td>
1178 show changeset information by line for each file
1178 show changeset information by line for each file
1179 </td></tr>
1179 </td></tr>
1180 <tr><td>
1180 <tr><td>
1181 <a href="/help/clone">
1181 <a href="/help/clone">
1182 clone
1182 clone
1183 </a>
1183 </a>
1184 </td><td>
1184 </td><td>
1185 make a copy of an existing repository
1185 make a copy of an existing repository
1186 </td></tr>
1186 </td></tr>
1187 <tr><td>
1187 <tr><td>
1188 <a href="/help/commit">
1188 <a href="/help/commit">
1189 commit
1189 commit
1190 </a>
1190 </a>
1191 </td><td>
1191 </td><td>
1192 commit the specified files or all outstanding changes
1192 commit the specified files or all outstanding changes
1193 </td></tr>
1193 </td></tr>
1194 <tr><td>
1194 <tr><td>
1195 <a href="/help/diff">
1195 <a href="/help/diff">
1196 diff
1196 diff
1197 </a>
1197 </a>
1198 </td><td>
1198 </td><td>
1199 diff repository (or selected files)
1199 diff repository (or selected files)
1200 </td></tr>
1200 </td></tr>
1201 <tr><td>
1201 <tr><td>
1202 <a href="/help/export">
1202 <a href="/help/export">
1203 export
1203 export
1204 </a>
1204 </a>
1205 </td><td>
1205 </td><td>
1206 dump the header and diffs for one or more changesets
1206 dump the header and diffs for one or more changesets
1207 </td></tr>
1207 </td></tr>
1208 <tr><td>
1208 <tr><td>
1209 <a href="/help/forget">
1209 <a href="/help/forget">
1210 forget
1210 forget
1211 </a>
1211 </a>
1212 </td><td>
1212 </td><td>
1213 forget the specified files on the next commit
1213 forget the specified files on the next commit
1214 </td></tr>
1214 </td></tr>
1215 <tr><td>
1215 <tr><td>
1216 <a href="/help/init">
1216 <a href="/help/init">
1217 init
1217 init
1218 </a>
1218 </a>
1219 </td><td>
1219 </td><td>
1220 create a new repository in the given directory
1220 create a new repository in the given directory
1221 </td></tr>
1221 </td></tr>
1222 <tr><td>
1222 <tr><td>
1223 <a href="/help/log">
1223 <a href="/help/log">
1224 log
1224 log
1225 </a>
1225 </a>
1226 </td><td>
1226 </td><td>
1227 show revision history of entire repository or files
1227 show revision history of entire repository or files
1228 </td></tr>
1228 </td></tr>
1229 <tr><td>
1229 <tr><td>
1230 <a href="/help/merge">
1230 <a href="/help/merge">
1231 merge
1231 merge
1232 </a>
1232 </a>
1233 </td><td>
1233 </td><td>
1234 merge working directory with another revision
1234 merge working directory with another revision
1235 </td></tr>
1235 </td></tr>
1236 <tr><td>
1236 <tr><td>
1237 <a href="/help/pull">
1237 <a href="/help/pull">
1238 pull
1238 pull
1239 </a>
1239 </a>
1240 </td><td>
1240 </td><td>
1241 pull changes from the specified source
1241 pull changes from the specified source
1242 </td></tr>
1242 </td></tr>
1243 <tr><td>
1243 <tr><td>
1244 <a href="/help/push">
1244 <a href="/help/push">
1245 push
1245 push
1246 </a>
1246 </a>
1247 </td><td>
1247 </td><td>
1248 push changes to the specified destination
1248 push changes to the specified destination
1249 </td></tr>
1249 </td></tr>
1250 <tr><td>
1250 <tr><td>
1251 <a href="/help/remove">
1251 <a href="/help/remove">
1252 remove
1252 remove
1253 </a>
1253 </a>
1254 </td><td>
1254 </td><td>
1255 remove the specified files on the next commit
1255 remove the specified files on the next commit
1256 </td></tr>
1256 </td></tr>
1257 <tr><td>
1257 <tr><td>
1258 <a href="/help/serve">
1258 <a href="/help/serve">
1259 serve
1259 serve
1260 </a>
1260 </a>
1261 </td><td>
1261 </td><td>
1262 start stand-alone webserver
1262 start stand-alone webserver
1263 </td></tr>
1263 </td></tr>
1264 <tr><td>
1264 <tr><td>
1265 <a href="/help/status">
1265 <a href="/help/status">
1266 status
1266 status
1267 </a>
1267 </a>
1268 </td><td>
1268 </td><td>
1269 show changed files in the working directory
1269 show changed files in the working directory
1270 </td></tr>
1270 </td></tr>
1271 <tr><td>
1271 <tr><td>
1272 <a href="/help/summary">
1272 <a href="/help/summary">
1273 summary
1273 summary
1274 </a>
1274 </a>
1275 </td><td>
1275 </td><td>
1276 summarize working directory state
1276 summarize working directory state
1277 </td></tr>
1277 </td></tr>
1278 <tr><td>
1278 <tr><td>
1279 <a href="/help/update">
1279 <a href="/help/update">
1280 update
1280 update
1281 </a>
1281 </a>
1282 </td><td>
1282 </td><td>
1283 update working directory (or switch revisions)
1283 update working directory (or switch revisions)
1284 </td></tr>
1284 </td></tr>
1285
1285
1286 <tr><td colspan="2"><h2><a name="other" href="#other">Other Commands</a></h2></td></tr>
1286 <tr><td colspan="2"><h2><a name="other" href="#other">Other Commands</a></h2></td></tr>
1287
1287
1288 <tr><td>
1288 <tr><td>
1289 <a href="/help/addremove">
1289 <a href="/help/addremove">
1290 addremove
1290 addremove
1291 </a>
1291 </a>
1292 </td><td>
1292 </td><td>
1293 add all new files, delete all missing files
1293 add all new files, delete all missing files
1294 </td></tr>
1294 </td></tr>
1295 <tr><td>
1295 <tr><td>
1296 <a href="/help/archive">
1296 <a href="/help/archive">
1297 archive
1297 archive
1298 </a>
1298 </a>
1299 </td><td>
1299 </td><td>
1300 create an unversioned archive of a repository revision
1300 create an unversioned archive of a repository revision
1301 </td></tr>
1301 </td></tr>
1302 <tr><td>
1302 <tr><td>
1303 <a href="/help/backout">
1303 <a href="/help/backout">
1304 backout
1304 backout
1305 </a>
1305 </a>
1306 </td><td>
1306 </td><td>
1307 reverse effect of earlier changeset
1307 reverse effect of earlier changeset
1308 </td></tr>
1308 </td></tr>
1309 <tr><td>
1309 <tr><td>
1310 <a href="/help/bisect">
1310 <a href="/help/bisect">
1311 bisect
1311 bisect
1312 </a>
1312 </a>
1313 </td><td>
1313 </td><td>
1314 subdivision search of changesets
1314 subdivision search of changesets
1315 </td></tr>
1315 </td></tr>
1316 <tr><td>
1316 <tr><td>
1317 <a href="/help/bookmarks">
1317 <a href="/help/bookmarks">
1318 bookmarks
1318 bookmarks
1319 </a>
1319 </a>
1320 </td><td>
1320 </td><td>
1321 track a line of development with movable markers
1321 track a line of development with movable markers
1322 </td></tr>
1322 </td></tr>
1323 <tr><td>
1323 <tr><td>
1324 <a href="/help/branch">
1324 <a href="/help/branch">
1325 branch
1325 branch
1326 </a>
1326 </a>
1327 </td><td>
1327 </td><td>
1328 set or show the current branch name
1328 set or show the current branch name
1329 </td></tr>
1329 </td></tr>
1330 <tr><td>
1330 <tr><td>
1331 <a href="/help/branches">
1331 <a href="/help/branches">
1332 branches
1332 branches
1333 </a>
1333 </a>
1334 </td><td>
1334 </td><td>
1335 list repository named branches
1335 list repository named branches
1336 </td></tr>
1336 </td></tr>
1337 <tr><td>
1337 <tr><td>
1338 <a href="/help/bundle">
1338 <a href="/help/bundle">
1339 bundle
1339 bundle
1340 </a>
1340 </a>
1341 </td><td>
1341 </td><td>
1342 create a changegroup file
1342 create a changegroup file
1343 </td></tr>
1343 </td></tr>
1344 <tr><td>
1344 <tr><td>
1345 <a href="/help/cat">
1345 <a href="/help/cat">
1346 cat
1346 cat
1347 </a>
1347 </a>
1348 </td><td>
1348 </td><td>
1349 output the current or given revision of files
1349 output the current or given revision of files
1350 </td></tr>
1350 </td></tr>
1351 <tr><td>
1351 <tr><td>
1352 <a href="/help/config">
1352 <a href="/help/config">
1353 config
1353 config
1354 </a>
1354 </a>
1355 </td><td>
1355 </td><td>
1356 show combined config settings from all hgrc files
1356 show combined config settings from all hgrc files
1357 </td></tr>
1357 </td></tr>
1358 <tr><td>
1358 <tr><td>
1359 <a href="/help/copy">
1359 <a href="/help/copy">
1360 copy
1360 copy
1361 </a>
1361 </a>
1362 </td><td>
1362 </td><td>
1363 mark files as copied for the next commit
1363 mark files as copied for the next commit
1364 </td></tr>
1364 </td></tr>
1365 <tr><td>
1365 <tr><td>
1366 <a href="/help/graft">
1366 <a href="/help/graft">
1367 graft
1367 graft
1368 </a>
1368 </a>
1369 </td><td>
1369 </td><td>
1370 copy changes from other branches onto the current branch
1370 copy changes from other branches onto the current branch
1371 </td></tr>
1371 </td></tr>
1372 <tr><td>
1372 <tr><td>
1373 <a href="/help/grep">
1373 <a href="/help/grep">
1374 grep
1374 grep
1375 </a>
1375 </a>
1376 </td><td>
1376 </td><td>
1377 search for a pattern in specified files and revisions
1377 search for a pattern in specified files and revisions
1378 </td></tr>
1378 </td></tr>
1379 <tr><td>
1379 <tr><td>
1380 <a href="/help/heads">
1380 <a href="/help/heads">
1381 heads
1381 heads
1382 </a>
1382 </a>
1383 </td><td>
1383 </td><td>
1384 show branch heads
1384 show branch heads
1385 </td></tr>
1385 </td></tr>
1386 <tr><td>
1386 <tr><td>
1387 <a href="/help/help">
1387 <a href="/help/help">
1388 help
1388 help
1389 </a>
1389 </a>
1390 </td><td>
1390 </td><td>
1391 show help for a given topic or a help overview
1391 show help for a given topic or a help overview
1392 </td></tr>
1392 </td></tr>
1393 <tr><td>
1393 <tr><td>
1394 <a href="/help/identify">
1394 <a href="/help/identify">
1395 identify
1395 identify
1396 </a>
1396 </a>
1397 </td><td>
1397 </td><td>
1398 identify the working copy or specified revision
1398 identify the working copy or specified revision
1399 </td></tr>
1399 </td></tr>
1400 <tr><td>
1400 <tr><td>
1401 <a href="/help/import">
1401 <a href="/help/import">
1402 import
1402 import
1403 </a>
1403 </a>
1404 </td><td>
1404 </td><td>
1405 import an ordered set of patches
1405 import an ordered set of patches
1406 </td></tr>
1406 </td></tr>
1407 <tr><td>
1407 <tr><td>
1408 <a href="/help/incoming">
1408 <a href="/help/incoming">
1409 incoming
1409 incoming
1410 </a>
1410 </a>
1411 </td><td>
1411 </td><td>
1412 show new changesets found in source
1412 show new changesets found in source
1413 </td></tr>
1413 </td></tr>
1414 <tr><td>
1414 <tr><td>
1415 <a href="/help/locate">
1415 <a href="/help/locate">
1416 locate
1416 locate
1417 </a>
1417 </a>
1418 </td><td>
1418 </td><td>
1419 locate files matching specific patterns
1419 locate files matching specific patterns
1420 </td></tr>
1420 </td></tr>
1421 <tr><td>
1421 <tr><td>
1422 <a href="/help/manifest">
1422 <a href="/help/manifest">
1423 manifest
1423 manifest
1424 </a>
1424 </a>
1425 </td><td>
1425 </td><td>
1426 output the current or given revision of the project manifest
1426 output the current or given revision of the project manifest
1427 </td></tr>
1427 </td></tr>
1428 <tr><td>
1428 <tr><td>
1429 <a href="/help/nohelp">
1429 <a href="/help/nohelp">
1430 nohelp
1430 nohelp
1431 </a>
1431 </a>
1432 </td><td>
1432 </td><td>
1433 (no help text available)
1433 (no help text available)
1434 </td></tr>
1434 </td></tr>
1435 <tr><td>
1435 <tr><td>
1436 <a href="/help/outgoing">
1436 <a href="/help/outgoing">
1437 outgoing
1437 outgoing
1438 </a>
1438 </a>
1439 </td><td>
1439 </td><td>
1440 show changesets not found in the destination
1440 show changesets not found in the destination
1441 </td></tr>
1441 </td></tr>
1442 <tr><td>
1442 <tr><td>
1443 <a href="/help/parents">
1443 <a href="/help/parents">
1444 parents
1444 parents
1445 </a>
1445 </a>
1446 </td><td>
1446 </td><td>
1447 show the parents of the working directory or revision
1447 show the parents of the working directory or revision
1448 </td></tr>
1448 </td></tr>
1449 <tr><td>
1449 <tr><td>
1450 <a href="/help/paths">
1450 <a href="/help/paths">
1451 paths
1451 paths
1452 </a>
1452 </a>
1453 </td><td>
1453 </td><td>
1454 show aliases for remote repositories
1454 show aliases for remote repositories
1455 </td></tr>
1455 </td></tr>
1456 <tr><td>
1456 <tr><td>
1457 <a href="/help/phase">
1457 <a href="/help/phase">
1458 phase
1458 phase
1459 </a>
1459 </a>
1460 </td><td>
1460 </td><td>
1461 set or show the current phase name
1461 set or show the current phase name
1462 </td></tr>
1462 </td></tr>
1463 <tr><td>
1463 <tr><td>
1464 <a href="/help/recover">
1464 <a href="/help/recover">
1465 recover
1465 recover
1466 </a>
1466 </a>
1467 </td><td>
1467 </td><td>
1468 roll back an interrupted transaction
1468 roll back an interrupted transaction
1469 </td></tr>
1469 </td></tr>
1470 <tr><td>
1470 <tr><td>
1471 <a href="/help/rename">
1471 <a href="/help/rename">
1472 rename
1472 rename
1473 </a>
1473 </a>
1474 </td><td>
1474 </td><td>
1475 rename files; equivalent of copy + remove
1475 rename files; equivalent of copy + remove
1476 </td></tr>
1476 </td></tr>
1477 <tr><td>
1477 <tr><td>
1478 <a href="/help/resolve">
1478 <a href="/help/resolve">
1479 resolve
1479 resolve
1480 </a>
1480 </a>
1481 </td><td>
1481 </td><td>
1482 redo merges or set/view the merge status of files
1482 redo merges or set/view the merge status of files
1483 </td></tr>
1483 </td></tr>
1484 <tr><td>
1484 <tr><td>
1485 <a href="/help/revert">
1485 <a href="/help/revert">
1486 revert
1486 revert
1487 </a>
1487 </a>
1488 </td><td>
1488 </td><td>
1489 restore files to their checkout state
1489 restore files to their checkout state
1490 </td></tr>
1490 </td></tr>
1491 <tr><td>
1491 <tr><td>
1492 <a href="/help/root">
1492 <a href="/help/root">
1493 root
1493 root
1494 </a>
1494 </a>
1495 </td><td>
1495 </td><td>
1496 print the root (top) of the current working directory
1496 print the root (top) of the current working directory
1497 </td></tr>
1497 </td></tr>
1498 <tr><td>
1498 <tr><td>
1499 <a href="/help/tag">
1499 <a href="/help/tag">
1500 tag
1500 tag
1501 </a>
1501 </a>
1502 </td><td>
1502 </td><td>
1503 add one or more tags for the current or given revision
1503 add one or more tags for the current or given revision
1504 </td></tr>
1504 </td></tr>
1505 <tr><td>
1505 <tr><td>
1506 <a href="/help/tags">
1506 <a href="/help/tags">
1507 tags
1507 tags
1508 </a>
1508 </a>
1509 </td><td>
1509 </td><td>
1510 list repository tags
1510 list repository tags
1511 </td></tr>
1511 </td></tr>
1512 <tr><td>
1512 <tr><td>
1513 <a href="/help/unbundle">
1513 <a href="/help/unbundle">
1514 unbundle
1514 unbundle
1515 </a>
1515 </a>
1516 </td><td>
1516 </td><td>
1517 apply one or more changegroup files
1517 apply one or more changegroup files
1518 </td></tr>
1518 </td></tr>
1519 <tr><td>
1519 <tr><td>
1520 <a href="/help/verify">
1520 <a href="/help/verify">
1521 verify
1521 verify
1522 </a>
1522 </a>
1523 </td><td>
1523 </td><td>
1524 verify the integrity of the repository
1524 verify the integrity of the repository
1525 </td></tr>
1525 </td></tr>
1526 <tr><td>
1526 <tr><td>
1527 <a href="/help/version">
1527 <a href="/help/version">
1528 version
1528 version
1529 </a>
1529 </a>
1530 </td><td>
1530 </td><td>
1531 output version and copyright information
1531 output version and copyright information
1532 </td></tr>
1532 </td></tr>
1533 </table>
1533 </table>
1534 </div>
1534 </div>
1535 </div>
1535 </div>
1536
1536
1537 <script type="text/javascript">process_dates()</script>
1537 <script type="text/javascript">process_dates()</script>
1538
1538
1539
1539
1540 </body>
1540 </body>
1541 </html>
1541 </html>
1542
1542
1543
1543
1544 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT "help/add"
1544 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT "help/add"
1545 200 Script output follows
1545 200 Script output follows
1546
1546
1547 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
1547 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
1548 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
1548 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
1549 <head>
1549 <head>
1550 <link rel="icon" href="/static/hgicon.png" type="image/png" />
1550 <link rel="icon" href="/static/hgicon.png" type="image/png" />
1551 <meta name="robots" content="index, nofollow" />
1551 <meta name="robots" content="index, nofollow" />
1552 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
1552 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
1553 <script type="text/javascript" src="/static/mercurial.js"></script>
1553 <script type="text/javascript" src="/static/mercurial.js"></script>
1554
1554
1555 <title>Help: add</title>
1555 <title>Help: add</title>
1556 </head>
1556 </head>
1557 <body>
1557 <body>
1558
1558
1559 <div class="container">
1559 <div class="container">
1560 <div class="menu">
1560 <div class="menu">
1561 <div class="logo">
1561 <div class="logo">
1562 <a href="http://mercurial.selenic.com/">
1562 <a href="http://mercurial.selenic.com/">
1563 <img src="/static/hglogo.png" alt="mercurial" /></a>
1563 <img src="/static/hglogo.png" alt="mercurial" /></a>
1564 </div>
1564 </div>
1565 <ul>
1565 <ul>
1566 <li><a href="/shortlog">log</a></li>
1566 <li><a href="/shortlog">log</a></li>
1567 <li><a href="/graph">graph</a></li>
1567 <li><a href="/graph">graph</a></li>
1568 <li><a href="/tags">tags</a></li>
1568 <li><a href="/tags">tags</a></li>
1569 <li><a href="/bookmarks">bookmarks</a></li>
1569 <li><a href="/bookmarks">bookmarks</a></li>
1570 <li><a href="/branches">branches</a></li>
1570 <li><a href="/branches">branches</a></li>
1571 </ul>
1571 </ul>
1572 <ul>
1572 <ul>
1573 <li class="active"><a href="/help">help</a></li>
1573 <li class="active"><a href="/help">help</a></li>
1574 </ul>
1574 </ul>
1575 </div>
1575 </div>
1576
1576
1577 <div class="main">
1577 <div class="main">
1578 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
1578 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
1579 <h3>Help: add</h3>
1579 <h3>Help: add</h3>
1580
1580
1581 <form class="search" action="/log">
1581 <form class="search" action="/log">
1582
1582
1583 <p><input name="rev" id="search1" type="text" size="30" /></p>
1583 <p><input name="rev" id="search1" type="text" size="30" /></p>
1584 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
1584 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
1585 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
1585 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
1586 </form>
1586 </form>
1587 <div id="doc">
1587 <div id="doc">
1588 <p>
1588 <p>
1589 hg add [OPTION]... [FILE]...
1589 hg add [OPTION]... [FILE]...
1590 </p>
1590 </p>
1591 <p>
1591 <p>
1592 add the specified files on the next commit
1592 add the specified files on the next commit
1593 </p>
1593 </p>
1594 <p>
1594 <p>
1595 Schedule files to be version controlled and added to the
1595 Schedule files to be version controlled and added to the
1596 repository.
1596 repository.
1597 </p>
1597 </p>
1598 <p>
1598 <p>
1599 The files will be added to the repository at the next commit. To
1599 The files will be added to the repository at the next commit. To
1600 undo an add before that, see &quot;hg forget&quot;.
1600 undo an add before that, see &quot;hg forget&quot;.
1601 </p>
1601 </p>
1602 <p>
1602 <p>
1603 If no names are given, add all files to the repository.
1603 If no names are given, add all files to the repository.
1604 </p>
1604 </p>
1605 <p>
1605 <p>
1606 An example showing how new (unknown) files are added
1606 An example showing how new (unknown) files are added
1607 automatically by &quot;hg add&quot;:
1607 automatically by &quot;hg add&quot;:
1608 </p>
1608 </p>
1609 <pre>
1609 <pre>
1610 \$ ls (re)
1610 \$ ls (re)
1611 foo.c
1611 foo.c
1612 \$ hg status (re)
1612 \$ hg status (re)
1613 ? foo.c
1613 ? foo.c
1614 \$ hg add (re)
1614 \$ hg add (re)
1615 adding foo.c
1615 adding foo.c
1616 \$ hg status (re)
1616 \$ hg status (re)
1617 A foo.c
1617 A foo.c
1618 </pre>
1618 </pre>
1619 <p>
1619 <p>
1620 Returns 0 if all files are successfully added.
1620 Returns 0 if all files are successfully added.
1621 </p>
1621 </p>
1622 <p>
1622 <p>
1623 options:
1623 options:
1624 </p>
1624 </p>
1625 <table>
1625 <table>
1626 <tr><td>-I</td>
1626 <tr><td>-I</td>
1627 <td>--include PATTERN [+]</td>
1627 <td>--include PATTERN [+]</td>
1628 <td>include names matching the given patterns</td></tr>
1628 <td>include names matching the given patterns</td></tr>
1629 <tr><td>-X</td>
1629 <tr><td>-X</td>
1630 <td>--exclude PATTERN [+]</td>
1630 <td>--exclude PATTERN [+]</td>
1631 <td>exclude names matching the given patterns</td></tr>
1631 <td>exclude names matching the given patterns</td></tr>
1632 <tr><td>-S</td>
1632 <tr><td>-S</td>
1633 <td>--subrepos</td>
1633 <td>--subrepos</td>
1634 <td>recurse into subrepositories</td></tr>
1634 <td>recurse into subrepositories</td></tr>
1635 <tr><td>-n</td>
1635 <tr><td>-n</td>
1636 <td>--dry-run</td>
1636 <td>--dry-run</td>
1637 <td>do not perform actions, just print output</td></tr>
1637 <td>do not perform actions, just print output</td></tr>
1638 </table>
1638 </table>
1639 <p>
1639 <p>
1640 [+] marked option can be specified multiple times
1640 [+] marked option can be specified multiple times
1641 </p>
1641 </p>
1642 <p>
1642 <p>
1643 global options:
1643 global options:
1644 </p>
1644 </p>
1645 <table>
1645 <table>
1646 <tr><td>-R</td>
1646 <tr><td>-R</td>
1647 <td>--repository REPO</td>
1647 <td>--repository REPO</td>
1648 <td>repository root directory or name of overlay bundle file</td></tr>
1648 <td>repository root directory or name of overlay bundle file</td></tr>
1649 <tr><td></td>
1649 <tr><td></td>
1650 <td>--cwd DIR</td>
1650 <td>--cwd DIR</td>
1651 <td>change working directory</td></tr>
1651 <td>change working directory</td></tr>
1652 <tr><td>-y</td>
1652 <tr><td>-y</td>
1653 <td>--noninteractive</td>
1653 <td>--noninteractive</td>
1654 <td>do not prompt, automatically pick the first choice for all prompts</td></tr>
1654 <td>do not prompt, automatically pick the first choice for all prompts</td></tr>
1655 <tr><td>-q</td>
1655 <tr><td>-q</td>
1656 <td>--quiet</td>
1656 <td>--quiet</td>
1657 <td>suppress output</td></tr>
1657 <td>suppress output</td></tr>
1658 <tr><td>-v</td>
1658 <tr><td>-v</td>
1659 <td>--verbose</td>
1659 <td>--verbose</td>
1660 <td>enable additional output</td></tr>
1660 <td>enable additional output</td></tr>
1661 <tr><td></td>
1661 <tr><td></td>
1662 <td>--config CONFIG [+]</td>
1662 <td>--config CONFIG [+]</td>
1663 <td>set/override config option (use 'section.name=value')</td></tr>
1663 <td>set/override config option (use 'section.name=value')</td></tr>
1664 <tr><td></td>
1664 <tr><td></td>
1665 <td>--debug</td>
1665 <td>--debug</td>
1666 <td>enable debugging output</td></tr>
1666 <td>enable debugging output</td></tr>
1667 <tr><td></td>
1667 <tr><td></td>
1668 <td>--debugger</td>
1668 <td>--debugger</td>
1669 <td>start debugger</td></tr>
1669 <td>start debugger</td></tr>
1670 <tr><td></td>
1670 <tr><td></td>
1671 <td>--encoding ENCODE</td>
1671 <td>--encoding ENCODE</td>
1672 <td>set the charset encoding (default: ascii)</td></tr>
1672 <td>set the charset encoding (default: ascii)</td></tr>
1673 <tr><td></td>
1673 <tr><td></td>
1674 <td>--encodingmode MODE</td>
1674 <td>--encodingmode MODE</td>
1675 <td>set the charset encoding mode (default: strict)</td></tr>
1675 <td>set the charset encoding mode (default: strict)</td></tr>
1676 <tr><td></td>
1676 <tr><td></td>
1677 <td>--traceback</td>
1677 <td>--traceback</td>
1678 <td>always print a traceback on exception</td></tr>
1678 <td>always print a traceback on exception</td></tr>
1679 <tr><td></td>
1679 <tr><td></td>
1680 <td>--time</td>
1680 <td>--time</td>
1681 <td>time how long the command takes</td></tr>
1681 <td>time how long the command takes</td></tr>
1682 <tr><td></td>
1682 <tr><td></td>
1683 <td>--profile</td>
1683 <td>--profile</td>
1684 <td>print command execution profile</td></tr>
1684 <td>print command execution profile</td></tr>
1685 <tr><td></td>
1685 <tr><td></td>
1686 <td>--version</td>
1686 <td>--version</td>
1687 <td>output version information and exit</td></tr>
1687 <td>output version information and exit</td></tr>
1688 <tr><td>-h</td>
1688 <tr><td>-h</td>
1689 <td>--help</td>
1689 <td>--help</td>
1690 <td>display help and exit</td></tr>
1690 <td>display help and exit</td></tr>
1691 <tr><td></td>
1691 <tr><td></td>
1692 <td>--hidden</td>
1692 <td>--hidden</td>
1693 <td>consider hidden changesets</td></tr>
1693 <td>consider hidden changesets</td></tr>
1694 </table>
1694 </table>
1695 <p>
1695 <p>
1696 [+] marked option can be specified multiple times
1696 [+] marked option can be specified multiple times
1697 </p>
1697 </p>
1698
1698
1699 </div>
1699 </div>
1700 </div>
1700 </div>
1701 </div>
1701 </div>
1702
1702
1703 <script type="text/javascript">process_dates()</script>
1703 <script type="text/javascript">process_dates()</script>
1704
1704
1705
1705
1706 </body>
1706 </body>
1707 </html>
1707 </html>
1708
1708
1709
1709
1710 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT "help/remove"
1710 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT "help/remove"
1711 200 Script output follows
1711 200 Script output follows
1712
1712
1713 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
1713 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
1714 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
1714 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
1715 <head>
1715 <head>
1716 <link rel="icon" href="/static/hgicon.png" type="image/png" />
1716 <link rel="icon" href="/static/hgicon.png" type="image/png" />
1717 <meta name="robots" content="index, nofollow" />
1717 <meta name="robots" content="index, nofollow" />
1718 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
1718 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
1719 <script type="text/javascript" src="/static/mercurial.js"></script>
1719 <script type="text/javascript" src="/static/mercurial.js"></script>
1720
1720
1721 <title>Help: remove</title>
1721 <title>Help: remove</title>
1722 </head>
1722 </head>
1723 <body>
1723 <body>
1724
1724
1725 <div class="container">
1725 <div class="container">
1726 <div class="menu">
1726 <div class="menu">
1727 <div class="logo">
1727 <div class="logo">
1728 <a href="http://mercurial.selenic.com/">
1728 <a href="http://mercurial.selenic.com/">
1729 <img src="/static/hglogo.png" alt="mercurial" /></a>
1729 <img src="/static/hglogo.png" alt="mercurial" /></a>
1730 </div>
1730 </div>
1731 <ul>
1731 <ul>
1732 <li><a href="/shortlog">log</a></li>
1732 <li><a href="/shortlog">log</a></li>
1733 <li><a href="/graph">graph</a></li>
1733 <li><a href="/graph">graph</a></li>
1734 <li><a href="/tags">tags</a></li>
1734 <li><a href="/tags">tags</a></li>
1735 <li><a href="/bookmarks">bookmarks</a></li>
1735 <li><a href="/bookmarks">bookmarks</a></li>
1736 <li><a href="/branches">branches</a></li>
1736 <li><a href="/branches">branches</a></li>
1737 </ul>
1737 </ul>
1738 <ul>
1738 <ul>
1739 <li class="active"><a href="/help">help</a></li>
1739 <li class="active"><a href="/help">help</a></li>
1740 </ul>
1740 </ul>
1741 </div>
1741 </div>
1742
1742
1743 <div class="main">
1743 <div class="main">
1744 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
1744 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
1745 <h3>Help: remove</h3>
1745 <h3>Help: remove</h3>
1746
1746
1747 <form class="search" action="/log">
1747 <form class="search" action="/log">
1748
1748
1749 <p><input name="rev" id="search1" type="text" size="30" /></p>
1749 <p><input name="rev" id="search1" type="text" size="30" /></p>
1750 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
1750 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
1751 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
1751 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
1752 </form>
1752 </form>
1753 <div id="doc">
1753 <div id="doc">
1754 <p>
1754 <p>
1755 hg remove [OPTION]... FILE...
1755 hg remove [OPTION]... FILE...
1756 </p>
1756 </p>
1757 <p>
1757 <p>
1758 aliases: rm
1758 aliases: rm
1759 </p>
1759 </p>
1760 <p>
1760 <p>
1761 remove the specified files on the next commit
1761 remove the specified files on the next commit
1762 </p>
1762 </p>
1763 <p>
1763 <p>
1764 Schedule the indicated files for removal from the current branch.
1764 Schedule the indicated files for removal from the current branch.
1765 </p>
1765 </p>
1766 <p>
1766 <p>
1767 This command schedules the files to be removed at the next commit.
1767 This command schedules the files to be removed at the next commit.
1768 To undo a remove before that, see &quot;hg revert&quot;. To undo added
1768 To undo a remove before that, see &quot;hg revert&quot;. To undo added
1769 files, see &quot;hg forget&quot;.
1769 files, see &quot;hg forget&quot;.
1770 </p>
1770 </p>
1771 <p>
1771 <p>
1772 -A/--after can be used to remove only files that have already
1772 -A/--after can be used to remove only files that have already
1773 been deleted, -f/--force can be used to force deletion, and -Af
1773 been deleted, -f/--force can be used to force deletion, and -Af
1774 can be used to remove files from the next revision without
1774 can be used to remove files from the next revision without
1775 deleting them from the working directory.
1775 deleting them from the working directory.
1776 </p>
1776 </p>
1777 <p>
1777 <p>
1778 The following table details the behavior of remove for different
1778 The following table details the behavior of remove for different
1779 file states (columns) and option combinations (rows). The file
1779 file states (columns) and option combinations (rows). The file
1780 states are Added [A], Clean [C], Modified [M] and Missing [!]
1780 states are Added [A], Clean [C], Modified [M] and Missing [!]
1781 (as reported by &quot;hg status&quot;). The actions are Warn, Remove
1781 (as reported by &quot;hg status&quot;). The actions are Warn, Remove
1782 (from branch) and Delete (from disk):
1782 (from branch) and Delete (from disk):
1783 </p>
1783 </p>
1784 <table>
1784 <table>
1785 <tr><td>opt/state</td>
1785 <tr><td>opt/state</td>
1786 <td>A</td>
1786 <td>A</td>
1787 <td>C</td>
1787 <td>C</td>
1788 <td>M</td>
1788 <td>M</td>
1789 <td>!</td></tr>
1789 <td>!</td></tr>
1790 <tr><td>none</td>
1790 <tr><td>none</td>
1791 <td>W</td>
1791 <td>W</td>
1792 <td>RD</td>
1792 <td>RD</td>
1793 <td>W</td>
1793 <td>W</td>
1794 <td>R</td></tr>
1794 <td>R</td></tr>
1795 <tr><td>-f</td>
1795 <tr><td>-f</td>
1796 <td>R</td>
1796 <td>R</td>
1797 <td>RD</td>
1797 <td>RD</td>
1798 <td>RD</td>
1798 <td>RD</td>
1799 <td>R</td></tr>
1799 <td>R</td></tr>
1800 <tr><td>-A</td>
1800 <tr><td>-A</td>
1801 <td>W</td>
1801 <td>W</td>
1802 <td>W</td>
1802 <td>W</td>
1803 <td>W</td>
1803 <td>W</td>
1804 <td>R</td></tr>
1804 <td>R</td></tr>
1805 <tr><td>-Af</td>
1805 <tr><td>-Af</td>
1806 <td>R</td>
1806 <td>R</td>
1807 <td>R</td>
1807 <td>R</td>
1808 <td>R</td>
1808 <td>R</td>
1809 <td>R</td></tr>
1809 <td>R</td></tr>
1810 </table>
1810 </table>
1811 <p>
1811 <p>
1812 Note that remove never deletes files in Added [A] state from the
1812 Note that remove never deletes files in Added [A] state from the
1813 working directory, not even if option --force is specified.
1813 working directory, not even if option --force is specified.
1814 </p>
1814 </p>
1815 <p>
1815 <p>
1816 Returns 0 on success, 1 if any warnings encountered.
1816 Returns 0 on success, 1 if any warnings encountered.
1817 </p>
1817 </p>
1818 <p>
1818 <p>
1819 options:
1819 options:
1820 </p>
1820 </p>
1821 <table>
1821 <table>
1822 <tr><td>-A</td>
1822 <tr><td>-A</td>
1823 <td>--after</td>
1823 <td>--after</td>
1824 <td>record delete for missing files</td></tr>
1824 <td>record delete for missing files</td></tr>
1825 <tr><td>-f</td>
1825 <tr><td>-f</td>
1826 <td>--force</td>
1826 <td>--force</td>
1827 <td>remove (and delete) file even if added or modified</td></tr>
1827 <td>remove (and delete) file even if added or modified</td></tr>
1828 <tr><td>-I</td>
1828 <tr><td>-I</td>
1829 <td>--include PATTERN [+]</td>
1829 <td>--include PATTERN [+]</td>
1830 <td>include names matching the given patterns</td></tr>
1830 <td>include names matching the given patterns</td></tr>
1831 <tr><td>-X</td>
1831 <tr><td>-X</td>
1832 <td>--exclude PATTERN [+]</td>
1832 <td>--exclude PATTERN [+]</td>
1833 <td>exclude names matching the given patterns</td></tr>
1833 <td>exclude names matching the given patterns</td></tr>
1834 </table>
1834 </table>
1835 <p>
1835 <p>
1836 [+] marked option can be specified multiple times
1836 [+] marked option can be specified multiple times
1837 </p>
1837 </p>
1838 <p>
1838 <p>
1839 global options:
1839 global options:
1840 </p>
1840 </p>
1841 <table>
1841 <table>
1842 <tr><td>-R</td>
1842 <tr><td>-R</td>
1843 <td>--repository REPO</td>
1843 <td>--repository REPO</td>
1844 <td>repository root directory or name of overlay bundle file</td></tr>
1844 <td>repository root directory or name of overlay bundle file</td></tr>
1845 <tr><td></td>
1845 <tr><td></td>
1846 <td>--cwd DIR</td>
1846 <td>--cwd DIR</td>
1847 <td>change working directory</td></tr>
1847 <td>change working directory</td></tr>
1848 <tr><td>-y</td>
1848 <tr><td>-y</td>
1849 <td>--noninteractive</td>
1849 <td>--noninteractive</td>
1850 <td>do not prompt, automatically pick the first choice for all prompts</td></tr>
1850 <td>do not prompt, automatically pick the first choice for all prompts</td></tr>
1851 <tr><td>-q</td>
1851 <tr><td>-q</td>
1852 <td>--quiet</td>
1852 <td>--quiet</td>
1853 <td>suppress output</td></tr>
1853 <td>suppress output</td></tr>
1854 <tr><td>-v</td>
1854 <tr><td>-v</td>
1855 <td>--verbose</td>
1855 <td>--verbose</td>
1856 <td>enable additional output</td></tr>
1856 <td>enable additional output</td></tr>
1857 <tr><td></td>
1857 <tr><td></td>
1858 <td>--config CONFIG [+]</td>
1858 <td>--config CONFIG [+]</td>
1859 <td>set/override config option (use 'section.name=value')</td></tr>
1859 <td>set/override config option (use 'section.name=value')</td></tr>
1860 <tr><td></td>
1860 <tr><td></td>
1861 <td>--debug</td>
1861 <td>--debug</td>
1862 <td>enable debugging output</td></tr>
1862 <td>enable debugging output</td></tr>
1863 <tr><td></td>
1863 <tr><td></td>
1864 <td>--debugger</td>
1864 <td>--debugger</td>
1865 <td>start debugger</td></tr>
1865 <td>start debugger</td></tr>
1866 <tr><td></td>
1866 <tr><td></td>
1867 <td>--encoding ENCODE</td>
1867 <td>--encoding ENCODE</td>
1868 <td>set the charset encoding (default: ascii)</td></tr>
1868 <td>set the charset encoding (default: ascii)</td></tr>
1869 <tr><td></td>
1869 <tr><td></td>
1870 <td>--encodingmode MODE</td>
1870 <td>--encodingmode MODE</td>
1871 <td>set the charset encoding mode (default: strict)</td></tr>
1871 <td>set the charset encoding mode (default: strict)</td></tr>
1872 <tr><td></td>
1872 <tr><td></td>
1873 <td>--traceback</td>
1873 <td>--traceback</td>
1874 <td>always print a traceback on exception</td></tr>
1874 <td>always print a traceback on exception</td></tr>
1875 <tr><td></td>
1875 <tr><td></td>
1876 <td>--time</td>
1876 <td>--time</td>
1877 <td>time how long the command takes</td></tr>
1877 <td>time how long the command takes</td></tr>
1878 <tr><td></td>
1878 <tr><td></td>
1879 <td>--profile</td>
1879 <td>--profile</td>
1880 <td>print command execution profile</td></tr>
1880 <td>print command execution profile</td></tr>
1881 <tr><td></td>
1881 <tr><td></td>
1882 <td>--version</td>
1882 <td>--version</td>
1883 <td>output version information and exit</td></tr>
1883 <td>output version information and exit</td></tr>
1884 <tr><td>-h</td>
1884 <tr><td>-h</td>
1885 <td>--help</td>
1885 <td>--help</td>
1886 <td>display help and exit</td></tr>
1886 <td>display help and exit</td></tr>
1887 <tr><td></td>
1887 <tr><td></td>
1888 <td>--hidden</td>
1888 <td>--hidden</td>
1889 <td>consider hidden changesets</td></tr>
1889 <td>consider hidden changesets</td></tr>
1890 </table>
1890 </table>
1891 <p>
1891 <p>
1892 [+] marked option can be specified multiple times
1892 [+] marked option can be specified multiple times
1893 </p>
1893 </p>
1894
1894
1895 </div>
1895 </div>
1896 </div>
1896 </div>
1897 </div>
1897 </div>
1898
1898
1899 <script type="text/javascript">process_dates()</script>
1899 <script type="text/javascript">process_dates()</script>
1900
1900
1901
1901
1902 </body>
1902 </body>
1903 </html>
1903 </html>
1904
1904
1905
1905
1906 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT "help/revisions"
1906 $ "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT "help/revisions"
1907 200 Script output follows
1907 200 Script output follows
1908
1908
1909 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
1909 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
1910 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
1910 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
1911 <head>
1911 <head>
1912 <link rel="icon" href="/static/hgicon.png" type="image/png" />
1912 <link rel="icon" href="/static/hgicon.png" type="image/png" />
1913 <meta name="robots" content="index, nofollow" />
1913 <meta name="robots" content="index, nofollow" />
1914 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
1914 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
1915 <script type="text/javascript" src="/static/mercurial.js"></script>
1915 <script type="text/javascript" src="/static/mercurial.js"></script>
1916
1916
1917 <title>Help: revisions</title>
1917 <title>Help: revisions</title>
1918 </head>
1918 </head>
1919 <body>
1919 <body>
1920
1920
1921 <div class="container">
1921 <div class="container">
1922 <div class="menu">
1922 <div class="menu">
1923 <div class="logo">
1923 <div class="logo">
1924 <a href="http://mercurial.selenic.com/">
1924 <a href="http://mercurial.selenic.com/">
1925 <img src="/static/hglogo.png" alt="mercurial" /></a>
1925 <img src="/static/hglogo.png" alt="mercurial" /></a>
1926 </div>
1926 </div>
1927 <ul>
1927 <ul>
1928 <li><a href="/shortlog">log</a></li>
1928 <li><a href="/shortlog">log</a></li>
1929 <li><a href="/graph">graph</a></li>
1929 <li><a href="/graph">graph</a></li>
1930 <li><a href="/tags">tags</a></li>
1930 <li><a href="/tags">tags</a></li>
1931 <li><a href="/bookmarks">bookmarks</a></li>
1931 <li><a href="/bookmarks">bookmarks</a></li>
1932 <li><a href="/branches">branches</a></li>
1932 <li><a href="/branches">branches</a></li>
1933 </ul>
1933 </ul>
1934 <ul>
1934 <ul>
1935 <li class="active"><a href="/help">help</a></li>
1935 <li class="active"><a href="/help">help</a></li>
1936 </ul>
1936 </ul>
1937 </div>
1937 </div>
1938
1938
1939 <div class="main">
1939 <div class="main">
1940 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
1940 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
1941 <h3>Help: revisions</h3>
1941 <h3>Help: revisions</h3>
1942
1942
1943 <form class="search" action="/log">
1943 <form class="search" action="/log">
1944
1944
1945 <p><input name="rev" id="search1" type="text" size="30" /></p>
1945 <p><input name="rev" id="search1" type="text" size="30" /></p>
1946 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
1946 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
1947 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
1947 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
1948 </form>
1948 </form>
1949 <div id="doc">
1949 <div id="doc">
1950 <h1>Specifying Single Revisions</h1>
1950 <h1>Specifying Single Revisions</h1>
1951 <p>
1951 <p>
1952 Mercurial supports several ways to specify individual revisions.
1952 Mercurial supports several ways to specify individual revisions.
1953 </p>
1953 </p>
1954 <p>
1954 <p>
1955 A plain integer is treated as a revision number. Negative integers are
1955 A plain integer is treated as a revision number. Negative integers are
1956 treated as sequential offsets from the tip, with -1 denoting the tip,
1956 treated as sequential offsets from the tip, with -1 denoting the tip,
1957 -2 denoting the revision prior to the tip, and so forth.
1957 -2 denoting the revision prior to the tip, and so forth.
1958 </p>
1958 </p>
1959 <p>
1959 <p>
1960 A 40-digit hexadecimal string is treated as a unique revision
1960 A 40-digit hexadecimal string is treated as a unique revision
1961 identifier.
1961 identifier.
1962 </p>
1962 </p>
1963 <p>
1963 <p>
1964 A hexadecimal string less than 40 characters long is treated as a
1964 A hexadecimal string less than 40 characters long is treated as a
1965 unique revision identifier and is referred to as a short-form
1965 unique revision identifier and is referred to as a short-form
1966 identifier. A short-form identifier is only valid if it is the prefix
1966 identifier. A short-form identifier is only valid if it is the prefix
1967 of exactly one full-length identifier.
1967 of exactly one full-length identifier.
1968 </p>
1968 </p>
1969 <p>
1969 <p>
1970 Any other string is treated as a bookmark, tag, or branch name. A
1970 Any other string is treated as a bookmark, tag, or branch name. A
1971 bookmark is a movable pointer to a revision. A tag is a permanent name
1971 bookmark is a movable pointer to a revision. A tag is a permanent name
1972 associated with a revision. A branch name denotes the tipmost open branch head
1972 associated with a revision. A branch name denotes the tipmost open branch head
1973 of that branch - or if they are all closed, the tipmost closed head of the
1973 of that branch - or if they are all closed, the tipmost closed head of the
1974 branch. Bookmark, tag, and branch names must not contain the &quot;:&quot; character.
1974 branch. Bookmark, tag, and branch names must not contain the &quot;:&quot; character.
1975 </p>
1975 </p>
1976 <p>
1976 <p>
1977 The reserved name &quot;tip&quot; always identifies the most recent revision.
1977 The reserved name &quot;tip&quot; always identifies the most recent revision.
1978 </p>
1978 </p>
1979 <p>
1979 <p>
1980 The reserved name &quot;null&quot; indicates the null revision. This is the
1980 The reserved name &quot;null&quot; indicates the null revision. This is the
1981 revision of an empty repository, and the parent of revision 0.
1981 revision of an empty repository, and the parent of revision 0.
1982 </p>
1982 </p>
1983 <p>
1983 <p>
1984 The reserved name &quot;.&quot; indicates the working directory parent. If no
1984 The reserved name &quot;.&quot; indicates the working directory parent. If no
1985 working directory is checked out, it is equivalent to null. If an
1985 working directory is checked out, it is equivalent to null. If an
1986 uncommitted merge is in progress, &quot;.&quot; is the revision of the first
1986 uncommitted merge is in progress, &quot;.&quot; is the revision of the first
1987 parent.
1987 parent.
1988 </p>
1988 </p>
1989
1989
1990 </div>
1990 </div>
1991 </div>
1991 </div>
1992 </div>
1992 </div>
1993
1993
1994 <script type="text/javascript">process_dates()</script>
1994 <script type="text/javascript">process_dates()</script>
1995
1995
1996
1996
1997 </body>
1997 </body>
1998 </html>
1998 </html>
1999
1999
2000
2000
2001 $ "$TESTDIR/killdaemons.py" $DAEMON_PIDS
2001 $ "$TESTDIR/killdaemons.py" $DAEMON_PIDS
2002
2002
2003 #endif
2003 #endif
General Comments 0
You need to be logged in to leave comments. Login now