##// END OF EJS Templates
config: add --global and --local flags...
Matt Mackall -
r20782:13fcb9ca default
parent child Browse files
Show More
@@ -1,5886 +1,5899 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 sys
12 import sys
13 import hg, scmutil, util, revlog, copies, error, bookmarks
13 import hg, scmutil, util, revlog, copies, error, bookmarks
14 import patch, help, encoding, templatekw, discovery
14 import patch, help, encoding, templatekw, discovery
15 import archival, changegroup, cmdutil, hbisect
15 import archival, changegroup, cmdutil, hbisect
16 import sshserver, hgweb, commandserver
16 import sshserver, hgweb, commandserver
17 from hgweb import server as hgweb_server
17 from hgweb import server as hgweb_server
18 import merge as mergemod
18 import merge as mergemod
19 import minirst, revset, fileset
19 import minirst, revset, fileset
20 import dagparser, context, simplemerge, graphmod
20 import dagparser, context, simplemerge, graphmod
21 import random
21 import random
22 import setdiscovery, treediscovery, dagutil, pvec, localrepo
22 import setdiscovery, treediscovery, dagutil, pvec, localrepo
23 import phases, obsolete
23 import phases, obsolete
24
24
25 table = {}
25 table = {}
26
26
27 command = cmdutil.command(table)
27 command = cmdutil.command(table)
28
28
29 # common command options
29 # common command options
30
30
31 globalopts = [
31 globalopts = [
32 ('R', 'repository', '',
32 ('R', 'repository', '',
33 _('repository root directory or name of overlay bundle file'),
33 _('repository root directory or name of overlay bundle file'),
34 _('REPO')),
34 _('REPO')),
35 ('', 'cwd', '',
35 ('', 'cwd', '',
36 _('change working directory'), _('DIR')),
36 _('change working directory'), _('DIR')),
37 ('y', 'noninteractive', None,
37 ('y', 'noninteractive', None,
38 _('do not prompt, automatically pick the first choice for all prompts')),
38 _('do not prompt, automatically pick the first choice for all prompts')),
39 ('q', 'quiet', None, _('suppress output')),
39 ('q', 'quiet', None, _('suppress output')),
40 ('v', 'verbose', None, _('enable additional output')),
40 ('v', 'verbose', None, _('enable additional output')),
41 ('', 'config', [],
41 ('', 'config', [],
42 _('set/override config option (use \'section.name=value\')'),
42 _('set/override config option (use \'section.name=value\')'),
43 _('CONFIG')),
43 _('CONFIG')),
44 ('', 'debug', None, _('enable debugging output')),
44 ('', 'debug', None, _('enable debugging output')),
45 ('', 'debugger', None, _('start debugger')),
45 ('', 'debugger', None, _('start debugger')),
46 ('', 'encoding', encoding.encoding, _('set the charset encoding'),
46 ('', 'encoding', encoding.encoding, _('set the charset encoding'),
47 _('ENCODE')),
47 _('ENCODE')),
48 ('', 'encodingmode', encoding.encodingmode,
48 ('', 'encodingmode', encoding.encodingmode,
49 _('set the charset encoding mode'), _('MODE')),
49 _('set the charset encoding mode'), _('MODE')),
50 ('', 'traceback', None, _('always print a traceback on exception')),
50 ('', 'traceback', None, _('always print a traceback on exception')),
51 ('', 'time', None, _('time how long the command takes')),
51 ('', 'time', None, _('time how long the command takes')),
52 ('', 'profile', None, _('print command execution profile')),
52 ('', 'profile', None, _('print command execution profile')),
53 ('', 'version', None, _('output version information and exit')),
53 ('', 'version', None, _('output version information and exit')),
54 ('h', 'help', None, _('display help and exit')),
54 ('h', 'help', None, _('display help and exit')),
55 ('', 'hidden', False, _('consider hidden changesets')),
55 ('', 'hidden', False, _('consider hidden changesets')),
56 ]
56 ]
57
57
58 dryrunopts = [('n', 'dry-run', None,
58 dryrunopts = [('n', 'dry-run', None,
59 _('do not perform actions, just print output'))]
59 _('do not perform actions, just print output'))]
60
60
61 remoteopts = [
61 remoteopts = [
62 ('e', 'ssh', '',
62 ('e', 'ssh', '',
63 _('specify ssh command to use'), _('CMD')),
63 _('specify ssh command to use'), _('CMD')),
64 ('', 'remotecmd', '',
64 ('', 'remotecmd', '',
65 _('specify hg command to run on the remote side'), _('CMD')),
65 _('specify hg command to run on the remote side'), _('CMD')),
66 ('', 'insecure', None,
66 ('', 'insecure', None,
67 _('do not verify server certificate (ignoring web.cacerts config)')),
67 _('do not verify server certificate (ignoring web.cacerts config)')),
68 ]
68 ]
69
69
70 walkopts = [
70 walkopts = [
71 ('I', 'include', [],
71 ('I', 'include', [],
72 _('include names matching the given patterns'), _('PATTERN')),
72 _('include names matching the given patterns'), _('PATTERN')),
73 ('X', 'exclude', [],
73 ('X', 'exclude', [],
74 _('exclude names matching the given patterns'), _('PATTERN')),
74 _('exclude names matching the given patterns'), _('PATTERN')),
75 ]
75 ]
76
76
77 commitopts = [
77 commitopts = [
78 ('m', 'message', '',
78 ('m', 'message', '',
79 _('use text as commit message'), _('TEXT')),
79 _('use text as commit message'), _('TEXT')),
80 ('l', 'logfile', '',
80 ('l', 'logfile', '',
81 _('read commit message from file'), _('FILE')),
81 _('read commit message from file'), _('FILE')),
82 ]
82 ]
83
83
84 commitopts2 = [
84 commitopts2 = [
85 ('d', 'date', '',
85 ('d', 'date', '',
86 _('record the specified date as commit date'), _('DATE')),
86 _('record the specified date as commit date'), _('DATE')),
87 ('u', 'user', '',
87 ('u', 'user', '',
88 _('record the specified user as committer'), _('USER')),
88 _('record the specified user as committer'), _('USER')),
89 ]
89 ]
90
90
91 templateopts = [
91 templateopts = [
92 ('', 'style', '',
92 ('', 'style', '',
93 _('display using template map file (DEPRECATED)'), _('STYLE')),
93 _('display using template map file (DEPRECATED)'), _('STYLE')),
94 ('T', 'template', '',
94 ('T', 'template', '',
95 _('display with template'), _('TEMPLATE')),
95 _('display with template'), _('TEMPLATE')),
96 ]
96 ]
97
97
98 logopts = [
98 logopts = [
99 ('p', 'patch', None, _('show patch')),
99 ('p', 'patch', None, _('show patch')),
100 ('g', 'git', None, _('use git extended diff format')),
100 ('g', 'git', None, _('use git extended diff format')),
101 ('l', 'limit', '',
101 ('l', 'limit', '',
102 _('limit number of changes displayed'), _('NUM')),
102 _('limit number of changes displayed'), _('NUM')),
103 ('M', 'no-merges', None, _('do not show merges')),
103 ('M', 'no-merges', None, _('do not show merges')),
104 ('', 'stat', None, _('output diffstat-style summary of changes')),
104 ('', 'stat', None, _('output diffstat-style summary of changes')),
105 ('G', 'graph', None, _("show the revision DAG")),
105 ('G', 'graph', None, _("show the revision DAG")),
106 ] + templateopts
106 ] + templateopts
107
107
108 diffopts = [
108 diffopts = [
109 ('a', 'text', None, _('treat all files as text')),
109 ('a', 'text', None, _('treat all files as text')),
110 ('g', 'git', None, _('use git extended diff format')),
110 ('g', 'git', None, _('use git extended diff format')),
111 ('', 'nodates', None, _('omit dates from diff headers'))
111 ('', 'nodates', None, _('omit dates from diff headers'))
112 ]
112 ]
113
113
114 diffwsopts = [
114 diffwsopts = [
115 ('w', 'ignore-all-space', None,
115 ('w', 'ignore-all-space', None,
116 _('ignore white space when comparing lines')),
116 _('ignore white space when comparing lines')),
117 ('b', 'ignore-space-change', None,
117 ('b', 'ignore-space-change', None,
118 _('ignore changes in the amount of white space')),
118 _('ignore changes in the amount of white space')),
119 ('B', 'ignore-blank-lines', None,
119 ('B', 'ignore-blank-lines', None,
120 _('ignore changes whose lines are all blank')),
120 _('ignore changes whose lines are all blank')),
121 ]
121 ]
122
122
123 diffopts2 = [
123 diffopts2 = [
124 ('p', 'show-function', None, _('show which function each change is in')),
124 ('p', 'show-function', None, _('show which function each change is in')),
125 ('', 'reverse', None, _('produce a diff that undoes the changes')),
125 ('', 'reverse', None, _('produce a diff that undoes the changes')),
126 ] + diffwsopts + [
126 ] + diffwsopts + [
127 ('U', 'unified', '',
127 ('U', 'unified', '',
128 _('number of lines of context to show'), _('NUM')),
128 _('number of lines of context to show'), _('NUM')),
129 ('', 'stat', None, _('output diffstat-style summary of changes')),
129 ('', 'stat', None, _('output diffstat-style summary of changes')),
130 ]
130 ]
131
131
132 mergetoolopts = [
132 mergetoolopts = [
133 ('t', 'tool', '', _('specify merge tool')),
133 ('t', 'tool', '', _('specify merge tool')),
134 ]
134 ]
135
135
136 similarityopts = [
136 similarityopts = [
137 ('s', 'similarity', '',
137 ('s', 'similarity', '',
138 _('guess renamed files by similarity (0<=s<=100)'), _('SIMILARITY'))
138 _('guess renamed files by similarity (0<=s<=100)'), _('SIMILARITY'))
139 ]
139 ]
140
140
141 subrepoopts = [
141 subrepoopts = [
142 ('S', 'subrepos', None,
142 ('S', 'subrepos', None,
143 _('recurse into subrepositories'))
143 _('recurse into subrepositories'))
144 ]
144 ]
145
145
146 # Commands start here, listed alphabetically
146 # Commands start here, listed alphabetically
147
147
148 @command('^add',
148 @command('^add',
149 walkopts + subrepoopts + dryrunopts,
149 walkopts + subrepoopts + dryrunopts,
150 _('[OPTION]... [FILE]...'))
150 _('[OPTION]... [FILE]...'))
151 def add(ui, repo, *pats, **opts):
151 def add(ui, repo, *pats, **opts):
152 """add the specified files on the next commit
152 """add the specified files on the next commit
153
153
154 Schedule files to be version controlled and added to the
154 Schedule files to be version controlled and added to the
155 repository.
155 repository.
156
156
157 The files will be added to the repository at the next commit. To
157 The files will be added to the repository at the next commit. To
158 undo an add before that, see :hg:`forget`.
158 undo an add before that, see :hg:`forget`.
159
159
160 If no names are given, add all files to the repository.
160 If no names are given, add all files to the repository.
161
161
162 .. container:: verbose
162 .. container:: verbose
163
163
164 An example showing how new (unknown) files are added
164 An example showing how new (unknown) files are added
165 automatically by :hg:`add`::
165 automatically by :hg:`add`::
166
166
167 $ ls
167 $ ls
168 foo.c
168 foo.c
169 $ hg status
169 $ hg status
170 ? foo.c
170 ? foo.c
171 $ hg add
171 $ hg add
172 adding foo.c
172 adding foo.c
173 $ hg status
173 $ hg status
174 A foo.c
174 A foo.c
175
175
176 Returns 0 if all files are successfully added.
176 Returns 0 if all files are successfully added.
177 """
177 """
178
178
179 m = scmutil.match(repo[None], pats, opts)
179 m = scmutil.match(repo[None], pats, opts)
180 rejected = cmdutil.add(ui, repo, m, opts.get('dry_run'),
180 rejected = cmdutil.add(ui, repo, m, opts.get('dry_run'),
181 opts.get('subrepos'), prefix="", explicitonly=False)
181 opts.get('subrepos'), prefix="", explicitonly=False)
182 return rejected and 1 or 0
182 return rejected and 1 or 0
183
183
184 @command('addremove',
184 @command('addremove',
185 similarityopts + walkopts + dryrunopts,
185 similarityopts + walkopts + dryrunopts,
186 _('[OPTION]... [FILE]...'))
186 _('[OPTION]... [FILE]...'))
187 def addremove(ui, repo, *pats, **opts):
187 def addremove(ui, repo, *pats, **opts):
188 """add all new files, delete all missing files
188 """add all new files, delete all missing files
189
189
190 Add all new files and remove all missing files from the
190 Add all new files and remove all missing files from the
191 repository.
191 repository.
192
192
193 New files are ignored if they match any of the patterns in
193 New files are ignored if they match any of the patterns in
194 ``.hgignore``. As with add, these changes take effect at the next
194 ``.hgignore``. As with add, these changes take effect at the next
195 commit.
195 commit.
196
196
197 Use the -s/--similarity option to detect renamed files. This
197 Use the -s/--similarity option to detect renamed files. This
198 option takes a percentage between 0 (disabled) and 100 (files must
198 option takes a percentage between 0 (disabled) and 100 (files must
199 be identical) as its parameter. With a parameter greater than 0,
199 be identical) as its parameter. With a parameter greater than 0,
200 this compares every removed file with every added file and records
200 this compares every removed file with every added file and records
201 those similar enough as renames. Detecting renamed files this way
201 those similar enough as renames. Detecting renamed files this way
202 can be expensive. After using this option, :hg:`status -C` can be
202 can be expensive. After using this option, :hg:`status -C` can be
203 used to check which files were identified as moved or renamed. If
203 used to check which files were identified as moved or renamed. If
204 not specified, -s/--similarity defaults to 100 and only renames of
204 not specified, -s/--similarity defaults to 100 and only renames of
205 identical files are detected.
205 identical files are detected.
206
206
207 Returns 0 if all files are successfully added.
207 Returns 0 if all files are successfully added.
208 """
208 """
209 try:
209 try:
210 sim = float(opts.get('similarity') or 100)
210 sim = float(opts.get('similarity') or 100)
211 except ValueError:
211 except ValueError:
212 raise util.Abort(_('similarity must be a number'))
212 raise util.Abort(_('similarity must be a number'))
213 if sim < 0 or sim > 100:
213 if sim < 0 or sim > 100:
214 raise util.Abort(_('similarity must be between 0 and 100'))
214 raise util.Abort(_('similarity must be between 0 and 100'))
215 return scmutil.addremove(repo, pats, opts, similarity=sim / 100.0)
215 return scmutil.addremove(repo, pats, opts, similarity=sim / 100.0)
216
216
217 @command('^annotate|blame',
217 @command('^annotate|blame',
218 [('r', 'rev', '', _('annotate the specified revision'), _('REV')),
218 [('r', 'rev', '', _('annotate the specified revision'), _('REV')),
219 ('', 'follow', None,
219 ('', 'follow', None,
220 _('follow copies/renames and list the filename (DEPRECATED)')),
220 _('follow copies/renames and list the filename (DEPRECATED)')),
221 ('', 'no-follow', None, _("don't follow copies and renames")),
221 ('', 'no-follow', None, _("don't follow copies and renames")),
222 ('a', 'text', None, _('treat all files as text')),
222 ('a', 'text', None, _('treat all files as text')),
223 ('u', 'user', None, _('list the author (long with -v)')),
223 ('u', 'user', None, _('list the author (long with -v)')),
224 ('f', 'file', None, _('list the filename')),
224 ('f', 'file', None, _('list the filename')),
225 ('d', 'date', None, _('list the date (short with -q)')),
225 ('d', 'date', None, _('list the date (short with -q)')),
226 ('n', 'number', None, _('list the revision number (default)')),
226 ('n', 'number', None, _('list the revision number (default)')),
227 ('c', 'changeset', None, _('list the changeset')),
227 ('c', 'changeset', None, _('list the changeset')),
228 ('l', 'line-number', None, _('show line number at the first appearance'))
228 ('l', 'line-number', None, _('show line number at the first appearance'))
229 ] + diffwsopts + walkopts,
229 ] + diffwsopts + walkopts,
230 _('[-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE...'))
230 _('[-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE...'))
231 def annotate(ui, repo, *pats, **opts):
231 def annotate(ui, repo, *pats, **opts):
232 """show changeset information by line for each file
232 """show changeset information by line for each file
233
233
234 List changes in files, showing the revision id responsible for
234 List changes in files, showing the revision id responsible for
235 each line
235 each line
236
236
237 This command is useful for discovering when a change was made and
237 This command is useful for discovering when a change was made and
238 by whom.
238 by whom.
239
239
240 Without the -a/--text option, annotate will avoid processing files
240 Without the -a/--text option, annotate will avoid processing files
241 it detects as binary. With -a, annotate will annotate the file
241 it detects as binary. With -a, annotate will annotate the file
242 anyway, although the results will probably be neither useful
242 anyway, although the results will probably be neither useful
243 nor desirable.
243 nor desirable.
244
244
245 Returns 0 on success.
245 Returns 0 on success.
246 """
246 """
247 if opts.get('follow'):
247 if opts.get('follow'):
248 # --follow is deprecated and now just an alias for -f/--file
248 # --follow is deprecated and now just an alias for -f/--file
249 # to mimic the behavior of Mercurial before version 1.5
249 # to mimic the behavior of Mercurial before version 1.5
250 opts['file'] = True
250 opts['file'] = True
251
251
252 datefunc = ui.quiet and util.shortdate or util.datestr
252 datefunc = ui.quiet and util.shortdate or util.datestr
253 getdate = util.cachefunc(lambda x: datefunc(x[0].date()))
253 getdate = util.cachefunc(lambda x: datefunc(x[0].date()))
254
254
255 if not pats:
255 if not pats:
256 raise util.Abort(_('at least one filename or pattern is required'))
256 raise util.Abort(_('at least one filename or pattern is required'))
257
257
258 hexfn = ui.debugflag and hex or short
258 hexfn = ui.debugflag and hex or short
259
259
260 opmap = [('user', ' ', lambda x: ui.shortuser(x[0].user())),
260 opmap = [('user', ' ', lambda x: ui.shortuser(x[0].user())),
261 ('number', ' ', lambda x: str(x[0].rev())),
261 ('number', ' ', lambda x: str(x[0].rev())),
262 ('changeset', ' ', lambda x: hexfn(x[0].node())),
262 ('changeset', ' ', lambda x: hexfn(x[0].node())),
263 ('date', ' ', getdate),
263 ('date', ' ', getdate),
264 ('file', ' ', lambda x: x[0].path()),
264 ('file', ' ', lambda x: x[0].path()),
265 ('line_number', ':', lambda x: str(x[1])),
265 ('line_number', ':', lambda x: str(x[1])),
266 ]
266 ]
267
267
268 if (not opts.get('user') and not opts.get('changeset')
268 if (not opts.get('user') and not opts.get('changeset')
269 and not opts.get('date') and not opts.get('file')):
269 and not opts.get('date') and not opts.get('file')):
270 opts['number'] = True
270 opts['number'] = True
271
271
272 linenumber = opts.get('line_number') is not None
272 linenumber = opts.get('line_number') is not None
273 if linenumber and (not opts.get('changeset')) and (not opts.get('number')):
273 if linenumber and (not opts.get('changeset')) and (not opts.get('number')):
274 raise util.Abort(_('at least one of -n/-c is required for -l'))
274 raise util.Abort(_('at least one of -n/-c is required for -l'))
275
275
276 funcmap = [(func, sep) for op, sep, func in opmap if opts.get(op)]
276 funcmap = [(func, sep) for op, sep, func in opmap if opts.get(op)]
277 funcmap[0] = (funcmap[0][0], '') # no separator in front of first column
277 funcmap[0] = (funcmap[0][0], '') # no separator in front of first column
278
278
279 def bad(x, y):
279 def bad(x, y):
280 raise util.Abort("%s: %s" % (x, y))
280 raise util.Abort("%s: %s" % (x, y))
281
281
282 ctx = scmutil.revsingle(repo, opts.get('rev'))
282 ctx = scmutil.revsingle(repo, opts.get('rev'))
283 m = scmutil.match(ctx, pats, opts)
283 m = scmutil.match(ctx, pats, opts)
284 m.bad = bad
284 m.bad = bad
285 follow = not opts.get('no_follow')
285 follow = not opts.get('no_follow')
286 diffopts = patch.diffopts(ui, opts, section='annotate')
286 diffopts = patch.diffopts(ui, opts, section='annotate')
287 for abs in ctx.walk(m):
287 for abs in ctx.walk(m):
288 fctx = ctx[abs]
288 fctx = ctx[abs]
289 if not opts.get('text') and util.binary(fctx.data()):
289 if not opts.get('text') and util.binary(fctx.data()):
290 ui.write(_("%s: binary file\n") % ((pats and m.rel(abs)) or abs))
290 ui.write(_("%s: binary file\n") % ((pats and m.rel(abs)) or abs))
291 continue
291 continue
292
292
293 lines = fctx.annotate(follow=follow, linenumber=linenumber,
293 lines = fctx.annotate(follow=follow, linenumber=linenumber,
294 diffopts=diffopts)
294 diffopts=diffopts)
295 pieces = []
295 pieces = []
296
296
297 for f, sep in funcmap:
297 for f, sep in funcmap:
298 l = [f(n) for n, dummy in lines]
298 l = [f(n) for n, dummy in lines]
299 if l:
299 if l:
300 sized = [(x, encoding.colwidth(x)) for x in l]
300 sized = [(x, encoding.colwidth(x)) for x in l]
301 ml = max([w for x, w in sized])
301 ml = max([w for x, w in sized])
302 pieces.append(["%s%s%s" % (sep, ' ' * (ml - w), x)
302 pieces.append(["%s%s%s" % (sep, ' ' * (ml - w), x)
303 for x, w in sized])
303 for x, w in sized])
304
304
305 if pieces:
305 if pieces:
306 for p, l in zip(zip(*pieces), lines):
306 for p, l in zip(zip(*pieces), lines):
307 ui.write("%s: %s" % ("".join(p), l[1]))
307 ui.write("%s: %s" % ("".join(p), l[1]))
308
308
309 if lines and not lines[-1][1].endswith('\n'):
309 if lines and not lines[-1][1].endswith('\n'):
310 ui.write('\n')
310 ui.write('\n')
311
311
312 @command('archive',
312 @command('archive',
313 [('', 'no-decode', None, _('do not pass files through decoders')),
313 [('', 'no-decode', None, _('do not pass files through decoders')),
314 ('p', 'prefix', '', _('directory prefix for files in archive'),
314 ('p', 'prefix', '', _('directory prefix for files in archive'),
315 _('PREFIX')),
315 _('PREFIX')),
316 ('r', 'rev', '', _('revision to distribute'), _('REV')),
316 ('r', 'rev', '', _('revision to distribute'), _('REV')),
317 ('t', 'type', '', _('type of distribution to create'), _('TYPE')),
317 ('t', 'type', '', _('type of distribution to create'), _('TYPE')),
318 ] + subrepoopts + walkopts,
318 ] + subrepoopts + walkopts,
319 _('[OPTION]... DEST'))
319 _('[OPTION]... DEST'))
320 def archive(ui, repo, dest, **opts):
320 def archive(ui, repo, dest, **opts):
321 '''create an unversioned archive of a repository revision
321 '''create an unversioned archive of a repository revision
322
322
323 By default, the revision used is the parent of the working
323 By default, the revision used is the parent of the working
324 directory; use -r/--rev to specify a different revision.
324 directory; use -r/--rev to specify a different revision.
325
325
326 The archive type is automatically detected based on file
326 The archive type is automatically detected based on file
327 extension (or override using -t/--type).
327 extension (or override using -t/--type).
328
328
329 .. container:: verbose
329 .. container:: verbose
330
330
331 Examples:
331 Examples:
332
332
333 - create a zip file containing the 1.0 release::
333 - create a zip file containing the 1.0 release::
334
334
335 hg archive -r 1.0 project-1.0.zip
335 hg archive -r 1.0 project-1.0.zip
336
336
337 - create a tarball excluding .hg files::
337 - create a tarball excluding .hg files::
338
338
339 hg archive project.tar.gz -X ".hg*"
339 hg archive project.tar.gz -X ".hg*"
340
340
341 Valid types are:
341 Valid types are:
342
342
343 :``files``: a directory full of files (default)
343 :``files``: a directory full of files (default)
344 :``tar``: tar archive, uncompressed
344 :``tar``: tar archive, uncompressed
345 :``tbz2``: tar archive, compressed using bzip2
345 :``tbz2``: tar archive, compressed using bzip2
346 :``tgz``: tar archive, compressed using gzip
346 :``tgz``: tar archive, compressed using gzip
347 :``uzip``: zip archive, uncompressed
347 :``uzip``: zip archive, uncompressed
348 :``zip``: zip archive, compressed using deflate
348 :``zip``: zip archive, compressed using deflate
349
349
350 The exact name of the destination archive or directory is given
350 The exact name of the destination archive or directory is given
351 using a format string; see :hg:`help export` for details.
351 using a format string; see :hg:`help export` for details.
352
352
353 Each member added to an archive file has a directory prefix
353 Each member added to an archive file has a directory prefix
354 prepended. Use -p/--prefix to specify a format string for the
354 prepended. Use -p/--prefix to specify a format string for the
355 prefix. The default is the basename of the archive, with suffixes
355 prefix. The default is the basename of the archive, with suffixes
356 removed.
356 removed.
357
357
358 Returns 0 on success.
358 Returns 0 on success.
359 '''
359 '''
360
360
361 ctx = scmutil.revsingle(repo, opts.get('rev'))
361 ctx = scmutil.revsingle(repo, opts.get('rev'))
362 if not ctx:
362 if not ctx:
363 raise util.Abort(_('no working directory: please specify a revision'))
363 raise util.Abort(_('no working directory: please specify a revision'))
364 node = ctx.node()
364 node = ctx.node()
365 dest = cmdutil.makefilename(repo, dest, node)
365 dest = cmdutil.makefilename(repo, dest, node)
366 if os.path.realpath(dest) == repo.root:
366 if os.path.realpath(dest) == repo.root:
367 raise util.Abort(_('repository root cannot be destination'))
367 raise util.Abort(_('repository root cannot be destination'))
368
368
369 kind = opts.get('type') or archival.guesskind(dest) or 'files'
369 kind = opts.get('type') or archival.guesskind(dest) or 'files'
370 prefix = opts.get('prefix')
370 prefix = opts.get('prefix')
371
371
372 if dest == '-':
372 if dest == '-':
373 if kind == 'files':
373 if kind == 'files':
374 raise util.Abort(_('cannot archive plain files to stdout'))
374 raise util.Abort(_('cannot archive plain files to stdout'))
375 dest = cmdutil.makefileobj(repo, dest)
375 dest = cmdutil.makefileobj(repo, dest)
376 if not prefix:
376 if not prefix:
377 prefix = os.path.basename(repo.root) + '-%h'
377 prefix = os.path.basename(repo.root) + '-%h'
378
378
379 prefix = cmdutil.makefilename(repo, prefix, node)
379 prefix = cmdutil.makefilename(repo, prefix, node)
380 matchfn = scmutil.match(ctx, [], opts)
380 matchfn = scmutil.match(ctx, [], opts)
381 archival.archive(repo, dest, node, kind, not opts.get('no_decode'),
381 archival.archive(repo, dest, node, kind, not opts.get('no_decode'),
382 matchfn, prefix, subrepos=opts.get('subrepos'))
382 matchfn, prefix, subrepos=opts.get('subrepos'))
383
383
384 @command('backout',
384 @command('backout',
385 [('', 'merge', None, _('merge with old dirstate parent after backout')),
385 [('', 'merge', None, _('merge with old dirstate parent after backout')),
386 ('', 'parent', '',
386 ('', 'parent', '',
387 _('parent to choose when backing out merge (DEPRECATED)'), _('REV')),
387 _('parent to choose when backing out merge (DEPRECATED)'), _('REV')),
388 ('r', 'rev', '', _('revision to backout'), _('REV')),
388 ('r', 'rev', '', _('revision to backout'), _('REV')),
389 ] + mergetoolopts + walkopts + commitopts + commitopts2,
389 ] + mergetoolopts + walkopts + commitopts + commitopts2,
390 _('[OPTION]... [-r] REV'))
390 _('[OPTION]... [-r] REV'))
391 def backout(ui, repo, node=None, rev=None, **opts):
391 def backout(ui, repo, node=None, rev=None, **opts):
392 '''reverse effect of earlier changeset
392 '''reverse effect of earlier changeset
393
393
394 Prepare a new changeset with the effect of REV undone in the
394 Prepare a new changeset with the effect of REV undone in the
395 current working directory.
395 current working directory.
396
396
397 If REV is the parent of the working directory, then this new changeset
397 If REV is the parent of the working directory, then this new changeset
398 is committed automatically. Otherwise, hg needs to merge the
398 is committed automatically. Otherwise, hg needs to merge the
399 changes and the merged result is left uncommitted.
399 changes and the merged result is left uncommitted.
400
400
401 .. note::
401 .. note::
402
402
403 backout cannot be used to fix either an unwanted or
403 backout cannot be used to fix either an unwanted or
404 incorrect merge.
404 incorrect merge.
405
405
406 .. container:: verbose
406 .. container:: verbose
407
407
408 By default, the pending changeset will have one parent,
408 By default, the pending changeset will have one parent,
409 maintaining a linear history. With --merge, the pending
409 maintaining a linear history. With --merge, the pending
410 changeset will instead have two parents: the old parent of the
410 changeset will instead have two parents: the old parent of the
411 working directory and a new child of REV that simply undoes REV.
411 working directory and a new child of REV that simply undoes REV.
412
412
413 Before version 1.7, the behavior without --merge was equivalent
413 Before version 1.7, the behavior without --merge was equivalent
414 to specifying --merge followed by :hg:`update --clean .` to
414 to specifying --merge followed by :hg:`update --clean .` to
415 cancel the merge and leave the child of REV as a head to be
415 cancel the merge and leave the child of REV as a head to be
416 merged separately.
416 merged separately.
417
417
418 See :hg:`help dates` for a list of formats valid for -d/--date.
418 See :hg:`help dates` for a list of formats valid for -d/--date.
419
419
420 Returns 0 on success.
420 Returns 0 on success.
421 '''
421 '''
422 if rev and node:
422 if rev and node:
423 raise util.Abort(_("please specify just one revision"))
423 raise util.Abort(_("please specify just one revision"))
424
424
425 if not rev:
425 if not rev:
426 rev = node
426 rev = node
427
427
428 if not rev:
428 if not rev:
429 raise util.Abort(_("please specify a revision to backout"))
429 raise util.Abort(_("please specify a revision to backout"))
430
430
431 date = opts.get('date')
431 date = opts.get('date')
432 if date:
432 if date:
433 opts['date'] = util.parsedate(date)
433 opts['date'] = util.parsedate(date)
434
434
435 cmdutil.checkunfinished(repo)
435 cmdutil.checkunfinished(repo)
436 cmdutil.bailifchanged(repo)
436 cmdutil.bailifchanged(repo)
437 node = scmutil.revsingle(repo, rev).node()
437 node = scmutil.revsingle(repo, rev).node()
438
438
439 op1, op2 = repo.dirstate.parents()
439 op1, op2 = repo.dirstate.parents()
440 a = repo.changelog.ancestor(op1, node)
440 a = repo.changelog.ancestor(op1, node)
441 if a != node:
441 if a != node:
442 raise util.Abort(_('cannot backout change on a different branch'))
442 raise util.Abort(_('cannot backout change on a different branch'))
443
443
444 p1, p2 = repo.changelog.parents(node)
444 p1, p2 = repo.changelog.parents(node)
445 if p1 == nullid:
445 if p1 == nullid:
446 raise util.Abort(_('cannot backout a change with no parents'))
446 raise util.Abort(_('cannot backout a change with no parents'))
447 if p2 != nullid:
447 if p2 != nullid:
448 if not opts.get('parent'):
448 if not opts.get('parent'):
449 raise util.Abort(_('cannot backout a merge changeset'))
449 raise util.Abort(_('cannot backout a merge changeset'))
450 p = repo.lookup(opts['parent'])
450 p = repo.lookup(opts['parent'])
451 if p not in (p1, p2):
451 if p not in (p1, p2):
452 raise util.Abort(_('%s is not a parent of %s') %
452 raise util.Abort(_('%s is not a parent of %s') %
453 (short(p), short(node)))
453 (short(p), short(node)))
454 parent = p
454 parent = p
455 else:
455 else:
456 if opts.get('parent'):
456 if opts.get('parent'):
457 raise util.Abort(_('cannot use --parent on non-merge changeset'))
457 raise util.Abort(_('cannot use --parent on non-merge changeset'))
458 parent = p1
458 parent = p1
459
459
460 # the backout should appear on the same branch
460 # the backout should appear on the same branch
461 wlock = repo.wlock()
461 wlock = repo.wlock()
462 try:
462 try:
463 branch = repo.dirstate.branch()
463 branch = repo.dirstate.branch()
464 bheads = repo.branchheads(branch)
464 bheads = repo.branchheads(branch)
465 rctx = scmutil.revsingle(repo, hex(parent))
465 rctx = scmutil.revsingle(repo, hex(parent))
466 if not opts.get('merge') and op1 != node:
466 if not opts.get('merge') and op1 != node:
467 try:
467 try:
468 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
468 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
469 stats = mergemod.update(repo, parent, True, True, False,
469 stats = mergemod.update(repo, parent, True, True, False,
470 node, False)
470 node, False)
471 repo.setparents(op1, op2)
471 repo.setparents(op1, op2)
472 hg._showstats(repo, stats)
472 hg._showstats(repo, stats)
473 if stats[3]:
473 if stats[3]:
474 repo.ui.status(_("use 'hg resolve' to retry unresolved "
474 repo.ui.status(_("use 'hg resolve' to retry unresolved "
475 "file merges\n"))
475 "file merges\n"))
476 else:
476 else:
477 msg = _("changeset %s backed out, "
477 msg = _("changeset %s backed out, "
478 "don't forget to commit.\n")
478 "don't forget to commit.\n")
479 ui.status(msg % short(node))
479 ui.status(msg % short(node))
480 return stats[3] > 0
480 return stats[3] > 0
481 finally:
481 finally:
482 ui.setconfig('ui', 'forcemerge', '')
482 ui.setconfig('ui', 'forcemerge', '')
483 else:
483 else:
484 hg.clean(repo, node, show_stats=False)
484 hg.clean(repo, node, show_stats=False)
485 repo.dirstate.setbranch(branch)
485 repo.dirstate.setbranch(branch)
486 cmdutil.revert(ui, repo, rctx, repo.dirstate.parents())
486 cmdutil.revert(ui, repo, rctx, repo.dirstate.parents())
487
487
488
488
489 e = cmdutil.commiteditor
489 e = cmdutil.commiteditor
490 if not opts['message'] and not opts['logfile']:
490 if not opts['message'] and not opts['logfile']:
491 # we don't translate commit messages
491 # we don't translate commit messages
492 opts['message'] = "Backed out changeset %s" % short(node)
492 opts['message'] = "Backed out changeset %s" % short(node)
493 e = cmdutil.commitforceeditor
493 e = cmdutil.commitforceeditor
494
494
495 def commitfunc(ui, repo, message, match, opts):
495 def commitfunc(ui, repo, message, match, opts):
496 return repo.commit(message, opts.get('user'), opts.get('date'),
496 return repo.commit(message, opts.get('user'), opts.get('date'),
497 match, editor=e)
497 match, editor=e)
498 newnode = cmdutil.commit(ui, repo, commitfunc, [], opts)
498 newnode = cmdutil.commit(ui, repo, commitfunc, [], opts)
499 cmdutil.commitstatus(repo, newnode, branch, bheads)
499 cmdutil.commitstatus(repo, newnode, branch, bheads)
500
500
501 def nice(node):
501 def nice(node):
502 return '%d:%s' % (repo.changelog.rev(node), short(node))
502 return '%d:%s' % (repo.changelog.rev(node), short(node))
503 ui.status(_('changeset %s backs out changeset %s\n') %
503 ui.status(_('changeset %s backs out changeset %s\n') %
504 (nice(repo.changelog.tip()), nice(node)))
504 (nice(repo.changelog.tip()), nice(node)))
505 if opts.get('merge') and op1 != node:
505 if opts.get('merge') and op1 != node:
506 hg.clean(repo, op1, show_stats=False)
506 hg.clean(repo, op1, show_stats=False)
507 ui.status(_('merging with changeset %s\n')
507 ui.status(_('merging with changeset %s\n')
508 % nice(repo.changelog.tip()))
508 % nice(repo.changelog.tip()))
509 try:
509 try:
510 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
510 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
511 return hg.merge(repo, hex(repo.changelog.tip()))
511 return hg.merge(repo, hex(repo.changelog.tip()))
512 finally:
512 finally:
513 ui.setconfig('ui', 'forcemerge', '')
513 ui.setconfig('ui', 'forcemerge', '')
514 finally:
514 finally:
515 wlock.release()
515 wlock.release()
516 return 0
516 return 0
517
517
518 @command('bisect',
518 @command('bisect',
519 [('r', 'reset', False, _('reset bisect state')),
519 [('r', 'reset', False, _('reset bisect state')),
520 ('g', 'good', False, _('mark changeset good')),
520 ('g', 'good', False, _('mark changeset good')),
521 ('b', 'bad', False, _('mark changeset bad')),
521 ('b', 'bad', False, _('mark changeset bad')),
522 ('s', 'skip', False, _('skip testing changeset')),
522 ('s', 'skip', False, _('skip testing changeset')),
523 ('e', 'extend', False, _('extend the bisect range')),
523 ('e', 'extend', False, _('extend the bisect range')),
524 ('c', 'command', '', _('use command to check changeset state'), _('CMD')),
524 ('c', 'command', '', _('use command to check changeset state'), _('CMD')),
525 ('U', 'noupdate', False, _('do not update to target'))],
525 ('U', 'noupdate', False, _('do not update to target'))],
526 _("[-gbsr] [-U] [-c CMD] [REV]"))
526 _("[-gbsr] [-U] [-c CMD] [REV]"))
527 def bisect(ui, repo, rev=None, extra=None, command=None,
527 def bisect(ui, repo, rev=None, extra=None, command=None,
528 reset=None, good=None, bad=None, skip=None, extend=None,
528 reset=None, good=None, bad=None, skip=None, extend=None,
529 noupdate=None):
529 noupdate=None):
530 """subdivision search of changesets
530 """subdivision search of changesets
531
531
532 This command helps to find changesets which introduce problems. To
532 This command helps to find changesets which introduce problems. To
533 use, mark the earliest changeset you know exhibits the problem as
533 use, mark the earliest changeset you know exhibits the problem as
534 bad, then mark the latest changeset which is free from the problem
534 bad, then mark the latest changeset which is free from the problem
535 as good. Bisect will update your working directory to a revision
535 as good. Bisect will update your working directory to a revision
536 for testing (unless the -U/--noupdate option is specified). Once
536 for testing (unless the -U/--noupdate option is specified). Once
537 you have performed tests, mark the working directory as good or
537 you have performed tests, mark the working directory as good or
538 bad, and bisect will either update to another candidate changeset
538 bad, and bisect will either update to another candidate changeset
539 or announce that it has found the bad revision.
539 or announce that it has found the bad revision.
540
540
541 As a shortcut, you can also use the revision argument to mark a
541 As a shortcut, you can also use the revision argument to mark a
542 revision as good or bad without checking it out first.
542 revision as good or bad without checking it out first.
543
543
544 If you supply a command, it will be used for automatic bisection.
544 If you supply a command, it will be used for automatic bisection.
545 The environment variable HG_NODE will contain the ID of the
545 The environment variable HG_NODE will contain the ID of the
546 changeset being tested. The exit status of the command will be
546 changeset being tested. The exit status of the command will be
547 used to mark revisions as good or bad: status 0 means good, 125
547 used to mark revisions as good or bad: status 0 means good, 125
548 means to skip the revision, 127 (command not found) will abort the
548 means to skip the revision, 127 (command not found) will abort the
549 bisection, and any other non-zero exit status means the revision
549 bisection, and any other non-zero exit status means the revision
550 is bad.
550 is bad.
551
551
552 .. container:: verbose
552 .. container:: verbose
553
553
554 Some examples:
554 Some examples:
555
555
556 - start a bisection with known bad revision 34, and good revision 12::
556 - start a bisection with known bad revision 34, and good revision 12::
557
557
558 hg bisect --bad 34
558 hg bisect --bad 34
559 hg bisect --good 12
559 hg bisect --good 12
560
560
561 - advance the current bisection by marking current revision as good or
561 - advance the current bisection by marking current revision as good or
562 bad::
562 bad::
563
563
564 hg bisect --good
564 hg bisect --good
565 hg bisect --bad
565 hg bisect --bad
566
566
567 - mark the current revision, or a known revision, to be skipped (e.g. if
567 - mark the current revision, or a known revision, to be skipped (e.g. if
568 that revision is not usable because of another issue)::
568 that revision is not usable because of another issue)::
569
569
570 hg bisect --skip
570 hg bisect --skip
571 hg bisect --skip 23
571 hg bisect --skip 23
572
572
573 - skip all revisions that do not touch directories ``foo`` or ``bar``::
573 - skip all revisions that do not touch directories ``foo`` or ``bar``::
574
574
575 hg bisect --skip "!( file('path:foo') & file('path:bar') )"
575 hg bisect --skip "!( file('path:foo') & file('path:bar') )"
576
576
577 - forget the current bisection::
577 - forget the current bisection::
578
578
579 hg bisect --reset
579 hg bisect --reset
580
580
581 - use 'make && make tests' to automatically find the first broken
581 - use 'make && make tests' to automatically find the first broken
582 revision::
582 revision::
583
583
584 hg bisect --reset
584 hg bisect --reset
585 hg bisect --bad 34
585 hg bisect --bad 34
586 hg bisect --good 12
586 hg bisect --good 12
587 hg bisect --command "make && make tests"
587 hg bisect --command "make && make tests"
588
588
589 - see all changesets whose states are already known in the current
589 - see all changesets whose states are already known in the current
590 bisection::
590 bisection::
591
591
592 hg log -r "bisect(pruned)"
592 hg log -r "bisect(pruned)"
593
593
594 - see the changeset currently being bisected (especially useful
594 - see the changeset currently being bisected (especially useful
595 if running with -U/--noupdate)::
595 if running with -U/--noupdate)::
596
596
597 hg log -r "bisect(current)"
597 hg log -r "bisect(current)"
598
598
599 - see all changesets that took part in the current bisection::
599 - see all changesets that took part in the current bisection::
600
600
601 hg log -r "bisect(range)"
601 hg log -r "bisect(range)"
602
602
603 - you can even get a nice graph::
603 - you can even get a nice graph::
604
604
605 hg log --graph -r "bisect(range)"
605 hg log --graph -r "bisect(range)"
606
606
607 See :hg:`help revsets` for more about the `bisect()` keyword.
607 See :hg:`help revsets` for more about the `bisect()` keyword.
608
608
609 Returns 0 on success.
609 Returns 0 on success.
610 """
610 """
611 def extendbisectrange(nodes, good):
611 def extendbisectrange(nodes, good):
612 # bisect is incomplete when it ends on a merge node and
612 # bisect is incomplete when it ends on a merge node and
613 # one of the parent was not checked.
613 # one of the parent was not checked.
614 parents = repo[nodes[0]].parents()
614 parents = repo[nodes[0]].parents()
615 if len(parents) > 1:
615 if len(parents) > 1:
616 side = good and state['bad'] or state['good']
616 side = good and state['bad'] or state['good']
617 num = len(set(i.node() for i in parents) & set(side))
617 num = len(set(i.node() for i in parents) & set(side))
618 if num == 1:
618 if num == 1:
619 return parents[0].ancestor(parents[1])
619 return parents[0].ancestor(parents[1])
620 return None
620 return None
621
621
622 def print_result(nodes, good):
622 def print_result(nodes, good):
623 displayer = cmdutil.show_changeset(ui, repo, {})
623 displayer = cmdutil.show_changeset(ui, repo, {})
624 if len(nodes) == 1:
624 if len(nodes) == 1:
625 # narrowed it down to a single revision
625 # narrowed it down to a single revision
626 if good:
626 if good:
627 ui.write(_("The first good revision is:\n"))
627 ui.write(_("The first good revision is:\n"))
628 else:
628 else:
629 ui.write(_("The first bad revision is:\n"))
629 ui.write(_("The first bad revision is:\n"))
630 displayer.show(repo[nodes[0]])
630 displayer.show(repo[nodes[0]])
631 extendnode = extendbisectrange(nodes, good)
631 extendnode = extendbisectrange(nodes, good)
632 if extendnode is not None:
632 if extendnode is not None:
633 ui.write(_('Not all ancestors of this changeset have been'
633 ui.write(_('Not all ancestors of this changeset have been'
634 ' checked.\nUse bisect --extend to continue the '
634 ' checked.\nUse bisect --extend to continue the '
635 'bisection from\nthe common ancestor, %s.\n')
635 'bisection from\nthe common ancestor, %s.\n')
636 % extendnode)
636 % extendnode)
637 else:
637 else:
638 # multiple possible revisions
638 # multiple possible revisions
639 if good:
639 if good:
640 ui.write(_("Due to skipped revisions, the first "
640 ui.write(_("Due to skipped revisions, the first "
641 "good revision could be any of:\n"))
641 "good revision could be any of:\n"))
642 else:
642 else:
643 ui.write(_("Due to skipped revisions, the first "
643 ui.write(_("Due to skipped revisions, the first "
644 "bad revision could be any of:\n"))
644 "bad revision could be any of:\n"))
645 for n in nodes:
645 for n in nodes:
646 displayer.show(repo[n])
646 displayer.show(repo[n])
647 displayer.close()
647 displayer.close()
648
648
649 def check_state(state, interactive=True):
649 def check_state(state, interactive=True):
650 if not state['good'] or not state['bad']:
650 if not state['good'] or not state['bad']:
651 if (good or bad or skip or reset) and interactive:
651 if (good or bad or skip or reset) and interactive:
652 return
652 return
653 if not state['good']:
653 if not state['good']:
654 raise util.Abort(_('cannot bisect (no known good revisions)'))
654 raise util.Abort(_('cannot bisect (no known good revisions)'))
655 else:
655 else:
656 raise util.Abort(_('cannot bisect (no known bad revisions)'))
656 raise util.Abort(_('cannot bisect (no known bad revisions)'))
657 return True
657 return True
658
658
659 # backward compatibility
659 # backward compatibility
660 if rev in "good bad reset init".split():
660 if rev in "good bad reset init".split():
661 ui.warn(_("(use of 'hg bisect <cmd>' is deprecated)\n"))
661 ui.warn(_("(use of 'hg bisect <cmd>' is deprecated)\n"))
662 cmd, rev, extra = rev, extra, None
662 cmd, rev, extra = rev, extra, None
663 if cmd == "good":
663 if cmd == "good":
664 good = True
664 good = True
665 elif cmd == "bad":
665 elif cmd == "bad":
666 bad = True
666 bad = True
667 else:
667 else:
668 reset = True
668 reset = True
669 elif extra or good + bad + skip + reset + extend + bool(command) > 1:
669 elif extra or good + bad + skip + reset + extend + bool(command) > 1:
670 raise util.Abort(_('incompatible arguments'))
670 raise util.Abort(_('incompatible arguments'))
671
671
672 cmdutil.checkunfinished(repo)
672 cmdutil.checkunfinished(repo)
673
673
674 if reset:
674 if reset:
675 p = repo.join("bisect.state")
675 p = repo.join("bisect.state")
676 if os.path.exists(p):
676 if os.path.exists(p):
677 os.unlink(p)
677 os.unlink(p)
678 return
678 return
679
679
680 state = hbisect.load_state(repo)
680 state = hbisect.load_state(repo)
681
681
682 if command:
682 if command:
683 changesets = 1
683 changesets = 1
684 if noupdate:
684 if noupdate:
685 try:
685 try:
686 node = state['current'][0]
686 node = state['current'][0]
687 except LookupError:
687 except LookupError:
688 raise util.Abort(_('current bisect revision is unknown - '
688 raise util.Abort(_('current bisect revision is unknown - '
689 'start a new bisect to fix'))
689 'start a new bisect to fix'))
690 else:
690 else:
691 node, p2 = repo.dirstate.parents()
691 node, p2 = repo.dirstate.parents()
692 if p2 != nullid:
692 if p2 != nullid:
693 raise util.Abort(_('current bisect revision is a merge'))
693 raise util.Abort(_('current bisect revision is a merge'))
694 try:
694 try:
695 while changesets:
695 while changesets:
696 # update state
696 # update state
697 state['current'] = [node]
697 state['current'] = [node]
698 hbisect.save_state(repo, state)
698 hbisect.save_state(repo, state)
699 status = util.system(command,
699 status = util.system(command,
700 environ={'HG_NODE': hex(node)},
700 environ={'HG_NODE': hex(node)},
701 out=ui.fout)
701 out=ui.fout)
702 if status == 125:
702 if status == 125:
703 transition = "skip"
703 transition = "skip"
704 elif status == 0:
704 elif status == 0:
705 transition = "good"
705 transition = "good"
706 # status < 0 means process was killed
706 # status < 0 means process was killed
707 elif status == 127:
707 elif status == 127:
708 raise util.Abort(_("failed to execute %s") % command)
708 raise util.Abort(_("failed to execute %s") % command)
709 elif status < 0:
709 elif status < 0:
710 raise util.Abort(_("%s killed") % command)
710 raise util.Abort(_("%s killed") % command)
711 else:
711 else:
712 transition = "bad"
712 transition = "bad"
713 ctx = scmutil.revsingle(repo, rev, node)
713 ctx = scmutil.revsingle(repo, rev, node)
714 rev = None # clear for future iterations
714 rev = None # clear for future iterations
715 state[transition].append(ctx.node())
715 state[transition].append(ctx.node())
716 ui.status(_('changeset %d:%s: %s\n') % (ctx, ctx, transition))
716 ui.status(_('changeset %d:%s: %s\n') % (ctx, ctx, transition))
717 check_state(state, interactive=False)
717 check_state(state, interactive=False)
718 # bisect
718 # bisect
719 nodes, changesets, bgood = hbisect.bisect(repo.changelog, state)
719 nodes, changesets, bgood = hbisect.bisect(repo.changelog, state)
720 # update to next check
720 # update to next check
721 node = nodes[0]
721 node = nodes[0]
722 if not noupdate:
722 if not noupdate:
723 cmdutil.bailifchanged(repo)
723 cmdutil.bailifchanged(repo)
724 hg.clean(repo, node, show_stats=False)
724 hg.clean(repo, node, show_stats=False)
725 finally:
725 finally:
726 state['current'] = [node]
726 state['current'] = [node]
727 hbisect.save_state(repo, state)
727 hbisect.save_state(repo, state)
728 print_result(nodes, bgood)
728 print_result(nodes, bgood)
729 return
729 return
730
730
731 # update state
731 # update state
732
732
733 if rev:
733 if rev:
734 nodes = [repo.lookup(i) for i in scmutil.revrange(repo, [rev])]
734 nodes = [repo.lookup(i) for i in scmutil.revrange(repo, [rev])]
735 else:
735 else:
736 nodes = [repo.lookup('.')]
736 nodes = [repo.lookup('.')]
737
737
738 if good or bad or skip:
738 if good or bad or skip:
739 if good:
739 if good:
740 state['good'] += nodes
740 state['good'] += nodes
741 elif bad:
741 elif bad:
742 state['bad'] += nodes
742 state['bad'] += nodes
743 elif skip:
743 elif skip:
744 state['skip'] += nodes
744 state['skip'] += nodes
745 hbisect.save_state(repo, state)
745 hbisect.save_state(repo, state)
746
746
747 if not check_state(state):
747 if not check_state(state):
748 return
748 return
749
749
750 # actually bisect
750 # actually bisect
751 nodes, changesets, good = hbisect.bisect(repo.changelog, state)
751 nodes, changesets, good = hbisect.bisect(repo.changelog, state)
752 if extend:
752 if extend:
753 if not changesets:
753 if not changesets:
754 extendnode = extendbisectrange(nodes, good)
754 extendnode = extendbisectrange(nodes, good)
755 if extendnode is not None:
755 if extendnode is not None:
756 ui.write(_("Extending search to changeset %d:%s\n"
756 ui.write(_("Extending search to changeset %d:%s\n"
757 % (extendnode.rev(), extendnode)))
757 % (extendnode.rev(), extendnode)))
758 state['current'] = [extendnode.node()]
758 state['current'] = [extendnode.node()]
759 hbisect.save_state(repo, state)
759 hbisect.save_state(repo, state)
760 if noupdate:
760 if noupdate:
761 return
761 return
762 cmdutil.bailifchanged(repo)
762 cmdutil.bailifchanged(repo)
763 return hg.clean(repo, extendnode.node())
763 return hg.clean(repo, extendnode.node())
764 raise util.Abort(_("nothing to extend"))
764 raise util.Abort(_("nothing to extend"))
765
765
766 if changesets == 0:
766 if changesets == 0:
767 print_result(nodes, good)
767 print_result(nodes, good)
768 else:
768 else:
769 assert len(nodes) == 1 # only a single node can be tested next
769 assert len(nodes) == 1 # only a single node can be tested next
770 node = nodes[0]
770 node = nodes[0]
771 # compute the approximate number of remaining tests
771 # compute the approximate number of remaining tests
772 tests, size = 0, 2
772 tests, size = 0, 2
773 while size <= changesets:
773 while size <= changesets:
774 tests, size = tests + 1, size * 2
774 tests, size = tests + 1, size * 2
775 rev = repo.changelog.rev(node)
775 rev = repo.changelog.rev(node)
776 ui.write(_("Testing changeset %d:%s "
776 ui.write(_("Testing changeset %d:%s "
777 "(%d changesets remaining, ~%d tests)\n")
777 "(%d changesets remaining, ~%d tests)\n")
778 % (rev, short(node), changesets, tests))
778 % (rev, short(node), changesets, tests))
779 state['current'] = [node]
779 state['current'] = [node]
780 hbisect.save_state(repo, state)
780 hbisect.save_state(repo, state)
781 if not noupdate:
781 if not noupdate:
782 cmdutil.bailifchanged(repo)
782 cmdutil.bailifchanged(repo)
783 return hg.clean(repo, node)
783 return hg.clean(repo, node)
784
784
785 @command('bookmarks|bookmark',
785 @command('bookmarks|bookmark',
786 [('f', 'force', False, _('force')),
786 [('f', 'force', False, _('force')),
787 ('r', 'rev', '', _('revision'), _('REV')),
787 ('r', 'rev', '', _('revision'), _('REV')),
788 ('d', 'delete', False, _('delete a given bookmark')),
788 ('d', 'delete', False, _('delete a given bookmark')),
789 ('m', 'rename', '', _('rename a given bookmark'), _('NAME')),
789 ('m', 'rename', '', _('rename a given bookmark'), _('NAME')),
790 ('i', 'inactive', False, _('mark a bookmark inactive'))],
790 ('i', 'inactive', False, _('mark a bookmark inactive'))],
791 _('hg bookmarks [OPTIONS]... [NAME]...'))
791 _('hg bookmarks [OPTIONS]... [NAME]...'))
792 def bookmark(ui, repo, *names, **opts):
792 def bookmark(ui, repo, *names, **opts):
793 '''track a line of development with movable markers
793 '''track a line of development with movable markers
794
794
795 Bookmarks are pointers to certain commits that move when committing.
795 Bookmarks are pointers to certain commits that move when committing.
796 Bookmarks are local. They can be renamed, copied and deleted. It is
796 Bookmarks are local. They can be renamed, copied and deleted. It is
797 possible to use :hg:`merge NAME` to merge from a given bookmark, and
797 possible to use :hg:`merge NAME` to merge from a given bookmark, and
798 :hg:`update NAME` to update to a given bookmark.
798 :hg:`update NAME` to update to a given bookmark.
799
799
800 You can use :hg:`bookmark NAME` to set a bookmark on the working
800 You can use :hg:`bookmark NAME` to set a bookmark on the working
801 directory's parent revision with the given name. If you specify
801 directory's parent revision with the given name. If you specify
802 a revision using -r REV (where REV may be an existing bookmark),
802 a revision using -r REV (where REV may be an existing bookmark),
803 the bookmark is assigned to that revision.
803 the bookmark is assigned to that revision.
804
804
805 Bookmarks can be pushed and pulled between repositories (see :hg:`help
805 Bookmarks can be pushed and pulled between repositories (see :hg:`help
806 push` and :hg:`help pull`). This requires both the local and remote
806 push` and :hg:`help pull`). This requires both the local and remote
807 repositories to support bookmarks. For versions prior to 1.8, this means
807 repositories to support bookmarks. For versions prior to 1.8, this means
808 the bookmarks extension must be enabled.
808 the bookmarks extension must be enabled.
809
809
810 If you set a bookmark called '@', new clones of the repository will
810 If you set a bookmark called '@', new clones of the repository will
811 have that revision checked out (and the bookmark made active) by
811 have that revision checked out (and the bookmark made active) by
812 default.
812 default.
813
813
814 With -i/--inactive, the new bookmark will not be made the active
814 With -i/--inactive, the new bookmark will not be made the active
815 bookmark. If -r/--rev is given, the new bookmark will not be made
815 bookmark. If -r/--rev is given, the new bookmark will not be made
816 active even if -i/--inactive is not given. If no NAME is given, the
816 active even if -i/--inactive is not given. If no NAME is given, the
817 current active bookmark will be marked inactive.
817 current active bookmark will be marked inactive.
818 '''
818 '''
819 force = opts.get('force')
819 force = opts.get('force')
820 rev = opts.get('rev')
820 rev = opts.get('rev')
821 delete = opts.get('delete')
821 delete = opts.get('delete')
822 rename = opts.get('rename')
822 rename = opts.get('rename')
823 inactive = opts.get('inactive')
823 inactive = opts.get('inactive')
824
824
825 def checkformat(mark):
825 def checkformat(mark):
826 mark = mark.strip()
826 mark = mark.strip()
827 if not mark:
827 if not mark:
828 raise util.Abort(_("bookmark names cannot consist entirely of "
828 raise util.Abort(_("bookmark names cannot consist entirely of "
829 "whitespace"))
829 "whitespace"))
830 scmutil.checknewlabel(repo, mark, 'bookmark')
830 scmutil.checknewlabel(repo, mark, 'bookmark')
831 return mark
831 return mark
832
832
833 def checkconflict(repo, mark, cur, force=False, target=None):
833 def checkconflict(repo, mark, cur, force=False, target=None):
834 if mark in marks and not force:
834 if mark in marks and not force:
835 if target:
835 if target:
836 if marks[mark] == target and target == cur:
836 if marks[mark] == target and target == cur:
837 # re-activating a bookmark
837 # re-activating a bookmark
838 return
838 return
839 anc = repo.changelog.ancestors([repo[target].rev()])
839 anc = repo.changelog.ancestors([repo[target].rev()])
840 bmctx = repo[marks[mark]]
840 bmctx = repo[marks[mark]]
841 divs = [repo[b].node() for b in marks
841 divs = [repo[b].node() for b in marks
842 if b.split('@', 1)[0] == mark.split('@', 1)[0]]
842 if b.split('@', 1)[0] == mark.split('@', 1)[0]]
843
843
844 # allow resolving a single divergent bookmark even if moving
844 # allow resolving a single divergent bookmark even if moving
845 # the bookmark across branches when a revision is specified
845 # the bookmark across branches when a revision is specified
846 # that contains a divergent bookmark
846 # that contains a divergent bookmark
847 if bmctx.rev() not in anc and target in divs:
847 if bmctx.rev() not in anc and target in divs:
848 bookmarks.deletedivergent(repo, [target], mark)
848 bookmarks.deletedivergent(repo, [target], mark)
849 return
849 return
850
850
851 deletefrom = [b for b in divs
851 deletefrom = [b for b in divs
852 if repo[b].rev() in anc or b == target]
852 if repo[b].rev() in anc or b == target]
853 bookmarks.deletedivergent(repo, deletefrom, mark)
853 bookmarks.deletedivergent(repo, deletefrom, mark)
854 if bookmarks.validdest(repo, bmctx, repo[target]):
854 if bookmarks.validdest(repo, bmctx, repo[target]):
855 ui.status(_("moving bookmark '%s' forward from %s\n") %
855 ui.status(_("moving bookmark '%s' forward from %s\n") %
856 (mark, short(bmctx.node())))
856 (mark, short(bmctx.node())))
857 return
857 return
858 raise util.Abort(_("bookmark '%s' already exists "
858 raise util.Abort(_("bookmark '%s' already exists "
859 "(use -f to force)") % mark)
859 "(use -f to force)") % mark)
860 if ((mark in repo.branchmap() or mark == repo.dirstate.branch())
860 if ((mark in repo.branchmap() or mark == repo.dirstate.branch())
861 and not force):
861 and not force):
862 raise util.Abort(
862 raise util.Abort(
863 _("a bookmark cannot have the name of an existing branch"))
863 _("a bookmark cannot have the name of an existing branch"))
864
864
865 if delete and rename:
865 if delete and rename:
866 raise util.Abort(_("--delete and --rename are incompatible"))
866 raise util.Abort(_("--delete and --rename are incompatible"))
867 if delete and rev:
867 if delete and rev:
868 raise util.Abort(_("--rev is incompatible with --delete"))
868 raise util.Abort(_("--rev is incompatible with --delete"))
869 if rename and rev:
869 if rename and rev:
870 raise util.Abort(_("--rev is incompatible with --rename"))
870 raise util.Abort(_("--rev is incompatible with --rename"))
871 if not names and (delete or rev):
871 if not names and (delete or rev):
872 raise util.Abort(_("bookmark name required"))
872 raise util.Abort(_("bookmark name required"))
873
873
874 if delete or rename or names or inactive:
874 if delete or rename or names or inactive:
875 wlock = repo.wlock()
875 wlock = repo.wlock()
876 try:
876 try:
877 cur = repo.changectx('.').node()
877 cur = repo.changectx('.').node()
878 marks = repo._bookmarks
878 marks = repo._bookmarks
879 if delete:
879 if delete:
880 for mark in names:
880 for mark in names:
881 if mark not in marks:
881 if mark not in marks:
882 raise util.Abort(_("bookmark '%s' does not exist") %
882 raise util.Abort(_("bookmark '%s' does not exist") %
883 mark)
883 mark)
884 if mark == repo._bookmarkcurrent:
884 if mark == repo._bookmarkcurrent:
885 bookmarks.unsetcurrent(repo)
885 bookmarks.unsetcurrent(repo)
886 del marks[mark]
886 del marks[mark]
887 marks.write()
887 marks.write()
888
888
889 elif rename:
889 elif rename:
890 if not names:
890 if not names:
891 raise util.Abort(_("new bookmark name required"))
891 raise util.Abort(_("new bookmark name required"))
892 elif len(names) > 1:
892 elif len(names) > 1:
893 raise util.Abort(_("only one new bookmark name allowed"))
893 raise util.Abort(_("only one new bookmark name allowed"))
894 mark = checkformat(names[0])
894 mark = checkformat(names[0])
895 if rename not in marks:
895 if rename not in marks:
896 raise util.Abort(_("bookmark '%s' does not exist") % rename)
896 raise util.Abort(_("bookmark '%s' does not exist") % rename)
897 checkconflict(repo, mark, cur, force)
897 checkconflict(repo, mark, cur, force)
898 marks[mark] = marks[rename]
898 marks[mark] = marks[rename]
899 if repo._bookmarkcurrent == rename and not inactive:
899 if repo._bookmarkcurrent == rename and not inactive:
900 bookmarks.setcurrent(repo, mark)
900 bookmarks.setcurrent(repo, mark)
901 del marks[rename]
901 del marks[rename]
902 marks.write()
902 marks.write()
903
903
904 elif names:
904 elif names:
905 newact = None
905 newact = None
906 for mark in names:
906 for mark in names:
907 mark = checkformat(mark)
907 mark = checkformat(mark)
908 if newact is None:
908 if newact is None:
909 newact = mark
909 newact = mark
910 if inactive and mark == repo._bookmarkcurrent:
910 if inactive and mark == repo._bookmarkcurrent:
911 bookmarks.unsetcurrent(repo)
911 bookmarks.unsetcurrent(repo)
912 return
912 return
913 tgt = cur
913 tgt = cur
914 if rev:
914 if rev:
915 tgt = scmutil.revsingle(repo, rev).node()
915 tgt = scmutil.revsingle(repo, rev).node()
916 checkconflict(repo, mark, cur, force, tgt)
916 checkconflict(repo, mark, cur, force, tgt)
917 marks[mark] = tgt
917 marks[mark] = tgt
918 if not inactive and cur == marks[newact] and not rev:
918 if not inactive and cur == marks[newact] and not rev:
919 bookmarks.setcurrent(repo, newact)
919 bookmarks.setcurrent(repo, newact)
920 elif cur != tgt and newact == repo._bookmarkcurrent:
920 elif cur != tgt and newact == repo._bookmarkcurrent:
921 bookmarks.unsetcurrent(repo)
921 bookmarks.unsetcurrent(repo)
922 marks.write()
922 marks.write()
923
923
924 elif inactive:
924 elif inactive:
925 if len(marks) == 0:
925 if len(marks) == 0:
926 ui.status(_("no bookmarks set\n"))
926 ui.status(_("no bookmarks set\n"))
927 elif not repo._bookmarkcurrent:
927 elif not repo._bookmarkcurrent:
928 ui.status(_("no active bookmark\n"))
928 ui.status(_("no active bookmark\n"))
929 else:
929 else:
930 bookmarks.unsetcurrent(repo)
930 bookmarks.unsetcurrent(repo)
931 finally:
931 finally:
932 wlock.release()
932 wlock.release()
933 else: # show bookmarks
933 else: # show bookmarks
934 hexfn = ui.debugflag and hex or short
934 hexfn = ui.debugflag and hex or short
935 marks = repo._bookmarks
935 marks = repo._bookmarks
936 if len(marks) == 0:
936 if len(marks) == 0:
937 ui.status(_("no bookmarks set\n"))
937 ui.status(_("no bookmarks set\n"))
938 else:
938 else:
939 for bmark, n in sorted(marks.iteritems()):
939 for bmark, n in sorted(marks.iteritems()):
940 current = repo._bookmarkcurrent
940 current = repo._bookmarkcurrent
941 if bmark == current:
941 if bmark == current:
942 prefix, label = '*', 'bookmarks.current'
942 prefix, label = '*', 'bookmarks.current'
943 else:
943 else:
944 prefix, label = ' ', ''
944 prefix, label = ' ', ''
945
945
946 if ui.quiet:
946 if ui.quiet:
947 ui.write("%s\n" % bmark, label=label)
947 ui.write("%s\n" % bmark, label=label)
948 else:
948 else:
949 ui.write(" %s %-25s %d:%s\n" % (
949 ui.write(" %s %-25s %d:%s\n" % (
950 prefix, bmark, repo.changelog.rev(n), hexfn(n)),
950 prefix, bmark, repo.changelog.rev(n), hexfn(n)),
951 label=label)
951 label=label)
952
952
953 @command('branch',
953 @command('branch',
954 [('f', 'force', None,
954 [('f', 'force', None,
955 _('set branch name even if it shadows an existing branch')),
955 _('set branch name even if it shadows an existing branch')),
956 ('C', 'clean', None, _('reset branch name to parent branch name'))],
956 ('C', 'clean', None, _('reset branch name to parent branch name'))],
957 _('[-fC] [NAME]'))
957 _('[-fC] [NAME]'))
958 def branch(ui, repo, label=None, **opts):
958 def branch(ui, repo, label=None, **opts):
959 """set or show the current branch name
959 """set or show the current branch name
960
960
961 .. note::
961 .. note::
962
962
963 Branch names are permanent and global. Use :hg:`bookmark` to create a
963 Branch names are permanent and global. Use :hg:`bookmark` to create a
964 light-weight bookmark instead. See :hg:`help glossary` for more
964 light-weight bookmark instead. See :hg:`help glossary` for more
965 information about named branches and bookmarks.
965 information about named branches and bookmarks.
966
966
967 With no argument, show the current branch name. With one argument,
967 With no argument, show the current branch name. With one argument,
968 set the working directory branch name (the branch will not exist
968 set the working directory branch name (the branch will not exist
969 in the repository until the next commit). Standard practice
969 in the repository until the next commit). Standard practice
970 recommends that primary development take place on the 'default'
970 recommends that primary development take place on the 'default'
971 branch.
971 branch.
972
972
973 Unless -f/--force is specified, branch will not let you set a
973 Unless -f/--force is specified, branch will not let you set a
974 branch name that already exists, even if it's inactive.
974 branch name that already exists, even if it's inactive.
975
975
976 Use -C/--clean to reset the working directory branch to that of
976 Use -C/--clean to reset the working directory branch to that of
977 the parent of the working directory, negating a previous branch
977 the parent of the working directory, negating a previous branch
978 change.
978 change.
979
979
980 Use the command :hg:`update` to switch to an existing branch. Use
980 Use the command :hg:`update` to switch to an existing branch. Use
981 :hg:`commit --close-branch` to mark this branch as closed.
981 :hg:`commit --close-branch` to mark this branch as closed.
982
982
983 Returns 0 on success.
983 Returns 0 on success.
984 """
984 """
985 if label:
985 if label:
986 label = label.strip()
986 label = label.strip()
987
987
988 if not opts.get('clean') and not label:
988 if not opts.get('clean') and not label:
989 ui.write("%s\n" % repo.dirstate.branch())
989 ui.write("%s\n" % repo.dirstate.branch())
990 return
990 return
991
991
992 wlock = repo.wlock()
992 wlock = repo.wlock()
993 try:
993 try:
994 if opts.get('clean'):
994 if opts.get('clean'):
995 label = repo[None].p1().branch()
995 label = repo[None].p1().branch()
996 repo.dirstate.setbranch(label)
996 repo.dirstate.setbranch(label)
997 ui.status(_('reset working directory to branch %s\n') % label)
997 ui.status(_('reset working directory to branch %s\n') % label)
998 elif label:
998 elif label:
999 if not opts.get('force') and label in repo.branchmap():
999 if not opts.get('force') and label in repo.branchmap():
1000 if label not in [p.branch() for p in repo.parents()]:
1000 if label not in [p.branch() for p in repo.parents()]:
1001 raise util.Abort(_('a branch of the same name already'
1001 raise util.Abort(_('a branch of the same name already'
1002 ' exists'),
1002 ' exists'),
1003 # i18n: "it" refers to an existing branch
1003 # i18n: "it" refers to an existing branch
1004 hint=_("use 'hg update' to switch to it"))
1004 hint=_("use 'hg update' to switch to it"))
1005 scmutil.checknewlabel(repo, label, 'branch')
1005 scmutil.checknewlabel(repo, label, 'branch')
1006 repo.dirstate.setbranch(label)
1006 repo.dirstate.setbranch(label)
1007 ui.status(_('marked working directory as branch %s\n') % label)
1007 ui.status(_('marked working directory as branch %s\n') % label)
1008 ui.status(_('(branches are permanent and global, '
1008 ui.status(_('(branches are permanent and global, '
1009 'did you want a bookmark?)\n'))
1009 'did you want a bookmark?)\n'))
1010 finally:
1010 finally:
1011 wlock.release()
1011 wlock.release()
1012
1012
1013 @command('branches',
1013 @command('branches',
1014 [('a', 'active', False, _('show only branches that have unmerged heads')),
1014 [('a', 'active', False, _('show only branches that have unmerged heads')),
1015 ('c', 'closed', False, _('show normal and closed branches'))],
1015 ('c', 'closed', False, _('show normal and closed branches'))],
1016 _('[-ac]'))
1016 _('[-ac]'))
1017 def branches(ui, repo, active=False, closed=False):
1017 def branches(ui, repo, active=False, closed=False):
1018 """list repository named branches
1018 """list repository named branches
1019
1019
1020 List the repository's named branches, indicating which ones are
1020 List the repository's named branches, indicating which ones are
1021 inactive. If -c/--closed is specified, also list branches which have
1021 inactive. If -c/--closed is specified, also list branches which have
1022 been marked closed (see :hg:`commit --close-branch`).
1022 been marked closed (see :hg:`commit --close-branch`).
1023
1023
1024 If -a/--active is specified, only show active branches. A branch
1024 If -a/--active is specified, only show active branches. A branch
1025 is considered active if it contains repository heads.
1025 is considered active if it contains repository heads.
1026
1026
1027 Use the command :hg:`update` to switch to an existing branch.
1027 Use the command :hg:`update` to switch to an existing branch.
1028
1028
1029 Returns 0.
1029 Returns 0.
1030 """
1030 """
1031
1031
1032 hexfunc = ui.debugflag and hex or short
1032 hexfunc = ui.debugflag and hex or short
1033
1033
1034 allheads = set(repo.heads())
1034 allheads = set(repo.heads())
1035 branches = []
1035 branches = []
1036 for tag, heads, tip, isclosed in repo.branchmap().iterbranches():
1036 for tag, heads, tip, isclosed in repo.branchmap().iterbranches():
1037 isactive = not isclosed and bool(set(heads) & allheads)
1037 isactive = not isclosed and bool(set(heads) & allheads)
1038 branches.append((tag, repo[tip], isactive, not isclosed))
1038 branches.append((tag, repo[tip], isactive, not isclosed))
1039 branches.sort(key=lambda i: (i[2], i[1].rev(), i[0], i[3]),
1039 branches.sort(key=lambda i: (i[2], i[1].rev(), i[0], i[3]),
1040 reverse=True)
1040 reverse=True)
1041
1041
1042 for tag, ctx, isactive, isopen in branches:
1042 for tag, ctx, isactive, isopen in branches:
1043 if (not active) or isactive:
1043 if (not active) or isactive:
1044 if isactive:
1044 if isactive:
1045 label = 'branches.active'
1045 label = 'branches.active'
1046 notice = ''
1046 notice = ''
1047 elif not isopen:
1047 elif not isopen:
1048 if not closed:
1048 if not closed:
1049 continue
1049 continue
1050 label = 'branches.closed'
1050 label = 'branches.closed'
1051 notice = _(' (closed)')
1051 notice = _(' (closed)')
1052 else:
1052 else:
1053 label = 'branches.inactive'
1053 label = 'branches.inactive'
1054 notice = _(' (inactive)')
1054 notice = _(' (inactive)')
1055 if tag == repo.dirstate.branch():
1055 if tag == repo.dirstate.branch():
1056 label = 'branches.current'
1056 label = 'branches.current'
1057 rev = str(ctx.rev()).rjust(31 - encoding.colwidth(tag))
1057 rev = str(ctx.rev()).rjust(31 - encoding.colwidth(tag))
1058 rev = ui.label('%s:%s' % (rev, hexfunc(ctx.node())),
1058 rev = ui.label('%s:%s' % (rev, hexfunc(ctx.node())),
1059 'log.changeset changeset.%s' % ctx.phasestr())
1059 'log.changeset changeset.%s' % ctx.phasestr())
1060 labeledtag = ui.label(tag, label)
1060 labeledtag = ui.label(tag, label)
1061 if ui.quiet:
1061 if ui.quiet:
1062 ui.write("%s\n" % labeledtag)
1062 ui.write("%s\n" % labeledtag)
1063 else:
1063 else:
1064 ui.write("%s %s%s\n" % (labeledtag, rev, notice))
1064 ui.write("%s %s%s\n" % (labeledtag, rev, notice))
1065
1065
1066 @command('bundle',
1066 @command('bundle',
1067 [('f', 'force', None, _('run even when the destination is unrelated')),
1067 [('f', 'force', None, _('run even when the destination is unrelated')),
1068 ('r', 'rev', [], _('a changeset intended to be added to the destination'),
1068 ('r', 'rev', [], _('a changeset intended to be added to the destination'),
1069 _('REV')),
1069 _('REV')),
1070 ('b', 'branch', [], _('a specific branch you would like to bundle'),
1070 ('b', 'branch', [], _('a specific branch you would like to bundle'),
1071 _('BRANCH')),
1071 _('BRANCH')),
1072 ('', 'base', [],
1072 ('', 'base', [],
1073 _('a base changeset assumed to be available at the destination'),
1073 _('a base changeset assumed to be available at the destination'),
1074 _('REV')),
1074 _('REV')),
1075 ('a', 'all', None, _('bundle all changesets in the repository')),
1075 ('a', 'all', None, _('bundle all changesets in the repository')),
1076 ('t', 'type', 'bzip2', _('bundle compression type to use'), _('TYPE')),
1076 ('t', 'type', 'bzip2', _('bundle compression type to use'), _('TYPE')),
1077 ] + remoteopts,
1077 ] + remoteopts,
1078 _('[-f] [-t TYPE] [-a] [-r REV]... [--base REV]... FILE [DEST]'))
1078 _('[-f] [-t TYPE] [-a] [-r REV]... [--base REV]... FILE [DEST]'))
1079 def bundle(ui, repo, fname, dest=None, **opts):
1079 def bundle(ui, repo, fname, dest=None, **opts):
1080 """create a changegroup file
1080 """create a changegroup file
1081
1081
1082 Generate a compressed changegroup file collecting changesets not
1082 Generate a compressed changegroup file collecting changesets not
1083 known to be in another repository.
1083 known to be in another repository.
1084
1084
1085 If you omit the destination repository, then hg assumes the
1085 If you omit the destination repository, then hg assumes the
1086 destination will have all the nodes you specify with --base
1086 destination will have all the nodes you specify with --base
1087 parameters. To create a bundle containing all changesets, use
1087 parameters. To create a bundle containing all changesets, use
1088 -a/--all (or --base null).
1088 -a/--all (or --base null).
1089
1089
1090 You can change compression method with the -t/--type option.
1090 You can change compression method with the -t/--type option.
1091 The available compression methods are: none, bzip2, and
1091 The available compression methods are: none, bzip2, and
1092 gzip (by default, bundles are compressed using bzip2).
1092 gzip (by default, bundles are compressed using bzip2).
1093
1093
1094 The bundle file can then be transferred using conventional means
1094 The bundle file can then be transferred using conventional means
1095 and applied to another repository with the unbundle or pull
1095 and applied to another repository with the unbundle or pull
1096 command. This is useful when direct push and pull are not
1096 command. This is useful when direct push and pull are not
1097 available or when exporting an entire repository is undesirable.
1097 available or when exporting an entire repository is undesirable.
1098
1098
1099 Applying bundles preserves all changeset contents including
1099 Applying bundles preserves all changeset contents including
1100 permissions, copy/rename information, and revision history.
1100 permissions, copy/rename information, and revision history.
1101
1101
1102 Returns 0 on success, 1 if no changes found.
1102 Returns 0 on success, 1 if no changes found.
1103 """
1103 """
1104 revs = None
1104 revs = None
1105 if 'rev' in opts:
1105 if 'rev' in opts:
1106 revs = scmutil.revrange(repo, opts['rev'])
1106 revs = scmutil.revrange(repo, opts['rev'])
1107
1107
1108 bundletype = opts.get('type', 'bzip2').lower()
1108 bundletype = opts.get('type', 'bzip2').lower()
1109 btypes = {'none': 'HG10UN', 'bzip2': 'HG10BZ', 'gzip': 'HG10GZ'}
1109 btypes = {'none': 'HG10UN', 'bzip2': 'HG10BZ', 'gzip': 'HG10GZ'}
1110 bundletype = btypes.get(bundletype)
1110 bundletype = btypes.get(bundletype)
1111 if bundletype not in changegroup.bundletypes:
1111 if bundletype not in changegroup.bundletypes:
1112 raise util.Abort(_('unknown bundle type specified with --type'))
1112 raise util.Abort(_('unknown bundle type specified with --type'))
1113
1113
1114 if opts.get('all'):
1114 if opts.get('all'):
1115 base = ['null']
1115 base = ['null']
1116 else:
1116 else:
1117 base = scmutil.revrange(repo, opts.get('base'))
1117 base = scmutil.revrange(repo, opts.get('base'))
1118 # TODO: get desired bundlecaps from command line.
1118 # TODO: get desired bundlecaps from command line.
1119 bundlecaps = None
1119 bundlecaps = None
1120 if base:
1120 if base:
1121 if dest:
1121 if dest:
1122 raise util.Abort(_("--base is incompatible with specifying "
1122 raise util.Abort(_("--base is incompatible with specifying "
1123 "a destination"))
1123 "a destination"))
1124 common = [repo.lookup(rev) for rev in base]
1124 common = [repo.lookup(rev) for rev in base]
1125 heads = revs and map(repo.lookup, revs) or revs
1125 heads = revs and map(repo.lookup, revs) or revs
1126 cg = repo.getbundle('bundle', heads=heads, common=common,
1126 cg = repo.getbundle('bundle', heads=heads, common=common,
1127 bundlecaps=bundlecaps)
1127 bundlecaps=bundlecaps)
1128 outgoing = None
1128 outgoing = None
1129 else:
1129 else:
1130 dest = ui.expandpath(dest or 'default-push', dest or 'default')
1130 dest = ui.expandpath(dest or 'default-push', dest or 'default')
1131 dest, branches = hg.parseurl(dest, opts.get('branch'))
1131 dest, branches = hg.parseurl(dest, opts.get('branch'))
1132 other = hg.peer(repo, opts, dest)
1132 other = hg.peer(repo, opts, dest)
1133 revs, checkout = hg.addbranchrevs(repo, repo, branches, revs)
1133 revs, checkout = hg.addbranchrevs(repo, repo, branches, revs)
1134 heads = revs and map(repo.lookup, revs) or revs
1134 heads = revs and map(repo.lookup, revs) or revs
1135 outgoing = discovery.findcommonoutgoing(repo, other,
1135 outgoing = discovery.findcommonoutgoing(repo, other,
1136 onlyheads=heads,
1136 onlyheads=heads,
1137 force=opts.get('force'),
1137 force=opts.get('force'),
1138 portable=True)
1138 portable=True)
1139 cg = repo.getlocalbundle('bundle', outgoing, bundlecaps)
1139 cg = repo.getlocalbundle('bundle', outgoing, bundlecaps)
1140 if not cg:
1140 if not cg:
1141 scmutil.nochangesfound(ui, repo, outgoing and outgoing.excluded)
1141 scmutil.nochangesfound(ui, repo, outgoing and outgoing.excluded)
1142 return 1
1142 return 1
1143
1143
1144 changegroup.writebundle(cg, fname, bundletype)
1144 changegroup.writebundle(cg, fname, bundletype)
1145
1145
1146 @command('cat',
1146 @command('cat',
1147 [('o', 'output', '',
1147 [('o', 'output', '',
1148 _('print output to file with formatted name'), _('FORMAT')),
1148 _('print output to file with formatted name'), _('FORMAT')),
1149 ('r', 'rev', '', _('print the given revision'), _('REV')),
1149 ('r', 'rev', '', _('print the given revision'), _('REV')),
1150 ('', 'decode', None, _('apply any matching decode filter')),
1150 ('', 'decode', None, _('apply any matching decode filter')),
1151 ] + walkopts,
1151 ] + walkopts,
1152 _('[OPTION]... FILE...'))
1152 _('[OPTION]... FILE...'))
1153 def cat(ui, repo, file1, *pats, **opts):
1153 def cat(ui, repo, file1, *pats, **opts):
1154 """output the current or given revision of files
1154 """output the current or given revision of files
1155
1155
1156 Print the specified files as they were at the given revision. If
1156 Print the specified files as they were at the given revision. If
1157 no revision is given, the parent of the working directory is used.
1157 no revision is given, the parent of the working directory is used.
1158
1158
1159 Output may be to a file, in which case the name of the file is
1159 Output may be to a file, in which case the name of the file is
1160 given using a format string. The formatting rules are the same as
1160 given using a format string. The formatting rules are the same as
1161 for the export command, with the following additions:
1161 for the export command, with the following additions:
1162
1162
1163 :``%s``: basename of file being printed
1163 :``%s``: basename of file being printed
1164 :``%d``: dirname of file being printed, or '.' if in repository root
1164 :``%d``: dirname of file being printed, or '.' if in repository root
1165 :``%p``: root-relative path name of file being printed
1165 :``%p``: root-relative path name of file being printed
1166
1166
1167 Returns 0 on success.
1167 Returns 0 on success.
1168 """
1168 """
1169 ctx = scmutil.revsingle(repo, opts.get('rev'))
1169 ctx = scmutil.revsingle(repo, opts.get('rev'))
1170 err = 1
1170 err = 1
1171 m = scmutil.match(ctx, (file1,) + pats, opts)
1171 m = scmutil.match(ctx, (file1,) + pats, opts)
1172
1172
1173 def write(path):
1173 def write(path):
1174 fp = cmdutil.makefileobj(repo, opts.get('output'), ctx.node(),
1174 fp = cmdutil.makefileobj(repo, opts.get('output'), ctx.node(),
1175 pathname=path)
1175 pathname=path)
1176 data = ctx[path].data()
1176 data = ctx[path].data()
1177 if opts.get('decode'):
1177 if opts.get('decode'):
1178 data = repo.wwritedata(path, data)
1178 data = repo.wwritedata(path, data)
1179 fp.write(data)
1179 fp.write(data)
1180 fp.close()
1180 fp.close()
1181
1181
1182 # Automation often uses hg cat on single files, so special case it
1182 # Automation often uses hg cat on single files, so special case it
1183 # for performance to avoid the cost of parsing the manifest.
1183 # for performance to avoid the cost of parsing the manifest.
1184 if len(m.files()) == 1 and not m.anypats():
1184 if len(m.files()) == 1 and not m.anypats():
1185 file = m.files()[0]
1185 file = m.files()[0]
1186 mf = repo.manifest
1186 mf = repo.manifest
1187 mfnode = ctx._changeset[0]
1187 mfnode = ctx._changeset[0]
1188 if mf.find(mfnode, file)[0]:
1188 if mf.find(mfnode, file)[0]:
1189 write(file)
1189 write(file)
1190 return 0
1190 return 0
1191
1191
1192 for abs in ctx.walk(m):
1192 for abs in ctx.walk(m):
1193 write(abs)
1193 write(abs)
1194 err = 0
1194 err = 0
1195 return err
1195 return err
1196
1196
1197 @command('^clone',
1197 @command('^clone',
1198 [('U', 'noupdate', None,
1198 [('U', 'noupdate', None,
1199 _('the clone will include an empty working copy (only a repository)')),
1199 _('the clone will include an empty working copy (only a repository)')),
1200 ('u', 'updaterev', '', _('revision, tag or branch to check out'), _('REV')),
1200 ('u', 'updaterev', '', _('revision, tag or branch to check out'), _('REV')),
1201 ('r', 'rev', [], _('include the specified changeset'), _('REV')),
1201 ('r', 'rev', [], _('include the specified changeset'), _('REV')),
1202 ('b', 'branch', [], _('clone only the specified branch'), _('BRANCH')),
1202 ('b', 'branch', [], _('clone only the specified branch'), _('BRANCH')),
1203 ('', 'pull', None, _('use pull protocol to copy metadata')),
1203 ('', 'pull', None, _('use pull protocol to copy metadata')),
1204 ('', 'uncompressed', None, _('use uncompressed transfer (fast over LAN)')),
1204 ('', 'uncompressed', None, _('use uncompressed transfer (fast over LAN)')),
1205 ] + remoteopts,
1205 ] + remoteopts,
1206 _('[OPTION]... SOURCE [DEST]'))
1206 _('[OPTION]... SOURCE [DEST]'))
1207 def clone(ui, source, dest=None, **opts):
1207 def clone(ui, source, dest=None, **opts):
1208 """make a copy of an existing repository
1208 """make a copy of an existing repository
1209
1209
1210 Create a copy of an existing repository in a new directory.
1210 Create a copy of an existing repository in a new directory.
1211
1211
1212 If no destination directory name is specified, it defaults to the
1212 If no destination directory name is specified, it defaults to the
1213 basename of the source.
1213 basename of the source.
1214
1214
1215 The location of the source is added to the new repository's
1215 The location of the source is added to the new repository's
1216 ``.hg/hgrc`` file, as the default to be used for future pulls.
1216 ``.hg/hgrc`` file, as the default to be used for future pulls.
1217
1217
1218 Only local paths and ``ssh://`` URLs are supported as
1218 Only local paths and ``ssh://`` URLs are supported as
1219 destinations. For ``ssh://`` destinations, no working directory or
1219 destinations. For ``ssh://`` destinations, no working directory or
1220 ``.hg/hgrc`` will be created on the remote side.
1220 ``.hg/hgrc`` will be created on the remote side.
1221
1221
1222 To pull only a subset of changesets, specify one or more revisions
1222 To pull only a subset of changesets, specify one or more revisions
1223 identifiers with -r/--rev or branches with -b/--branch. The
1223 identifiers with -r/--rev or branches with -b/--branch. The
1224 resulting clone will contain only the specified changesets and
1224 resulting clone will contain only the specified changesets and
1225 their ancestors. These options (or 'clone src#rev dest') imply
1225 their ancestors. These options (or 'clone src#rev dest') imply
1226 --pull, even for local source repositories. Note that specifying a
1226 --pull, even for local source repositories. Note that specifying a
1227 tag will include the tagged changeset but not the changeset
1227 tag will include the tagged changeset but not the changeset
1228 containing the tag.
1228 containing the tag.
1229
1229
1230 If the source repository has a bookmark called '@' set, that
1230 If the source repository has a bookmark called '@' set, that
1231 revision will be checked out in the new repository by default.
1231 revision will be checked out in the new repository by default.
1232
1232
1233 To check out a particular version, use -u/--update, or
1233 To check out a particular version, use -u/--update, or
1234 -U/--noupdate to create a clone with no working directory.
1234 -U/--noupdate to create a clone with no working directory.
1235
1235
1236 .. container:: verbose
1236 .. container:: verbose
1237
1237
1238 For efficiency, hardlinks are used for cloning whenever the
1238 For efficiency, hardlinks are used for cloning whenever the
1239 source and destination are on the same filesystem (note this
1239 source and destination are on the same filesystem (note this
1240 applies only to the repository data, not to the working
1240 applies only to the repository data, not to the working
1241 directory). Some filesystems, such as AFS, implement hardlinking
1241 directory). Some filesystems, such as AFS, implement hardlinking
1242 incorrectly, but do not report errors. In these cases, use the
1242 incorrectly, but do not report errors. In these cases, use the
1243 --pull option to avoid hardlinking.
1243 --pull option to avoid hardlinking.
1244
1244
1245 In some cases, you can clone repositories and the working
1245 In some cases, you can clone repositories and the working
1246 directory using full hardlinks with ::
1246 directory using full hardlinks with ::
1247
1247
1248 $ cp -al REPO REPOCLONE
1248 $ cp -al REPO REPOCLONE
1249
1249
1250 This is the fastest way to clone, but it is not always safe. The
1250 This is the fastest way to clone, but it is not always safe. The
1251 operation is not atomic (making sure REPO is not modified during
1251 operation is not atomic (making sure REPO is not modified during
1252 the operation is up to you) and you have to make sure your
1252 the operation is up to you) and you have to make sure your
1253 editor breaks hardlinks (Emacs and most Linux Kernel tools do
1253 editor breaks hardlinks (Emacs and most Linux Kernel tools do
1254 so). Also, this is not compatible with certain extensions that
1254 so). Also, this is not compatible with certain extensions that
1255 place their metadata under the .hg directory, such as mq.
1255 place their metadata under the .hg directory, such as mq.
1256
1256
1257 Mercurial will update the working directory to the first applicable
1257 Mercurial will update the working directory to the first applicable
1258 revision from this list:
1258 revision from this list:
1259
1259
1260 a) null if -U or the source repository has no changesets
1260 a) null if -U or the source repository has no changesets
1261 b) if -u . and the source repository is local, the first parent of
1261 b) if -u . and the source repository is local, the first parent of
1262 the source repository's working directory
1262 the source repository's working directory
1263 c) the changeset specified with -u (if a branch name, this means the
1263 c) the changeset specified with -u (if a branch name, this means the
1264 latest head of that branch)
1264 latest head of that branch)
1265 d) the changeset specified with -r
1265 d) the changeset specified with -r
1266 e) the tipmost head specified with -b
1266 e) the tipmost head specified with -b
1267 f) the tipmost head specified with the url#branch source syntax
1267 f) the tipmost head specified with the url#branch source syntax
1268 g) the revision marked with the '@' bookmark, if present
1268 g) the revision marked with the '@' bookmark, if present
1269 h) the tipmost head of the default branch
1269 h) the tipmost head of the default branch
1270 i) tip
1270 i) tip
1271
1271
1272 Examples:
1272 Examples:
1273
1273
1274 - clone a remote repository to a new directory named hg/::
1274 - clone a remote repository to a new directory named hg/::
1275
1275
1276 hg clone http://selenic.com/hg
1276 hg clone http://selenic.com/hg
1277
1277
1278 - create a lightweight local clone::
1278 - create a lightweight local clone::
1279
1279
1280 hg clone project/ project-feature/
1280 hg clone project/ project-feature/
1281
1281
1282 - clone from an absolute path on an ssh server (note double-slash)::
1282 - clone from an absolute path on an ssh server (note double-slash)::
1283
1283
1284 hg clone ssh://user@server//home/projects/alpha/
1284 hg clone ssh://user@server//home/projects/alpha/
1285
1285
1286 - do a high-speed clone over a LAN while checking out a
1286 - do a high-speed clone over a LAN while checking out a
1287 specified version::
1287 specified version::
1288
1288
1289 hg clone --uncompressed http://server/repo -u 1.5
1289 hg clone --uncompressed http://server/repo -u 1.5
1290
1290
1291 - create a repository without changesets after a particular revision::
1291 - create a repository without changesets after a particular revision::
1292
1292
1293 hg clone -r 04e544 experimental/ good/
1293 hg clone -r 04e544 experimental/ good/
1294
1294
1295 - clone (and track) a particular named branch::
1295 - clone (and track) a particular named branch::
1296
1296
1297 hg clone http://selenic.com/hg#stable
1297 hg clone http://selenic.com/hg#stable
1298
1298
1299 See :hg:`help urls` for details on specifying URLs.
1299 See :hg:`help urls` for details on specifying URLs.
1300
1300
1301 Returns 0 on success.
1301 Returns 0 on success.
1302 """
1302 """
1303 if opts.get('noupdate') and opts.get('updaterev'):
1303 if opts.get('noupdate') and opts.get('updaterev'):
1304 raise util.Abort(_("cannot specify both --noupdate and --updaterev"))
1304 raise util.Abort(_("cannot specify both --noupdate and --updaterev"))
1305
1305
1306 r = hg.clone(ui, opts, source, dest,
1306 r = hg.clone(ui, opts, source, dest,
1307 pull=opts.get('pull'),
1307 pull=opts.get('pull'),
1308 stream=opts.get('uncompressed'),
1308 stream=opts.get('uncompressed'),
1309 rev=opts.get('rev'),
1309 rev=opts.get('rev'),
1310 update=opts.get('updaterev') or not opts.get('noupdate'),
1310 update=opts.get('updaterev') or not opts.get('noupdate'),
1311 branch=opts.get('branch'))
1311 branch=opts.get('branch'))
1312
1312
1313 return r is None
1313 return r is None
1314
1314
1315 @command('^commit|ci',
1315 @command('^commit|ci',
1316 [('A', 'addremove', None,
1316 [('A', 'addremove', None,
1317 _('mark new/missing files as added/removed before committing')),
1317 _('mark new/missing files as added/removed before committing')),
1318 ('', 'close-branch', None,
1318 ('', 'close-branch', None,
1319 _('mark a branch as closed, hiding it from the branch list')),
1319 _('mark a branch as closed, hiding it from the branch list')),
1320 ('', 'amend', None, _('amend the parent of the working dir')),
1320 ('', 'amend', None, _('amend the parent of the working dir')),
1321 ('s', 'secret', None, _('use the secret phase for committing')),
1321 ('s', 'secret', None, _('use the secret phase for committing')),
1322 ] + walkopts + commitopts + commitopts2 + subrepoopts,
1322 ] + walkopts + commitopts + commitopts2 + subrepoopts,
1323 _('[OPTION]... [FILE]...'))
1323 _('[OPTION]... [FILE]...'))
1324 def commit(ui, repo, *pats, **opts):
1324 def commit(ui, repo, *pats, **opts):
1325 """commit the specified files or all outstanding changes
1325 """commit the specified files or all outstanding changes
1326
1326
1327 Commit changes to the given files into the repository. Unlike a
1327 Commit changes to the given files into the repository. Unlike a
1328 centralized SCM, this operation is a local operation. See
1328 centralized SCM, this operation is a local operation. See
1329 :hg:`push` for a way to actively distribute your changes.
1329 :hg:`push` for a way to actively distribute your changes.
1330
1330
1331 If a list of files is omitted, all changes reported by :hg:`status`
1331 If a list of files is omitted, all changes reported by :hg:`status`
1332 will be committed.
1332 will be committed.
1333
1333
1334 If you are committing the result of a merge, do not provide any
1334 If you are committing the result of a merge, do not provide any
1335 filenames or -I/-X filters.
1335 filenames or -I/-X filters.
1336
1336
1337 If no commit message is specified, Mercurial starts your
1337 If no commit message is specified, Mercurial starts your
1338 configured editor where you can enter a message. In case your
1338 configured editor where you can enter a message. In case your
1339 commit fails, you will find a backup of your message in
1339 commit fails, you will find a backup of your message in
1340 ``.hg/last-message.txt``.
1340 ``.hg/last-message.txt``.
1341
1341
1342 The --amend flag can be used to amend the parent of the
1342 The --amend flag can be used to amend the parent of the
1343 working directory with a new commit that contains the changes
1343 working directory with a new commit that contains the changes
1344 in the parent in addition to those currently reported by :hg:`status`,
1344 in the parent in addition to those currently reported by :hg:`status`,
1345 if there are any. The old commit is stored in a backup bundle in
1345 if there are any. The old commit is stored in a backup bundle in
1346 ``.hg/strip-backup`` (see :hg:`help bundle` and :hg:`help unbundle`
1346 ``.hg/strip-backup`` (see :hg:`help bundle` and :hg:`help unbundle`
1347 on how to restore it).
1347 on how to restore it).
1348
1348
1349 Message, user and date are taken from the amended commit unless
1349 Message, user and date are taken from the amended commit unless
1350 specified. When a message isn't specified on the command line,
1350 specified. When a message isn't specified on the command line,
1351 the editor will open with the message of the amended commit.
1351 the editor will open with the message of the amended commit.
1352
1352
1353 It is not possible to amend public changesets (see :hg:`help phases`)
1353 It is not possible to amend public changesets (see :hg:`help phases`)
1354 or changesets that have children.
1354 or changesets that have children.
1355
1355
1356 See :hg:`help dates` for a list of formats valid for -d/--date.
1356 See :hg:`help dates` for a list of formats valid for -d/--date.
1357
1357
1358 Returns 0 on success, 1 if nothing changed.
1358 Returns 0 on success, 1 if nothing changed.
1359 """
1359 """
1360 if opts.get('subrepos'):
1360 if opts.get('subrepos'):
1361 if opts.get('amend'):
1361 if opts.get('amend'):
1362 raise util.Abort(_('cannot amend with --subrepos'))
1362 raise util.Abort(_('cannot amend with --subrepos'))
1363 # Let --subrepos on the command line override config setting.
1363 # Let --subrepos on the command line override config setting.
1364 ui.setconfig('ui', 'commitsubrepos', True)
1364 ui.setconfig('ui', 'commitsubrepos', True)
1365
1365
1366 # Save this for restoring it later
1366 # Save this for restoring it later
1367 oldcommitphase = ui.config('phases', 'new-commit')
1367 oldcommitphase = ui.config('phases', 'new-commit')
1368
1368
1369 cmdutil.checkunfinished(repo, commit=True)
1369 cmdutil.checkunfinished(repo, commit=True)
1370
1370
1371 branch = repo[None].branch()
1371 branch = repo[None].branch()
1372 bheads = repo.branchheads(branch)
1372 bheads = repo.branchheads(branch)
1373
1373
1374 extra = {}
1374 extra = {}
1375 if opts.get('close_branch'):
1375 if opts.get('close_branch'):
1376 extra['close'] = 1
1376 extra['close'] = 1
1377
1377
1378 if not bheads:
1378 if not bheads:
1379 raise util.Abort(_('can only close branch heads'))
1379 raise util.Abort(_('can only close branch heads'))
1380 elif opts.get('amend'):
1380 elif opts.get('amend'):
1381 if repo.parents()[0].p1().branch() != branch and \
1381 if repo.parents()[0].p1().branch() != branch and \
1382 repo.parents()[0].p2().branch() != branch:
1382 repo.parents()[0].p2().branch() != branch:
1383 raise util.Abort(_('can only close branch heads'))
1383 raise util.Abort(_('can only close branch heads'))
1384
1384
1385 if opts.get('amend'):
1385 if opts.get('amend'):
1386 if ui.configbool('ui', 'commitsubrepos'):
1386 if ui.configbool('ui', 'commitsubrepos'):
1387 raise util.Abort(_('cannot amend with ui.commitsubrepos enabled'))
1387 raise util.Abort(_('cannot amend with ui.commitsubrepos enabled'))
1388
1388
1389 old = repo['.']
1389 old = repo['.']
1390 if old.phase() == phases.public:
1390 if old.phase() == phases.public:
1391 raise util.Abort(_('cannot amend public changesets'))
1391 raise util.Abort(_('cannot amend public changesets'))
1392 if len(repo[None].parents()) > 1:
1392 if len(repo[None].parents()) > 1:
1393 raise util.Abort(_('cannot amend while merging'))
1393 raise util.Abort(_('cannot amend while merging'))
1394 if (not obsolete._enabled) and old.children():
1394 if (not obsolete._enabled) and old.children():
1395 raise util.Abort(_('cannot amend changeset with children'))
1395 raise util.Abort(_('cannot amend changeset with children'))
1396
1396
1397 e = cmdutil.commiteditor
1397 e = cmdutil.commiteditor
1398 if opts.get('force_editor'):
1398 if opts.get('force_editor'):
1399 e = cmdutil.commitforceeditor
1399 e = cmdutil.commitforceeditor
1400
1400
1401 # commitfunc is used only for temporary amend commit by cmdutil.amend
1401 # commitfunc is used only for temporary amend commit by cmdutil.amend
1402 def commitfunc(ui, repo, message, match, opts):
1402 def commitfunc(ui, repo, message, match, opts):
1403 editor = e
1403 editor = e
1404 # message contains text from -m or -l, if it's empty,
1404 # message contains text from -m or -l, if it's empty,
1405 # open the editor with the old message
1405 # open the editor with the old message
1406 if not message:
1406 if not message:
1407 message = old.description()
1407 message = old.description()
1408 editor = cmdutil.commitforceeditor
1408 editor = cmdutil.commitforceeditor
1409 return repo.commit(message,
1409 return repo.commit(message,
1410 opts.get('user') or old.user(),
1410 opts.get('user') or old.user(),
1411 opts.get('date') or old.date(),
1411 opts.get('date') or old.date(),
1412 match,
1412 match,
1413 editor=editor,
1413 editor=editor,
1414 extra=extra)
1414 extra=extra)
1415
1415
1416 current = repo._bookmarkcurrent
1416 current = repo._bookmarkcurrent
1417 marks = old.bookmarks()
1417 marks = old.bookmarks()
1418 node = cmdutil.amend(ui, repo, commitfunc, old, extra, pats, opts)
1418 node = cmdutil.amend(ui, repo, commitfunc, old, extra, pats, opts)
1419 if node == old.node():
1419 if node == old.node():
1420 ui.status(_("nothing changed\n"))
1420 ui.status(_("nothing changed\n"))
1421 return 1
1421 return 1
1422 elif marks:
1422 elif marks:
1423 ui.debug('moving bookmarks %r from %s to %s\n' %
1423 ui.debug('moving bookmarks %r from %s to %s\n' %
1424 (marks, old.hex(), hex(node)))
1424 (marks, old.hex(), hex(node)))
1425 newmarks = repo._bookmarks
1425 newmarks = repo._bookmarks
1426 for bm in marks:
1426 for bm in marks:
1427 newmarks[bm] = node
1427 newmarks[bm] = node
1428 if bm == current:
1428 if bm == current:
1429 bookmarks.setcurrent(repo, bm)
1429 bookmarks.setcurrent(repo, bm)
1430 newmarks.write()
1430 newmarks.write()
1431 else:
1431 else:
1432 e = cmdutil.commiteditor
1432 e = cmdutil.commiteditor
1433 if opts.get('force_editor'):
1433 if opts.get('force_editor'):
1434 e = cmdutil.commitforceeditor
1434 e = cmdutil.commitforceeditor
1435
1435
1436 def commitfunc(ui, repo, message, match, opts):
1436 def commitfunc(ui, repo, message, match, opts):
1437 try:
1437 try:
1438 if opts.get('secret'):
1438 if opts.get('secret'):
1439 ui.setconfig('phases', 'new-commit', 'secret')
1439 ui.setconfig('phases', 'new-commit', 'secret')
1440 # Propagate to subrepos
1440 # Propagate to subrepos
1441 repo.baseui.setconfig('phases', 'new-commit', 'secret')
1441 repo.baseui.setconfig('phases', 'new-commit', 'secret')
1442
1442
1443 return repo.commit(message, opts.get('user'), opts.get('date'),
1443 return repo.commit(message, opts.get('user'), opts.get('date'),
1444 match, editor=e, extra=extra)
1444 match, editor=e, extra=extra)
1445 finally:
1445 finally:
1446 ui.setconfig('phases', 'new-commit', oldcommitphase)
1446 ui.setconfig('phases', 'new-commit', oldcommitphase)
1447 repo.baseui.setconfig('phases', 'new-commit', oldcommitphase)
1447 repo.baseui.setconfig('phases', 'new-commit', oldcommitphase)
1448
1448
1449
1449
1450 node = cmdutil.commit(ui, repo, commitfunc, pats, opts)
1450 node = cmdutil.commit(ui, repo, commitfunc, pats, opts)
1451
1451
1452 if not node:
1452 if not node:
1453 stat = repo.status(match=scmutil.match(repo[None], pats, opts))
1453 stat = repo.status(match=scmutil.match(repo[None], pats, opts))
1454 if stat[3]:
1454 if stat[3]:
1455 ui.status(_("nothing changed (%d missing files, see "
1455 ui.status(_("nothing changed (%d missing files, see "
1456 "'hg status')\n") % len(stat[3]))
1456 "'hg status')\n") % len(stat[3]))
1457 else:
1457 else:
1458 ui.status(_("nothing changed\n"))
1458 ui.status(_("nothing changed\n"))
1459 return 1
1459 return 1
1460
1460
1461 cmdutil.commitstatus(repo, node, branch, bheads, opts)
1461 cmdutil.commitstatus(repo, node, branch, bheads, opts)
1462
1462
1463 @command('config|showconfig|debugconfig',
1463 @command('config|showconfig|debugconfig',
1464 [('u', 'untrusted', None, _('show untrusted configuration options')),
1464 [('u', 'untrusted', None, _('show untrusted configuration options')),
1465 ('e', 'edit', None, _('start editor'))],
1465 ('e', 'edit', None, _('edit user config')),
1466 _('[-u] [NAME]...'))
1466 ('l', 'local', None, _('edit repository config')),
1467 ('g', 'global', None, _('edit global config'))],
1468 _('[-u] [NAME]...'))
1467 def config(ui, repo, *values, **opts):
1469 def config(ui, repo, *values, **opts):
1468 """show combined config settings from all hgrc files
1470 """show combined config settings from all hgrc files
1469
1471
1470 With no arguments, print names and values of all config items.
1472 With no arguments, print names and values of all config items.
1471
1473
1472 With one argument of the form section.name, print just the value
1474 With one argument of the form section.name, print just the value
1473 of that config item.
1475 of that config item.
1474
1476
1475 With multiple arguments, print names and values of all config
1477 With multiple arguments, print names and values of all config
1476 items with matching section names.
1478 items with matching section names.
1477
1479
1478 With --debug, the source (filename and line number) is printed
1480 With --debug, the source (filename and line number) is printed
1479 for each config item.
1481 for each config item.
1480
1482
1481 Returns 0 on success.
1483 Returns 0 on success.
1482 """
1484 """
1483
1485
1484 if opts.get('edit'):
1486 if opts.get('edit') or opts.get('local') or opts.get('global'):
1485 paths = scmutil.userrcpath()
1487 if opts.get('local') and opts.get('global'):
1488 raise util.Abort(_("can't use --local and --global together"))
1489
1490 if opts.get('local'):
1491 if not repo:
1492 raise util.Abort(_("can't use --local outside a repository"))
1493 paths = [repo.join('hgrc')]
1494 elif opts.get('global'):
1495 paths = scmutil.systemrcpath()
1496 else:
1497 paths = scmutil.userrcpath()
1498
1486 for f in paths:
1499 for f in paths:
1487 if os.path.exists(f):
1500 if os.path.exists(f):
1488 break
1501 break
1489 else:
1502 else:
1490 f = paths[0]
1503 f = paths[0]
1491 fp = open(f, "w")
1504 fp = open(f, "w")
1492 fp.write(
1505 fp.write(
1493 '# example config (see "hg help config" for more info)\n'
1506 '# example config (see "hg help config" for more info)\n'
1494 '\n'
1507 '\n'
1495 '[ui]\n'
1508 '[ui]\n'
1496 '# name and email, e.g.\n'
1509 '# name and email, e.g.\n'
1497 '# username = Jane Doe <jdoe@example.com>\n'
1510 '# username = Jane Doe <jdoe@example.com>\n'
1498 'username =\n'
1511 'username =\n'
1499 '\n'
1512 '\n'
1500 '[extensions]\n'
1513 '[extensions]\n'
1501 '# uncomment these lines to enable some popular extensions\n'
1514 '# uncomment these lines to enable some popular extensions\n'
1502 '# (see "hg help extensions" for more info)\n'
1515 '# (see "hg help extensions" for more info)\n'
1503 '# pager =\n'
1516 '# pager =\n'
1504 '# progress =\n'
1517 '# progress =\n'
1505 '# color =\n')
1518 '# color =\n')
1506 fp.close()
1519 fp.close()
1507
1520
1508 editor = ui.geteditor()
1521 editor = ui.geteditor()
1509 util.system("%s \"%s\"" % (editor, f),
1522 util.system("%s \"%s\"" % (editor, f),
1510 onerr=util.Abort, errprefix=_("edit failed"),
1523 onerr=util.Abort, errprefix=_("edit failed"),
1511 out=ui.fout)
1524 out=ui.fout)
1512 return
1525 return
1513
1526
1514 for f in scmutil.rcpath():
1527 for f in scmutil.rcpath():
1515 ui.debug('read config from: %s\n' % f)
1528 ui.debug('read config from: %s\n' % f)
1516 untrusted = bool(opts.get('untrusted'))
1529 untrusted = bool(opts.get('untrusted'))
1517 if values:
1530 if values:
1518 sections = [v for v in values if '.' not in v]
1531 sections = [v for v in values if '.' not in v]
1519 items = [v for v in values if '.' in v]
1532 items = [v for v in values if '.' in v]
1520 if len(items) > 1 or items and sections:
1533 if len(items) > 1 or items and sections:
1521 raise util.Abort(_('only one config item permitted'))
1534 raise util.Abort(_('only one config item permitted'))
1522 for section, name, value in ui.walkconfig(untrusted=untrusted):
1535 for section, name, value in ui.walkconfig(untrusted=untrusted):
1523 value = str(value).replace('\n', '\\n')
1536 value = str(value).replace('\n', '\\n')
1524 sectname = section + '.' + name
1537 sectname = section + '.' + name
1525 if values:
1538 if values:
1526 for v in values:
1539 for v in values:
1527 if v == section:
1540 if v == section:
1528 ui.debug('%s: ' %
1541 ui.debug('%s: ' %
1529 ui.configsource(section, name, untrusted))
1542 ui.configsource(section, name, untrusted))
1530 ui.write('%s=%s\n' % (sectname, value))
1543 ui.write('%s=%s\n' % (sectname, value))
1531 elif v == sectname:
1544 elif v == sectname:
1532 ui.debug('%s: ' %
1545 ui.debug('%s: ' %
1533 ui.configsource(section, name, untrusted))
1546 ui.configsource(section, name, untrusted))
1534 ui.write(value, '\n')
1547 ui.write(value, '\n')
1535 else:
1548 else:
1536 ui.debug('%s: ' %
1549 ui.debug('%s: ' %
1537 ui.configsource(section, name, untrusted))
1550 ui.configsource(section, name, untrusted))
1538 ui.write('%s=%s\n' % (sectname, value))
1551 ui.write('%s=%s\n' % (sectname, value))
1539
1552
1540 @command('copy|cp',
1553 @command('copy|cp',
1541 [('A', 'after', None, _('record a copy that has already occurred')),
1554 [('A', 'after', None, _('record a copy that has already occurred')),
1542 ('f', 'force', None, _('forcibly copy over an existing managed file')),
1555 ('f', 'force', None, _('forcibly copy over an existing managed file')),
1543 ] + walkopts + dryrunopts,
1556 ] + walkopts + dryrunopts,
1544 _('[OPTION]... [SOURCE]... DEST'))
1557 _('[OPTION]... [SOURCE]... DEST'))
1545 def copy(ui, repo, *pats, **opts):
1558 def copy(ui, repo, *pats, **opts):
1546 """mark files as copied for the next commit
1559 """mark files as copied for the next commit
1547
1560
1548 Mark dest as having copies of source files. If dest is a
1561 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,
1562 directory, copies are put in that directory. If dest is a file,
1550 the source must be a single file.
1563 the source must be a single file.
1551
1564
1552 By default, this command copies the contents of files as they
1565 By default, this command copies the contents of files as they
1553 exist in the working directory. If invoked with -A/--after, the
1566 exist in the working directory. If invoked with -A/--after, the
1554 operation is recorded, but no copying is performed.
1567 operation is recorded, but no copying is performed.
1555
1568
1556 This command takes effect with the next commit. To undo a copy
1569 This command takes effect with the next commit. To undo a copy
1557 before that, see :hg:`revert`.
1570 before that, see :hg:`revert`.
1558
1571
1559 Returns 0 on success, 1 if errors are encountered.
1572 Returns 0 on success, 1 if errors are encountered.
1560 """
1573 """
1561 wlock = repo.wlock(False)
1574 wlock = repo.wlock(False)
1562 try:
1575 try:
1563 return cmdutil.copy(ui, repo, pats, opts)
1576 return cmdutil.copy(ui, repo, pats, opts)
1564 finally:
1577 finally:
1565 wlock.release()
1578 wlock.release()
1566
1579
1567 @command('debugancestor', [], _('[INDEX] REV1 REV2'))
1580 @command('debugancestor', [], _('[INDEX] REV1 REV2'))
1568 def debugancestor(ui, repo, *args):
1581 def debugancestor(ui, repo, *args):
1569 """find the ancestor revision of two revisions in a given index"""
1582 """find the ancestor revision of two revisions in a given index"""
1570 if len(args) == 3:
1583 if len(args) == 3:
1571 index, rev1, rev2 = args
1584 index, rev1, rev2 = args
1572 r = revlog.revlog(scmutil.opener(os.getcwd(), audit=False), index)
1585 r = revlog.revlog(scmutil.opener(os.getcwd(), audit=False), index)
1573 lookup = r.lookup
1586 lookup = r.lookup
1574 elif len(args) == 2:
1587 elif len(args) == 2:
1575 if not repo:
1588 if not repo:
1576 raise util.Abort(_("there is no Mercurial repository here "
1589 raise util.Abort(_("there is no Mercurial repository here "
1577 "(.hg not found)"))
1590 "(.hg not found)"))
1578 rev1, rev2 = args
1591 rev1, rev2 = args
1579 r = repo.changelog
1592 r = repo.changelog
1580 lookup = repo.lookup
1593 lookup = repo.lookup
1581 else:
1594 else:
1582 raise util.Abort(_('either two or three arguments required'))
1595 raise util.Abort(_('either two or three arguments required'))
1583 a = r.ancestor(lookup(rev1), lookup(rev2))
1596 a = r.ancestor(lookup(rev1), lookup(rev2))
1584 ui.write("%d:%s\n" % (r.rev(a), hex(a)))
1597 ui.write("%d:%s\n" % (r.rev(a), hex(a)))
1585
1598
1586 @command('debugbuilddag',
1599 @command('debugbuilddag',
1587 [('m', 'mergeable-file', None, _('add single file mergeable changes')),
1600 [('m', 'mergeable-file', None, _('add single file mergeable changes')),
1588 ('o', 'overwritten-file', None, _('add single file all revs overwrite')),
1601 ('o', 'overwritten-file', None, _('add single file all revs overwrite')),
1589 ('n', 'new-file', None, _('add new file at each rev'))],
1602 ('n', 'new-file', None, _('add new file at each rev'))],
1590 _('[OPTION]... [TEXT]'))
1603 _('[OPTION]... [TEXT]'))
1591 def debugbuilddag(ui, repo, text=None,
1604 def debugbuilddag(ui, repo, text=None,
1592 mergeable_file=False,
1605 mergeable_file=False,
1593 overwritten_file=False,
1606 overwritten_file=False,
1594 new_file=False):
1607 new_file=False):
1595 """builds a repo with a given DAG from scratch in the current empty repo
1608 """builds a repo with a given DAG from scratch in the current empty repo
1596
1609
1597 The description of the DAG is read from stdin if not given on the
1610 The description of the DAG is read from stdin if not given on the
1598 command line.
1611 command line.
1599
1612
1600 Elements:
1613 Elements:
1601
1614
1602 - "+n" is a linear run of n nodes based on the current default parent
1615 - "+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
1616 - "." is a single node based on the current default parent
1604 - "$" resets the default parent to null (implied at the start);
1617 - "$" resets the default parent to null (implied at the start);
1605 otherwise the default parent is always the last node created
1618 otherwise the default parent is always the last node created
1606 - "<p" sets the default parent to the backref p
1619 - "<p" sets the default parent to the backref p
1607 - "*p" is a fork at parent p, which is a backref
1620 - "*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
1621 - "*p1/p2" is a merge of parents p1 and p2, which are backrefs
1609 - "/p2" is a merge of the preceding node and p2
1622 - "/p2" is a merge of the preceding node and p2
1610 - ":tag" defines a local tag for the preceding node
1623 - ":tag" defines a local tag for the preceding node
1611 - "@branch" sets the named branch for subsequent nodes
1624 - "@branch" sets the named branch for subsequent nodes
1612 - "#...\\n" is a comment up to the end of the line
1625 - "#...\\n" is a comment up to the end of the line
1613
1626
1614 Whitespace between the above elements is ignored.
1627 Whitespace between the above elements is ignored.
1615
1628
1616 A backref is either
1629 A backref is either
1617
1630
1618 - a number n, which references the node curr-n, where curr is the current
1631 - a number n, which references the node curr-n, where curr is the current
1619 node, or
1632 node, or
1620 - the name of a local tag you placed earlier using ":tag", or
1633 - the name of a local tag you placed earlier using ":tag", or
1621 - empty to denote the default parent.
1634 - empty to denote the default parent.
1622
1635
1623 All string valued-elements are either strictly alphanumeric, or must
1636 All string valued-elements are either strictly alphanumeric, or must
1624 be enclosed in double quotes ("..."), with "\\" as escape character.
1637 be enclosed in double quotes ("..."), with "\\" as escape character.
1625 """
1638 """
1626
1639
1627 if text is None:
1640 if text is None:
1628 ui.status(_("reading DAG from stdin\n"))
1641 ui.status(_("reading DAG from stdin\n"))
1629 text = ui.fin.read()
1642 text = ui.fin.read()
1630
1643
1631 cl = repo.changelog
1644 cl = repo.changelog
1632 if len(cl) > 0:
1645 if len(cl) > 0:
1633 raise util.Abort(_('repository is not empty'))
1646 raise util.Abort(_('repository is not empty'))
1634
1647
1635 # determine number of revs in DAG
1648 # determine number of revs in DAG
1636 total = 0
1649 total = 0
1637 for type, data in dagparser.parsedag(text):
1650 for type, data in dagparser.parsedag(text):
1638 if type == 'n':
1651 if type == 'n':
1639 total += 1
1652 total += 1
1640
1653
1641 if mergeable_file:
1654 if mergeable_file:
1642 linesperrev = 2
1655 linesperrev = 2
1643 # make a file with k lines per rev
1656 # make a file with k lines per rev
1644 initialmergedlines = [str(i) for i in xrange(0, total * linesperrev)]
1657 initialmergedlines = [str(i) for i in xrange(0, total * linesperrev)]
1645 initialmergedlines.append("")
1658 initialmergedlines.append("")
1646
1659
1647 tags = []
1660 tags = []
1648
1661
1649 lock = tr = None
1662 lock = tr = None
1650 try:
1663 try:
1651 lock = repo.lock()
1664 lock = repo.lock()
1652 tr = repo.transaction("builddag")
1665 tr = repo.transaction("builddag")
1653
1666
1654 at = -1
1667 at = -1
1655 atbranch = 'default'
1668 atbranch = 'default'
1656 nodeids = []
1669 nodeids = []
1657 id = 0
1670 id = 0
1658 ui.progress(_('building'), id, unit=_('revisions'), total=total)
1671 ui.progress(_('building'), id, unit=_('revisions'), total=total)
1659 for type, data in dagparser.parsedag(text):
1672 for type, data in dagparser.parsedag(text):
1660 if type == 'n':
1673 if type == 'n':
1661 ui.note(('node %s\n' % str(data)))
1674 ui.note(('node %s\n' % str(data)))
1662 id, ps = data
1675 id, ps = data
1663
1676
1664 files = []
1677 files = []
1665 fctxs = {}
1678 fctxs = {}
1666
1679
1667 p2 = None
1680 p2 = None
1668 if mergeable_file:
1681 if mergeable_file:
1669 fn = "mf"
1682 fn = "mf"
1670 p1 = repo[ps[0]]
1683 p1 = repo[ps[0]]
1671 if len(ps) > 1:
1684 if len(ps) > 1:
1672 p2 = repo[ps[1]]
1685 p2 = repo[ps[1]]
1673 pa = p1.ancestor(p2)
1686 pa = p1.ancestor(p2)
1674 base, local, other = [x[fn].data() for x in (pa, p1,
1687 base, local, other = [x[fn].data() for x in (pa, p1,
1675 p2)]
1688 p2)]
1676 m3 = simplemerge.Merge3Text(base, local, other)
1689 m3 = simplemerge.Merge3Text(base, local, other)
1677 ml = [l.strip() for l in m3.merge_lines()]
1690 ml = [l.strip() for l in m3.merge_lines()]
1678 ml.append("")
1691 ml.append("")
1679 elif at > 0:
1692 elif at > 0:
1680 ml = p1[fn].data().split("\n")
1693 ml = p1[fn].data().split("\n")
1681 else:
1694 else:
1682 ml = initialmergedlines
1695 ml = initialmergedlines
1683 ml[id * linesperrev] += " r%i" % id
1696 ml[id * linesperrev] += " r%i" % id
1684 mergedtext = "\n".join(ml)
1697 mergedtext = "\n".join(ml)
1685 files.append(fn)
1698 files.append(fn)
1686 fctxs[fn] = context.memfilectx(fn, mergedtext)
1699 fctxs[fn] = context.memfilectx(fn, mergedtext)
1687
1700
1688 if overwritten_file:
1701 if overwritten_file:
1689 fn = "of"
1702 fn = "of"
1690 files.append(fn)
1703 files.append(fn)
1691 fctxs[fn] = context.memfilectx(fn, "r%i\n" % id)
1704 fctxs[fn] = context.memfilectx(fn, "r%i\n" % id)
1692
1705
1693 if new_file:
1706 if new_file:
1694 fn = "nf%i" % id
1707 fn = "nf%i" % id
1695 files.append(fn)
1708 files.append(fn)
1696 fctxs[fn] = context.memfilectx(fn, "r%i\n" % id)
1709 fctxs[fn] = context.memfilectx(fn, "r%i\n" % id)
1697 if len(ps) > 1:
1710 if len(ps) > 1:
1698 if not p2:
1711 if not p2:
1699 p2 = repo[ps[1]]
1712 p2 = repo[ps[1]]
1700 for fn in p2:
1713 for fn in p2:
1701 if fn.startswith("nf"):
1714 if fn.startswith("nf"):
1702 files.append(fn)
1715 files.append(fn)
1703 fctxs[fn] = p2[fn]
1716 fctxs[fn] = p2[fn]
1704
1717
1705 def fctxfn(repo, cx, path):
1718 def fctxfn(repo, cx, path):
1706 return fctxs.get(path)
1719 return fctxs.get(path)
1707
1720
1708 if len(ps) == 0 or ps[0] < 0:
1721 if len(ps) == 0 or ps[0] < 0:
1709 pars = [None, None]
1722 pars = [None, None]
1710 elif len(ps) == 1:
1723 elif len(ps) == 1:
1711 pars = [nodeids[ps[0]], None]
1724 pars = [nodeids[ps[0]], None]
1712 else:
1725 else:
1713 pars = [nodeids[p] for p in ps]
1726 pars = [nodeids[p] for p in ps]
1714 cx = context.memctx(repo, pars, "r%i" % id, files, fctxfn,
1727 cx = context.memctx(repo, pars, "r%i" % id, files, fctxfn,
1715 date=(id, 0),
1728 date=(id, 0),
1716 user="debugbuilddag",
1729 user="debugbuilddag",
1717 extra={'branch': atbranch})
1730 extra={'branch': atbranch})
1718 nodeid = repo.commitctx(cx)
1731 nodeid = repo.commitctx(cx)
1719 nodeids.append(nodeid)
1732 nodeids.append(nodeid)
1720 at = id
1733 at = id
1721 elif type == 'l':
1734 elif type == 'l':
1722 id, name = data
1735 id, name = data
1723 ui.note(('tag %s\n' % name))
1736 ui.note(('tag %s\n' % name))
1724 tags.append("%s %s\n" % (hex(repo.changelog.node(id)), name))
1737 tags.append("%s %s\n" % (hex(repo.changelog.node(id)), name))
1725 elif type == 'a':
1738 elif type == 'a':
1726 ui.note(('branch %s\n' % data))
1739 ui.note(('branch %s\n' % data))
1727 atbranch = data
1740 atbranch = data
1728 ui.progress(_('building'), id, unit=_('revisions'), total=total)
1741 ui.progress(_('building'), id, unit=_('revisions'), total=total)
1729 tr.close()
1742 tr.close()
1730
1743
1731 if tags:
1744 if tags:
1732 repo.opener.write("localtags", "".join(tags))
1745 repo.opener.write("localtags", "".join(tags))
1733 finally:
1746 finally:
1734 ui.progress(_('building'), None)
1747 ui.progress(_('building'), None)
1735 release(tr, lock)
1748 release(tr, lock)
1736
1749
1737 @command('debugbundle', [('a', 'all', None, _('show all details'))], _('FILE'))
1750 @command('debugbundle', [('a', 'all', None, _('show all details'))], _('FILE'))
1738 def debugbundle(ui, bundlepath, all=None, **opts):
1751 def debugbundle(ui, bundlepath, all=None, **opts):
1739 """lists the contents of a bundle"""
1752 """lists the contents of a bundle"""
1740 f = hg.openpath(ui, bundlepath)
1753 f = hg.openpath(ui, bundlepath)
1741 try:
1754 try:
1742 gen = changegroup.readbundle(f, bundlepath)
1755 gen = changegroup.readbundle(f, bundlepath)
1743 if all:
1756 if all:
1744 ui.write(("format: id, p1, p2, cset, delta base, len(delta)\n"))
1757 ui.write(("format: id, p1, p2, cset, delta base, len(delta)\n"))
1745
1758
1746 def showchunks(named):
1759 def showchunks(named):
1747 ui.write("\n%s\n" % named)
1760 ui.write("\n%s\n" % named)
1748 chain = None
1761 chain = None
1749 while True:
1762 while True:
1750 chunkdata = gen.deltachunk(chain)
1763 chunkdata = gen.deltachunk(chain)
1751 if not chunkdata:
1764 if not chunkdata:
1752 break
1765 break
1753 node = chunkdata['node']
1766 node = chunkdata['node']
1754 p1 = chunkdata['p1']
1767 p1 = chunkdata['p1']
1755 p2 = chunkdata['p2']
1768 p2 = chunkdata['p2']
1756 cs = chunkdata['cs']
1769 cs = chunkdata['cs']
1757 deltabase = chunkdata['deltabase']
1770 deltabase = chunkdata['deltabase']
1758 delta = chunkdata['delta']
1771 delta = chunkdata['delta']
1759 ui.write("%s %s %s %s %s %s\n" %
1772 ui.write("%s %s %s %s %s %s\n" %
1760 (hex(node), hex(p1), hex(p2),
1773 (hex(node), hex(p1), hex(p2),
1761 hex(cs), hex(deltabase), len(delta)))
1774 hex(cs), hex(deltabase), len(delta)))
1762 chain = node
1775 chain = node
1763
1776
1764 chunkdata = gen.changelogheader()
1777 chunkdata = gen.changelogheader()
1765 showchunks("changelog")
1778 showchunks("changelog")
1766 chunkdata = gen.manifestheader()
1779 chunkdata = gen.manifestheader()
1767 showchunks("manifest")
1780 showchunks("manifest")
1768 while True:
1781 while True:
1769 chunkdata = gen.filelogheader()
1782 chunkdata = gen.filelogheader()
1770 if not chunkdata:
1783 if not chunkdata:
1771 break
1784 break
1772 fname = chunkdata['filename']
1785 fname = chunkdata['filename']
1773 showchunks(fname)
1786 showchunks(fname)
1774 else:
1787 else:
1775 chunkdata = gen.changelogheader()
1788 chunkdata = gen.changelogheader()
1776 chain = None
1789 chain = None
1777 while True:
1790 while True:
1778 chunkdata = gen.deltachunk(chain)
1791 chunkdata = gen.deltachunk(chain)
1779 if not chunkdata:
1792 if not chunkdata:
1780 break
1793 break
1781 node = chunkdata['node']
1794 node = chunkdata['node']
1782 ui.write("%s\n" % hex(node))
1795 ui.write("%s\n" % hex(node))
1783 chain = node
1796 chain = node
1784 finally:
1797 finally:
1785 f.close()
1798 f.close()
1786
1799
1787 @command('debugcheckstate', [], '')
1800 @command('debugcheckstate', [], '')
1788 def debugcheckstate(ui, repo):
1801 def debugcheckstate(ui, repo):
1789 """validate the correctness of the current dirstate"""
1802 """validate the correctness of the current dirstate"""
1790 parent1, parent2 = repo.dirstate.parents()
1803 parent1, parent2 = repo.dirstate.parents()
1791 m1 = repo[parent1].manifest()
1804 m1 = repo[parent1].manifest()
1792 m2 = repo[parent2].manifest()
1805 m2 = repo[parent2].manifest()
1793 errors = 0
1806 errors = 0
1794 for f in repo.dirstate:
1807 for f in repo.dirstate:
1795 state = repo.dirstate[f]
1808 state = repo.dirstate[f]
1796 if state in "nr" and f not in m1:
1809 if state in "nr" and f not in m1:
1797 ui.warn(_("%s in state %s, but not in manifest1\n") % (f, state))
1810 ui.warn(_("%s in state %s, but not in manifest1\n") % (f, state))
1798 errors += 1
1811 errors += 1
1799 if state in "a" and f in m1:
1812 if state in "a" and f in m1:
1800 ui.warn(_("%s in state %s, but also in manifest1\n") % (f, state))
1813 ui.warn(_("%s in state %s, but also in manifest1\n") % (f, state))
1801 errors += 1
1814 errors += 1
1802 if state in "m" and f not in m1 and f not in m2:
1815 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") %
1816 ui.warn(_("%s in state %s, but not in either manifest\n") %
1804 (f, state))
1817 (f, state))
1805 errors += 1
1818 errors += 1
1806 for f in m1:
1819 for f in m1:
1807 state = repo.dirstate[f]
1820 state = repo.dirstate[f]
1808 if state not in "nrm":
1821 if state not in "nrm":
1809 ui.warn(_("%s in manifest1, but listed as state %s") % (f, state))
1822 ui.warn(_("%s in manifest1, but listed as state %s") % (f, state))
1810 errors += 1
1823 errors += 1
1811 if errors:
1824 if errors:
1812 error = _(".hg/dirstate inconsistent with current parent's manifest")
1825 error = _(".hg/dirstate inconsistent with current parent's manifest")
1813 raise util.Abort(error)
1826 raise util.Abort(error)
1814
1827
1815 @command('debugcommands', [], _('[COMMAND]'))
1828 @command('debugcommands', [], _('[COMMAND]'))
1816 def debugcommands(ui, cmd='', *args):
1829 def debugcommands(ui, cmd='', *args):
1817 """list all available commands and options"""
1830 """list all available commands and options"""
1818 for cmd, vals in sorted(table.iteritems()):
1831 for cmd, vals in sorted(table.iteritems()):
1819 cmd = cmd.split('|')[0].strip('^')
1832 cmd = cmd.split('|')[0].strip('^')
1820 opts = ', '.join([i[1] for i in vals[1]])
1833 opts = ', '.join([i[1] for i in vals[1]])
1821 ui.write('%s: %s\n' % (cmd, opts))
1834 ui.write('%s: %s\n' % (cmd, opts))
1822
1835
1823 @command('debugcomplete',
1836 @command('debugcomplete',
1824 [('o', 'options', None, _('show the command options'))],
1837 [('o', 'options', None, _('show the command options'))],
1825 _('[-o] CMD'))
1838 _('[-o] CMD'))
1826 def debugcomplete(ui, cmd='', **opts):
1839 def debugcomplete(ui, cmd='', **opts):
1827 """returns the completion list associated with the given command"""
1840 """returns the completion list associated with the given command"""
1828
1841
1829 if opts.get('options'):
1842 if opts.get('options'):
1830 options = []
1843 options = []
1831 otables = [globalopts]
1844 otables = [globalopts]
1832 if cmd:
1845 if cmd:
1833 aliases, entry = cmdutil.findcmd(cmd, table, False)
1846 aliases, entry = cmdutil.findcmd(cmd, table, False)
1834 otables.append(entry[1])
1847 otables.append(entry[1])
1835 for t in otables:
1848 for t in otables:
1836 for o in t:
1849 for o in t:
1837 if "(DEPRECATED)" in o[3]:
1850 if "(DEPRECATED)" in o[3]:
1838 continue
1851 continue
1839 if o[0]:
1852 if o[0]:
1840 options.append('-%s' % o[0])
1853 options.append('-%s' % o[0])
1841 options.append('--%s' % o[1])
1854 options.append('--%s' % o[1])
1842 ui.write("%s\n" % "\n".join(options))
1855 ui.write("%s\n" % "\n".join(options))
1843 return
1856 return
1844
1857
1845 cmdlist = cmdutil.findpossible(cmd, table)
1858 cmdlist = cmdutil.findpossible(cmd, table)
1846 if ui.verbose:
1859 if ui.verbose:
1847 cmdlist = [' '.join(c[0]) for c in cmdlist.values()]
1860 cmdlist = [' '.join(c[0]) for c in cmdlist.values()]
1848 ui.write("%s\n" % "\n".join(sorted(cmdlist)))
1861 ui.write("%s\n" % "\n".join(sorted(cmdlist)))
1849
1862
1850 @command('debugdag',
1863 @command('debugdag',
1851 [('t', 'tags', None, _('use tags as labels')),
1864 [('t', 'tags', None, _('use tags as labels')),
1852 ('b', 'branches', None, _('annotate with branch names')),
1865 ('b', 'branches', None, _('annotate with branch names')),
1853 ('', 'dots', None, _('use dots for runs')),
1866 ('', 'dots', None, _('use dots for runs')),
1854 ('s', 'spaces', None, _('separate elements by spaces'))],
1867 ('s', 'spaces', None, _('separate elements by spaces'))],
1855 _('[OPTION]... [FILE [REV]...]'))
1868 _('[OPTION]... [FILE [REV]...]'))
1856 def debugdag(ui, repo, file_=None, *revs, **opts):
1869 def debugdag(ui, repo, file_=None, *revs, **opts):
1857 """format the changelog or an index DAG as a concise textual description
1870 """format the changelog or an index DAG as a concise textual description
1858
1871
1859 If you pass a revlog index, the revlog's DAG is emitted. If you list
1872 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.
1873 revision numbers, they get labeled in the output as rN.
1861
1874
1862 Otherwise, the changelog DAG of the current repo is emitted.
1875 Otherwise, the changelog DAG of the current repo is emitted.
1863 """
1876 """
1864 spaces = opts.get('spaces')
1877 spaces = opts.get('spaces')
1865 dots = opts.get('dots')
1878 dots = opts.get('dots')
1866 if file_:
1879 if file_:
1867 rlog = revlog.revlog(scmutil.opener(os.getcwd(), audit=False), file_)
1880 rlog = revlog.revlog(scmutil.opener(os.getcwd(), audit=False), file_)
1868 revs = set((int(r) for r in revs))
1881 revs = set((int(r) for r in revs))
1869 def events():
1882 def events():
1870 for r in rlog:
1883 for r in rlog:
1871 yield 'n', (r, list(set(p for p in rlog.parentrevs(r)
1884 yield 'n', (r, list(set(p for p in rlog.parentrevs(r)
1872 if p != -1)))
1885 if p != -1)))
1873 if r in revs:
1886 if r in revs:
1874 yield 'l', (r, "r%i" % r)
1887 yield 'l', (r, "r%i" % r)
1875 elif repo:
1888 elif repo:
1876 cl = repo.changelog
1889 cl = repo.changelog
1877 tags = opts.get('tags')
1890 tags = opts.get('tags')
1878 branches = opts.get('branches')
1891 branches = opts.get('branches')
1879 if tags:
1892 if tags:
1880 labels = {}
1893 labels = {}
1881 for l, n in repo.tags().items():
1894 for l, n in repo.tags().items():
1882 labels.setdefault(cl.rev(n), []).append(l)
1895 labels.setdefault(cl.rev(n), []).append(l)
1883 def events():
1896 def events():
1884 b = "default"
1897 b = "default"
1885 for r in cl:
1898 for r in cl:
1886 if branches:
1899 if branches:
1887 newb = cl.read(cl.node(r))[5]['branch']
1900 newb = cl.read(cl.node(r))[5]['branch']
1888 if newb != b:
1901 if newb != b:
1889 yield 'a', newb
1902 yield 'a', newb
1890 b = newb
1903 b = newb
1891 yield 'n', (r, list(set(p for p in cl.parentrevs(r)
1904 yield 'n', (r, list(set(p for p in cl.parentrevs(r)
1892 if p != -1)))
1905 if p != -1)))
1893 if tags:
1906 if tags:
1894 ls = labels.get(r)
1907 ls = labels.get(r)
1895 if ls:
1908 if ls:
1896 for l in ls:
1909 for l in ls:
1897 yield 'l', (r, l)
1910 yield 'l', (r, l)
1898 else:
1911 else:
1899 raise util.Abort(_('need repo for changelog dag'))
1912 raise util.Abort(_('need repo for changelog dag'))
1900
1913
1901 for line in dagparser.dagtextlines(events(),
1914 for line in dagparser.dagtextlines(events(),
1902 addspaces=spaces,
1915 addspaces=spaces,
1903 wraplabels=True,
1916 wraplabels=True,
1904 wrapannotations=True,
1917 wrapannotations=True,
1905 wrapnonlinear=dots,
1918 wrapnonlinear=dots,
1906 usedots=dots,
1919 usedots=dots,
1907 maxlinewidth=70):
1920 maxlinewidth=70):
1908 ui.write(line)
1921 ui.write(line)
1909 ui.write("\n")
1922 ui.write("\n")
1910
1923
1911 @command('debugdata',
1924 @command('debugdata',
1912 [('c', 'changelog', False, _('open changelog')),
1925 [('c', 'changelog', False, _('open changelog')),
1913 ('m', 'manifest', False, _('open manifest'))],
1926 ('m', 'manifest', False, _('open manifest'))],
1914 _('-c|-m|FILE REV'))
1927 _('-c|-m|FILE REV'))
1915 def debugdata(ui, repo, file_, rev=None, **opts):
1928 def debugdata(ui, repo, file_, rev=None, **opts):
1916 """dump the contents of a data file revision"""
1929 """dump the contents of a data file revision"""
1917 if opts.get('changelog') or opts.get('manifest'):
1930 if opts.get('changelog') or opts.get('manifest'):
1918 file_, rev = None, file_
1931 file_, rev = None, file_
1919 elif rev is None:
1932 elif rev is None:
1920 raise error.CommandError('debugdata', _('invalid arguments'))
1933 raise error.CommandError('debugdata', _('invalid arguments'))
1921 r = cmdutil.openrevlog(repo, 'debugdata', file_, opts)
1934 r = cmdutil.openrevlog(repo, 'debugdata', file_, opts)
1922 try:
1935 try:
1923 ui.write(r.revision(r.lookup(rev)))
1936 ui.write(r.revision(r.lookup(rev)))
1924 except KeyError:
1937 except KeyError:
1925 raise util.Abort(_('invalid revision identifier %s') % rev)
1938 raise util.Abort(_('invalid revision identifier %s') % rev)
1926
1939
1927 @command('debugdate',
1940 @command('debugdate',
1928 [('e', 'extended', None, _('try extended date formats'))],
1941 [('e', 'extended', None, _('try extended date formats'))],
1929 _('[-e] DATE [RANGE]'))
1942 _('[-e] DATE [RANGE]'))
1930 def debugdate(ui, date, range=None, **opts):
1943 def debugdate(ui, date, range=None, **opts):
1931 """parse and display a date"""
1944 """parse and display a date"""
1932 if opts["extended"]:
1945 if opts["extended"]:
1933 d = util.parsedate(date, util.extendeddateformats)
1946 d = util.parsedate(date, util.extendeddateformats)
1934 else:
1947 else:
1935 d = util.parsedate(date)
1948 d = util.parsedate(date)
1936 ui.write(("internal: %s %s\n") % d)
1949 ui.write(("internal: %s %s\n") % d)
1937 ui.write(("standard: %s\n") % util.datestr(d))
1950 ui.write(("standard: %s\n") % util.datestr(d))
1938 if range:
1951 if range:
1939 m = util.matchdate(range)
1952 m = util.matchdate(range)
1940 ui.write(("match: %s\n") % m(d[0]))
1953 ui.write(("match: %s\n") % m(d[0]))
1941
1954
1942 @command('debugdiscovery',
1955 @command('debugdiscovery',
1943 [('', 'old', None, _('use old-style discovery')),
1956 [('', 'old', None, _('use old-style discovery')),
1944 ('', 'nonheads', None,
1957 ('', 'nonheads', None,
1945 _('use old-style discovery with non-heads included')),
1958 _('use old-style discovery with non-heads included')),
1946 ] + remoteopts,
1959 ] + remoteopts,
1947 _('[-l REV] [-r REV] [-b BRANCH]... [OTHER]'))
1960 _('[-l REV] [-r REV] [-b BRANCH]... [OTHER]'))
1948 def debugdiscovery(ui, repo, remoteurl="default", **opts):
1961 def debugdiscovery(ui, repo, remoteurl="default", **opts):
1949 """runs the changeset discovery protocol in isolation"""
1962 """runs the changeset discovery protocol in isolation"""
1950 remoteurl, branches = hg.parseurl(ui.expandpath(remoteurl),
1963 remoteurl, branches = hg.parseurl(ui.expandpath(remoteurl),
1951 opts.get('branch'))
1964 opts.get('branch'))
1952 remote = hg.peer(repo, opts, remoteurl)
1965 remote = hg.peer(repo, opts, remoteurl)
1953 ui.status(_('comparing with %s\n') % util.hidepassword(remoteurl))
1966 ui.status(_('comparing with %s\n') % util.hidepassword(remoteurl))
1954
1967
1955 # make sure tests are repeatable
1968 # make sure tests are repeatable
1956 random.seed(12323)
1969 random.seed(12323)
1957
1970
1958 def doit(localheads, remoteheads, remote=remote):
1971 def doit(localheads, remoteheads, remote=remote):
1959 if opts.get('old'):
1972 if opts.get('old'):
1960 if localheads:
1973 if localheads:
1961 raise util.Abort('cannot use localheads with old style '
1974 raise util.Abort('cannot use localheads with old style '
1962 'discovery')
1975 'discovery')
1963 if not util.safehasattr(remote, 'branches'):
1976 if not util.safehasattr(remote, 'branches'):
1964 # enable in-client legacy support
1977 # enable in-client legacy support
1965 remote = localrepo.locallegacypeer(remote.local())
1978 remote = localrepo.locallegacypeer(remote.local())
1966 common, _in, hds = treediscovery.findcommonincoming(repo, remote,
1979 common, _in, hds = treediscovery.findcommonincoming(repo, remote,
1967 force=True)
1980 force=True)
1968 common = set(common)
1981 common = set(common)
1969 if not opts.get('nonheads'):
1982 if not opts.get('nonheads'):
1970 ui.write(("unpruned common: %s\n") %
1983 ui.write(("unpruned common: %s\n") %
1971 " ".join(sorted(short(n) for n in common)))
1984 " ".join(sorted(short(n) for n in common)))
1972 dag = dagutil.revlogdag(repo.changelog)
1985 dag = dagutil.revlogdag(repo.changelog)
1973 all = dag.ancestorset(dag.internalizeall(common))
1986 all = dag.ancestorset(dag.internalizeall(common))
1974 common = dag.externalizeall(dag.headsetofconnecteds(all))
1987 common = dag.externalizeall(dag.headsetofconnecteds(all))
1975 else:
1988 else:
1976 common, any, hds = setdiscovery.findcommonheads(ui, repo, remote)
1989 common, any, hds = setdiscovery.findcommonheads(ui, repo, remote)
1977 common = set(common)
1990 common = set(common)
1978 rheads = set(hds)
1991 rheads = set(hds)
1979 lheads = set(repo.heads())
1992 lheads = set(repo.heads())
1980 ui.write(("common heads: %s\n") %
1993 ui.write(("common heads: %s\n") %
1981 " ".join(sorted(short(n) for n in common)))
1994 " ".join(sorted(short(n) for n in common)))
1982 if lheads <= common:
1995 if lheads <= common:
1983 ui.write(("local is subset\n"))
1996 ui.write(("local is subset\n"))
1984 elif rheads <= common:
1997 elif rheads <= common:
1985 ui.write(("remote is subset\n"))
1998 ui.write(("remote is subset\n"))
1986
1999
1987 serverlogs = opts.get('serverlog')
2000 serverlogs = opts.get('serverlog')
1988 if serverlogs:
2001 if serverlogs:
1989 for filename in serverlogs:
2002 for filename in serverlogs:
1990 logfile = open(filename, 'r')
2003 logfile = open(filename, 'r')
1991 try:
2004 try:
1992 line = logfile.readline()
2005 line = logfile.readline()
1993 while line:
2006 while line:
1994 parts = line.strip().split(';')
2007 parts = line.strip().split(';')
1995 op = parts[1]
2008 op = parts[1]
1996 if op == 'cg':
2009 if op == 'cg':
1997 pass
2010 pass
1998 elif op == 'cgss':
2011 elif op == 'cgss':
1999 doit(parts[2].split(' '), parts[3].split(' '))
2012 doit(parts[2].split(' '), parts[3].split(' '))
2000 elif op == 'unb':
2013 elif op == 'unb':
2001 doit(parts[3].split(' '), parts[2].split(' '))
2014 doit(parts[3].split(' '), parts[2].split(' '))
2002 line = logfile.readline()
2015 line = logfile.readline()
2003 finally:
2016 finally:
2004 logfile.close()
2017 logfile.close()
2005
2018
2006 else:
2019 else:
2007 remoterevs, _checkout = hg.addbranchrevs(repo, remote, branches,
2020 remoterevs, _checkout = hg.addbranchrevs(repo, remote, branches,
2008 opts.get('remote_head'))
2021 opts.get('remote_head'))
2009 localrevs = opts.get('local_head')
2022 localrevs = opts.get('local_head')
2010 doit(localrevs, remoterevs)
2023 doit(localrevs, remoterevs)
2011
2024
2012 @command('debugfileset',
2025 @command('debugfileset',
2013 [('r', 'rev', '', _('apply the filespec on this revision'), _('REV'))],
2026 [('r', 'rev', '', _('apply the filespec on this revision'), _('REV'))],
2014 _('[-r REV] FILESPEC'))
2027 _('[-r REV] FILESPEC'))
2015 def debugfileset(ui, repo, expr, **opts):
2028 def debugfileset(ui, repo, expr, **opts):
2016 '''parse and apply a fileset specification'''
2029 '''parse and apply a fileset specification'''
2017 ctx = scmutil.revsingle(repo, opts.get('rev'), None)
2030 ctx = scmutil.revsingle(repo, opts.get('rev'), None)
2018 if ui.verbose:
2031 if ui.verbose:
2019 tree = fileset.parse(expr)[0]
2032 tree = fileset.parse(expr)[0]
2020 ui.note(tree, "\n")
2033 ui.note(tree, "\n")
2021
2034
2022 for f in ctx.getfileset(expr):
2035 for f in ctx.getfileset(expr):
2023 ui.write("%s\n" % f)
2036 ui.write("%s\n" % f)
2024
2037
2025 @command('debugfsinfo', [], _('[PATH]'))
2038 @command('debugfsinfo', [], _('[PATH]'))
2026 def debugfsinfo(ui, path="."):
2039 def debugfsinfo(ui, path="."):
2027 """show information detected about current filesystem"""
2040 """show information detected about current filesystem"""
2028 util.writefile('.debugfsinfo', '')
2041 util.writefile('.debugfsinfo', '')
2029 ui.write(('exec: %s\n') % (util.checkexec(path) and 'yes' or 'no'))
2042 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'))
2043 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'))
2044 ui.write(('hardlink: %s\n') % (util.checknlink(path) and 'yes' or 'no'))
2032 ui.write(('case-sensitive: %s\n') % (util.checkcase('.debugfsinfo')
2045 ui.write(('case-sensitive: %s\n') % (util.checkcase('.debugfsinfo')
2033 and 'yes' or 'no'))
2046 and 'yes' or 'no'))
2034 os.unlink('.debugfsinfo')
2047 os.unlink('.debugfsinfo')
2035
2048
2036 @command('debuggetbundle',
2049 @command('debuggetbundle',
2037 [('H', 'head', [], _('id of head node'), _('ID')),
2050 [('H', 'head', [], _('id of head node'), _('ID')),
2038 ('C', 'common', [], _('id of common node'), _('ID')),
2051 ('C', 'common', [], _('id of common node'), _('ID')),
2039 ('t', 'type', 'bzip2', _('bundle compression type to use'), _('TYPE'))],
2052 ('t', 'type', 'bzip2', _('bundle compression type to use'), _('TYPE'))],
2040 _('REPO FILE [-H|-C ID]...'))
2053 _('REPO FILE [-H|-C ID]...'))
2041 def debuggetbundle(ui, repopath, bundlepath, head=None, common=None, **opts):
2054 def debuggetbundle(ui, repopath, bundlepath, head=None, common=None, **opts):
2042 """retrieves a bundle from a repo
2055 """retrieves a bundle from a repo
2043
2056
2044 Every ID must be a full-length hex node id string. Saves the bundle to the
2057 Every ID must be a full-length hex node id string. Saves the bundle to the
2045 given file.
2058 given file.
2046 """
2059 """
2047 repo = hg.peer(ui, opts, repopath)
2060 repo = hg.peer(ui, opts, repopath)
2048 if not repo.capable('getbundle'):
2061 if not repo.capable('getbundle'):
2049 raise util.Abort("getbundle() not supported by target repository")
2062 raise util.Abort("getbundle() not supported by target repository")
2050 args = {}
2063 args = {}
2051 if common:
2064 if common:
2052 args['common'] = [bin(s) for s in common]
2065 args['common'] = [bin(s) for s in common]
2053 if head:
2066 if head:
2054 args['heads'] = [bin(s) for s in head]
2067 args['heads'] = [bin(s) for s in head]
2055 # TODO: get desired bundlecaps from command line.
2068 # TODO: get desired bundlecaps from command line.
2056 args['bundlecaps'] = None
2069 args['bundlecaps'] = None
2057 bundle = repo.getbundle('debug', **args)
2070 bundle = repo.getbundle('debug', **args)
2058
2071
2059 bundletype = opts.get('type', 'bzip2').lower()
2072 bundletype = opts.get('type', 'bzip2').lower()
2060 btypes = {'none': 'HG10UN', 'bzip2': 'HG10BZ', 'gzip': 'HG10GZ'}
2073 btypes = {'none': 'HG10UN', 'bzip2': 'HG10BZ', 'gzip': 'HG10GZ'}
2061 bundletype = btypes.get(bundletype)
2074 bundletype = btypes.get(bundletype)
2062 if bundletype not in changegroup.bundletypes:
2075 if bundletype not in changegroup.bundletypes:
2063 raise util.Abort(_('unknown bundle type specified with --type'))
2076 raise util.Abort(_('unknown bundle type specified with --type'))
2064 changegroup.writebundle(bundle, bundlepath, bundletype)
2077 changegroup.writebundle(bundle, bundlepath, bundletype)
2065
2078
2066 @command('debugignore', [], '')
2079 @command('debugignore', [], '')
2067 def debugignore(ui, repo, *values, **opts):
2080 def debugignore(ui, repo, *values, **opts):
2068 """display the combined ignore pattern"""
2081 """display the combined ignore pattern"""
2069 ignore = repo.dirstate._ignore
2082 ignore = repo.dirstate._ignore
2070 includepat = getattr(ignore, 'includepat', None)
2083 includepat = getattr(ignore, 'includepat', None)
2071 if includepat is not None:
2084 if includepat is not None:
2072 ui.write("%s\n" % includepat)
2085 ui.write("%s\n" % includepat)
2073 else:
2086 else:
2074 raise util.Abort(_("no ignore patterns found"))
2087 raise util.Abort(_("no ignore patterns found"))
2075
2088
2076 @command('debugindex',
2089 @command('debugindex',
2077 [('c', 'changelog', False, _('open changelog')),
2090 [('c', 'changelog', False, _('open changelog')),
2078 ('m', 'manifest', False, _('open manifest')),
2091 ('m', 'manifest', False, _('open manifest')),
2079 ('f', 'format', 0, _('revlog format'), _('FORMAT'))],
2092 ('f', 'format', 0, _('revlog format'), _('FORMAT'))],
2080 _('[-f FORMAT] -c|-m|FILE'))
2093 _('[-f FORMAT] -c|-m|FILE'))
2081 def debugindex(ui, repo, file_=None, **opts):
2094 def debugindex(ui, repo, file_=None, **opts):
2082 """dump the contents of an index file"""
2095 """dump the contents of an index file"""
2083 r = cmdutil.openrevlog(repo, 'debugindex', file_, opts)
2096 r = cmdutil.openrevlog(repo, 'debugindex', file_, opts)
2084 format = opts.get('format', 0)
2097 format = opts.get('format', 0)
2085 if format not in (0, 1):
2098 if format not in (0, 1):
2086 raise util.Abort(_("unknown format %d") % format)
2099 raise util.Abort(_("unknown format %d") % format)
2087
2100
2088 generaldelta = r.version & revlog.REVLOGGENERALDELTA
2101 generaldelta = r.version & revlog.REVLOGGENERALDELTA
2089 if generaldelta:
2102 if generaldelta:
2090 basehdr = ' delta'
2103 basehdr = ' delta'
2091 else:
2104 else:
2092 basehdr = ' base'
2105 basehdr = ' base'
2093
2106
2094 if format == 0:
2107 if format == 0:
2095 ui.write(" rev offset length " + basehdr + " linkrev"
2108 ui.write(" rev offset length " + basehdr + " linkrev"
2096 " nodeid p1 p2\n")
2109 " nodeid p1 p2\n")
2097 elif format == 1:
2110 elif format == 1:
2098 ui.write(" rev flag offset length"
2111 ui.write(" rev flag offset length"
2099 " size " + basehdr + " link p1 p2"
2112 " size " + basehdr + " link p1 p2"
2100 " nodeid\n")
2113 " nodeid\n")
2101
2114
2102 for i in r:
2115 for i in r:
2103 node = r.node(i)
2116 node = r.node(i)
2104 if generaldelta:
2117 if generaldelta:
2105 base = r.deltaparent(i)
2118 base = r.deltaparent(i)
2106 else:
2119 else:
2107 base = r.chainbase(i)
2120 base = r.chainbase(i)
2108 if format == 0:
2121 if format == 0:
2109 try:
2122 try:
2110 pp = r.parents(node)
2123 pp = r.parents(node)
2111 except Exception:
2124 except Exception:
2112 pp = [nullid, nullid]
2125 pp = [nullid, nullid]
2113 ui.write("% 6d % 9d % 7d % 6d % 7d %s %s %s\n" % (
2126 ui.write("% 6d % 9d % 7d % 6d % 7d %s %s %s\n" % (
2114 i, r.start(i), r.length(i), base, r.linkrev(i),
2127 i, r.start(i), r.length(i), base, r.linkrev(i),
2115 short(node), short(pp[0]), short(pp[1])))
2128 short(node), short(pp[0]), short(pp[1])))
2116 elif format == 1:
2129 elif format == 1:
2117 pr = r.parentrevs(i)
2130 pr = r.parentrevs(i)
2118 ui.write("% 6d %04x % 8d % 8d % 8d % 6d % 6d % 6d % 6d %s\n" % (
2131 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),
2132 i, r.flags(i), r.start(i), r.length(i), r.rawsize(i),
2120 base, r.linkrev(i), pr[0], pr[1], short(node)))
2133 base, r.linkrev(i), pr[0], pr[1], short(node)))
2121
2134
2122 @command('debugindexdot', [], _('FILE'))
2135 @command('debugindexdot', [], _('FILE'))
2123 def debugindexdot(ui, repo, file_):
2136 def debugindexdot(ui, repo, file_):
2124 """dump an index DAG as a graphviz dot file"""
2137 """dump an index DAG as a graphviz dot file"""
2125 r = None
2138 r = None
2126 if repo:
2139 if repo:
2127 filelog = repo.file(file_)
2140 filelog = repo.file(file_)
2128 if len(filelog):
2141 if len(filelog):
2129 r = filelog
2142 r = filelog
2130 if not r:
2143 if not r:
2131 r = revlog.revlog(scmutil.opener(os.getcwd(), audit=False), file_)
2144 r = revlog.revlog(scmutil.opener(os.getcwd(), audit=False), file_)
2132 ui.write(("digraph G {\n"))
2145 ui.write(("digraph G {\n"))
2133 for i in r:
2146 for i in r:
2134 node = r.node(i)
2147 node = r.node(i)
2135 pp = r.parents(node)
2148 pp = r.parents(node)
2136 ui.write("\t%d -> %d\n" % (r.rev(pp[0]), i))
2149 ui.write("\t%d -> %d\n" % (r.rev(pp[0]), i))
2137 if pp[1] != nullid:
2150 if pp[1] != nullid:
2138 ui.write("\t%d -> %d\n" % (r.rev(pp[1]), i))
2151 ui.write("\t%d -> %d\n" % (r.rev(pp[1]), i))
2139 ui.write("}\n")
2152 ui.write("}\n")
2140
2153
2141 @command('debuginstall', [], '')
2154 @command('debuginstall', [], '')
2142 def debuginstall(ui):
2155 def debuginstall(ui):
2143 '''test Mercurial installation
2156 '''test Mercurial installation
2144
2157
2145 Returns 0 on success.
2158 Returns 0 on success.
2146 '''
2159 '''
2147
2160
2148 def writetemp(contents):
2161 def writetemp(contents):
2149 (fd, name) = tempfile.mkstemp(prefix="hg-debuginstall-")
2162 (fd, name) = tempfile.mkstemp(prefix="hg-debuginstall-")
2150 f = os.fdopen(fd, "wb")
2163 f = os.fdopen(fd, "wb")
2151 f.write(contents)
2164 f.write(contents)
2152 f.close()
2165 f.close()
2153 return name
2166 return name
2154
2167
2155 problems = 0
2168 problems = 0
2156
2169
2157 # encoding
2170 # encoding
2158 ui.status(_("checking encoding (%s)...\n") % encoding.encoding)
2171 ui.status(_("checking encoding (%s)...\n") % encoding.encoding)
2159 try:
2172 try:
2160 encoding.fromlocal("test")
2173 encoding.fromlocal("test")
2161 except util.Abort, inst:
2174 except util.Abort, inst:
2162 ui.write(" %s\n" % inst)
2175 ui.write(" %s\n" % inst)
2163 ui.write(_(" (check that your locale is properly set)\n"))
2176 ui.write(_(" (check that your locale is properly set)\n"))
2164 problems += 1
2177 problems += 1
2165
2178
2166 # Python
2179 # Python
2167 ui.status(_("checking Python executable (%s)\n") % sys.executable)
2180 ui.status(_("checking Python executable (%s)\n") % sys.executable)
2168 ui.status(_("checking Python version (%s)\n")
2181 ui.status(_("checking Python version (%s)\n")
2169 % ("%s.%s.%s" % sys.version_info[:3]))
2182 % ("%s.%s.%s" % sys.version_info[:3]))
2170 ui.status(_("checking Python lib (%s)...\n")
2183 ui.status(_("checking Python lib (%s)...\n")
2171 % os.path.dirname(os.__file__))
2184 % os.path.dirname(os.__file__))
2172
2185
2173 # compiled modules
2186 # compiled modules
2174 ui.status(_("checking installed modules (%s)...\n")
2187 ui.status(_("checking installed modules (%s)...\n")
2175 % os.path.dirname(__file__))
2188 % os.path.dirname(__file__))
2176 try:
2189 try:
2177 import bdiff, mpatch, base85, osutil
2190 import bdiff, mpatch, base85, osutil
2178 dir(bdiff), dir(mpatch), dir(base85), dir(osutil) # quiet pyflakes
2191 dir(bdiff), dir(mpatch), dir(base85), dir(osutil) # quiet pyflakes
2179 except Exception, inst:
2192 except Exception, inst:
2180 ui.write(" %s\n" % inst)
2193 ui.write(" %s\n" % inst)
2181 ui.write(_(" One or more extensions could not be found"))
2194 ui.write(_(" One or more extensions could not be found"))
2182 ui.write(_(" (check that you compiled the extensions)\n"))
2195 ui.write(_(" (check that you compiled the extensions)\n"))
2183 problems += 1
2196 problems += 1
2184
2197
2185 # templates
2198 # templates
2186 import templater
2199 import templater
2187 p = templater.templatepath()
2200 p = templater.templatepath()
2188 ui.status(_("checking templates (%s)...\n") % ' '.join(p))
2201 ui.status(_("checking templates (%s)...\n") % ' '.join(p))
2189 if p:
2202 if p:
2190 m = templater.templatepath("map-cmdline.default")
2203 m = templater.templatepath("map-cmdline.default")
2191 if m:
2204 if m:
2192 # template found, check if it is working
2205 # template found, check if it is working
2193 try:
2206 try:
2194 templater.templater(m)
2207 templater.templater(m)
2195 except Exception, inst:
2208 except Exception, inst:
2196 ui.write(" %s\n" % inst)
2209 ui.write(" %s\n" % inst)
2197 p = None
2210 p = None
2198 else:
2211 else:
2199 ui.write(_(" template 'default' not found\n"))
2212 ui.write(_(" template 'default' not found\n"))
2200 p = None
2213 p = None
2201 else:
2214 else:
2202 ui.write(_(" no template directories found\n"))
2215 ui.write(_(" no template directories found\n"))
2203 if not p:
2216 if not p:
2204 ui.write(_(" (templates seem to have been installed incorrectly)\n"))
2217 ui.write(_(" (templates seem to have been installed incorrectly)\n"))
2205 problems += 1
2218 problems += 1
2206
2219
2207 # editor
2220 # editor
2208 ui.status(_("checking commit editor...\n"))
2221 ui.status(_("checking commit editor...\n"))
2209 editor = ui.geteditor()
2222 editor = ui.geteditor()
2210 cmdpath = util.findexe(editor) or util.findexe(editor.split()[0])
2223 cmdpath = util.findexe(editor) or util.findexe(editor.split()[0])
2211 if not cmdpath:
2224 if not cmdpath:
2212 if editor == 'vi':
2225 if editor == 'vi':
2213 ui.write(_(" No commit editor set and can't find vi in PATH\n"))
2226 ui.write(_(" No commit editor set and can't find vi in PATH\n"))
2214 ui.write(_(" (specify a commit editor in your configuration"
2227 ui.write(_(" (specify a commit editor in your configuration"
2215 " file)\n"))
2228 " file)\n"))
2216 else:
2229 else:
2217 ui.write(_(" Can't find editor '%s' in PATH\n") % editor)
2230 ui.write(_(" Can't find editor '%s' in PATH\n") % editor)
2218 ui.write(_(" (specify a commit editor in your configuration"
2231 ui.write(_(" (specify a commit editor in your configuration"
2219 " file)\n"))
2232 " file)\n"))
2220 problems += 1
2233 problems += 1
2221
2234
2222 # check username
2235 # check username
2223 ui.status(_("checking username...\n"))
2236 ui.status(_("checking username...\n"))
2224 try:
2237 try:
2225 ui.username()
2238 ui.username()
2226 except util.Abort, e:
2239 except util.Abort, e:
2227 ui.write(" %s\n" % e)
2240 ui.write(" %s\n" % e)
2228 ui.write(_(" (specify a username in your configuration file)\n"))
2241 ui.write(_(" (specify a username in your configuration file)\n"))
2229 problems += 1
2242 problems += 1
2230
2243
2231 if not problems:
2244 if not problems:
2232 ui.status(_("no problems detected\n"))
2245 ui.status(_("no problems detected\n"))
2233 else:
2246 else:
2234 ui.write(_("%s problems detected,"
2247 ui.write(_("%s problems detected,"
2235 " please check your install!\n") % problems)
2248 " please check your install!\n") % problems)
2236
2249
2237 return problems
2250 return problems
2238
2251
2239 @command('debugknown', [], _('REPO ID...'))
2252 @command('debugknown', [], _('REPO ID...'))
2240 def debugknown(ui, repopath, *ids, **opts):
2253 def debugknown(ui, repopath, *ids, **opts):
2241 """test whether node ids are known to a repo
2254 """test whether node ids are known to a repo
2242
2255
2243 Every ID must be a full-length hex node id string. Returns a list of 0s
2256 Every ID must be a full-length hex node id string. Returns a list of 0s
2244 and 1s indicating unknown/known.
2257 and 1s indicating unknown/known.
2245 """
2258 """
2246 repo = hg.peer(ui, opts, repopath)
2259 repo = hg.peer(ui, opts, repopath)
2247 if not repo.capable('known'):
2260 if not repo.capable('known'):
2248 raise util.Abort("known() not supported by target repository")
2261 raise util.Abort("known() not supported by target repository")
2249 flags = repo.known([bin(s) for s in ids])
2262 flags = repo.known([bin(s) for s in ids])
2250 ui.write("%s\n" % ("".join([f and "1" or "0" for f in flags])))
2263 ui.write("%s\n" % ("".join([f and "1" or "0" for f in flags])))
2251
2264
2252 @command('debuglabelcomplete', [], _('LABEL...'))
2265 @command('debuglabelcomplete', [], _('LABEL...'))
2253 def debuglabelcomplete(ui, repo, *args):
2266 def debuglabelcomplete(ui, repo, *args):
2254 '''complete "labels" - tags, open branch names, bookmark names'''
2267 '''complete "labels" - tags, open branch names, bookmark names'''
2255
2268
2256 labels = set()
2269 labels = set()
2257 labels.update(t[0] for t in repo.tagslist())
2270 labels.update(t[0] for t in repo.tagslist())
2258 labels.update(repo._bookmarks.keys())
2271 labels.update(repo._bookmarks.keys())
2259 labels.update(tag for (tag, heads, tip, closed)
2272 labels.update(tag for (tag, heads, tip, closed)
2260 in repo.branchmap().iterbranches() if not closed)
2273 in repo.branchmap().iterbranches() if not closed)
2261 completions = set()
2274 completions = set()
2262 if not args:
2275 if not args:
2263 args = ['']
2276 args = ['']
2264 for a in args:
2277 for a in args:
2265 completions.update(l for l in labels if l.startswith(a))
2278 completions.update(l for l in labels if l.startswith(a))
2266 ui.write('\n'.join(sorted(completions)))
2279 ui.write('\n'.join(sorted(completions)))
2267 ui.write('\n')
2280 ui.write('\n')
2268
2281
2269 @command('debugobsolete',
2282 @command('debugobsolete',
2270 [('', 'flags', 0, _('markers flag')),
2283 [('', 'flags', 0, _('markers flag')),
2271 ] + commitopts2,
2284 ] + commitopts2,
2272 _('[OBSOLETED [REPLACEMENT] [REPL... ]'))
2285 _('[OBSOLETED [REPLACEMENT] [REPL... ]'))
2273 def debugobsolete(ui, repo, precursor=None, *successors, **opts):
2286 def debugobsolete(ui, repo, precursor=None, *successors, **opts):
2274 """create arbitrary obsolete marker
2287 """create arbitrary obsolete marker
2275
2288
2276 With no arguments, displays the list of obsolescence markers."""
2289 With no arguments, displays the list of obsolescence markers."""
2277 def parsenodeid(s):
2290 def parsenodeid(s):
2278 try:
2291 try:
2279 # We do not use revsingle/revrange functions here to accept
2292 # We do not use revsingle/revrange functions here to accept
2280 # arbitrary node identifiers, possibly not present in the
2293 # arbitrary node identifiers, possibly not present in the
2281 # local repository.
2294 # local repository.
2282 n = bin(s)
2295 n = bin(s)
2283 if len(n) != len(nullid):
2296 if len(n) != len(nullid):
2284 raise TypeError()
2297 raise TypeError()
2285 return n
2298 return n
2286 except TypeError:
2299 except TypeError:
2287 raise util.Abort('changeset references must be full hexadecimal '
2300 raise util.Abort('changeset references must be full hexadecimal '
2288 'node identifiers')
2301 'node identifiers')
2289
2302
2290 if precursor is not None:
2303 if precursor is not None:
2291 metadata = {}
2304 metadata = {}
2292 if 'date' in opts:
2305 if 'date' in opts:
2293 metadata['date'] = opts['date']
2306 metadata['date'] = opts['date']
2294 metadata['user'] = opts['user'] or ui.username()
2307 metadata['user'] = opts['user'] or ui.username()
2295 succs = tuple(parsenodeid(succ) for succ in successors)
2308 succs = tuple(parsenodeid(succ) for succ in successors)
2296 l = repo.lock()
2309 l = repo.lock()
2297 try:
2310 try:
2298 tr = repo.transaction('debugobsolete')
2311 tr = repo.transaction('debugobsolete')
2299 try:
2312 try:
2300 repo.obsstore.create(tr, parsenodeid(precursor), succs,
2313 repo.obsstore.create(tr, parsenodeid(precursor), succs,
2301 opts['flags'], metadata)
2314 opts['flags'], metadata)
2302 tr.close()
2315 tr.close()
2303 finally:
2316 finally:
2304 tr.release()
2317 tr.release()
2305 finally:
2318 finally:
2306 l.release()
2319 l.release()
2307 else:
2320 else:
2308 for m in obsolete.allmarkers(repo):
2321 for m in obsolete.allmarkers(repo):
2309 cmdutil.showmarker(ui, m)
2322 cmdutil.showmarker(ui, m)
2310
2323
2311 @command('debugpathcomplete',
2324 @command('debugpathcomplete',
2312 [('f', 'full', None, _('complete an entire path')),
2325 [('f', 'full', None, _('complete an entire path')),
2313 ('n', 'normal', None, _('show only normal files')),
2326 ('n', 'normal', None, _('show only normal files')),
2314 ('a', 'added', None, _('show only added files')),
2327 ('a', 'added', None, _('show only added files')),
2315 ('r', 'removed', None, _('show only removed files'))],
2328 ('r', 'removed', None, _('show only removed files'))],
2316 _('FILESPEC...'))
2329 _('FILESPEC...'))
2317 def debugpathcomplete(ui, repo, *specs, **opts):
2330 def debugpathcomplete(ui, repo, *specs, **opts):
2318 '''complete part or all of a tracked path
2331 '''complete part or all of a tracked path
2319
2332
2320 This command supports shells that offer path name completion. It
2333 This command supports shells that offer path name completion. It
2321 currently completes only files already known to the dirstate.
2334 currently completes only files already known to the dirstate.
2322
2335
2323 Completion extends only to the next path segment unless
2336 Completion extends only to the next path segment unless
2324 --full is specified, in which case entire paths are used.'''
2337 --full is specified, in which case entire paths are used.'''
2325
2338
2326 def complete(path, acceptable):
2339 def complete(path, acceptable):
2327 dirstate = repo.dirstate
2340 dirstate = repo.dirstate
2328 spec = os.path.normpath(os.path.join(os.getcwd(), path))
2341 spec = os.path.normpath(os.path.join(os.getcwd(), path))
2329 rootdir = repo.root + os.sep
2342 rootdir = repo.root + os.sep
2330 if spec != repo.root and not spec.startswith(rootdir):
2343 if spec != repo.root and not spec.startswith(rootdir):
2331 return [], []
2344 return [], []
2332 if os.path.isdir(spec):
2345 if os.path.isdir(spec):
2333 spec += '/'
2346 spec += '/'
2334 spec = spec[len(rootdir):]
2347 spec = spec[len(rootdir):]
2335 fixpaths = os.sep != '/'
2348 fixpaths = os.sep != '/'
2336 if fixpaths:
2349 if fixpaths:
2337 spec = spec.replace(os.sep, '/')
2350 spec = spec.replace(os.sep, '/')
2338 speclen = len(spec)
2351 speclen = len(spec)
2339 fullpaths = opts['full']
2352 fullpaths = opts['full']
2340 files, dirs = set(), set()
2353 files, dirs = set(), set()
2341 adddir, addfile = dirs.add, files.add
2354 adddir, addfile = dirs.add, files.add
2342 for f, st in dirstate.iteritems():
2355 for f, st in dirstate.iteritems():
2343 if f.startswith(spec) and st[0] in acceptable:
2356 if f.startswith(spec) and st[0] in acceptable:
2344 if fixpaths:
2357 if fixpaths:
2345 f = f.replace('/', os.sep)
2358 f = f.replace('/', os.sep)
2346 if fullpaths:
2359 if fullpaths:
2347 addfile(f)
2360 addfile(f)
2348 continue
2361 continue
2349 s = f.find(os.sep, speclen)
2362 s = f.find(os.sep, speclen)
2350 if s >= 0:
2363 if s >= 0:
2351 adddir(f[:s])
2364 adddir(f[:s])
2352 else:
2365 else:
2353 addfile(f)
2366 addfile(f)
2354 return files, dirs
2367 return files, dirs
2355
2368
2356 acceptable = ''
2369 acceptable = ''
2357 if opts['normal']:
2370 if opts['normal']:
2358 acceptable += 'nm'
2371 acceptable += 'nm'
2359 if opts['added']:
2372 if opts['added']:
2360 acceptable += 'a'
2373 acceptable += 'a'
2361 if opts['removed']:
2374 if opts['removed']:
2362 acceptable += 'r'
2375 acceptable += 'r'
2363 cwd = repo.getcwd()
2376 cwd = repo.getcwd()
2364 if not specs:
2377 if not specs:
2365 specs = ['.']
2378 specs = ['.']
2366
2379
2367 files, dirs = set(), set()
2380 files, dirs = set(), set()
2368 for spec in specs:
2381 for spec in specs:
2369 f, d = complete(spec, acceptable or 'nmar')
2382 f, d = complete(spec, acceptable or 'nmar')
2370 files.update(f)
2383 files.update(f)
2371 dirs.update(d)
2384 dirs.update(d)
2372 files.update(dirs)
2385 files.update(dirs)
2373 ui.write('\n'.join(repo.pathto(p, cwd) for p in sorted(files)))
2386 ui.write('\n'.join(repo.pathto(p, cwd) for p in sorted(files)))
2374 ui.write('\n')
2387 ui.write('\n')
2375
2388
2376 @command('debugpushkey', [], _('REPO NAMESPACE [KEY OLD NEW]'))
2389 @command('debugpushkey', [], _('REPO NAMESPACE [KEY OLD NEW]'))
2377 def debugpushkey(ui, repopath, namespace, *keyinfo, **opts):
2390 def debugpushkey(ui, repopath, namespace, *keyinfo, **opts):
2378 '''access the pushkey key/value protocol
2391 '''access the pushkey key/value protocol
2379
2392
2380 With two args, list the keys in the given namespace.
2393 With two args, list the keys in the given namespace.
2381
2394
2382 With five args, set a key to new if it currently is set to old.
2395 With five args, set a key to new if it currently is set to old.
2383 Reports success or failure.
2396 Reports success or failure.
2384 '''
2397 '''
2385
2398
2386 target = hg.peer(ui, {}, repopath)
2399 target = hg.peer(ui, {}, repopath)
2387 if keyinfo:
2400 if keyinfo:
2388 key, old, new = keyinfo
2401 key, old, new = keyinfo
2389 r = target.pushkey(namespace, key, old, new)
2402 r = target.pushkey(namespace, key, old, new)
2390 ui.status(str(r) + '\n')
2403 ui.status(str(r) + '\n')
2391 return not r
2404 return not r
2392 else:
2405 else:
2393 for k, v in sorted(target.listkeys(namespace).iteritems()):
2406 for k, v in sorted(target.listkeys(namespace).iteritems()):
2394 ui.write("%s\t%s\n" % (k.encode('string-escape'),
2407 ui.write("%s\t%s\n" % (k.encode('string-escape'),
2395 v.encode('string-escape')))
2408 v.encode('string-escape')))
2396
2409
2397 @command('debugpvec', [], _('A B'))
2410 @command('debugpvec', [], _('A B'))
2398 def debugpvec(ui, repo, a, b=None):
2411 def debugpvec(ui, repo, a, b=None):
2399 ca = scmutil.revsingle(repo, a)
2412 ca = scmutil.revsingle(repo, a)
2400 cb = scmutil.revsingle(repo, b)
2413 cb = scmutil.revsingle(repo, b)
2401 pa = pvec.ctxpvec(ca)
2414 pa = pvec.ctxpvec(ca)
2402 pb = pvec.ctxpvec(cb)
2415 pb = pvec.ctxpvec(cb)
2403 if pa == pb:
2416 if pa == pb:
2404 rel = "="
2417 rel = "="
2405 elif pa > pb:
2418 elif pa > pb:
2406 rel = ">"
2419 rel = ">"
2407 elif pa < pb:
2420 elif pa < pb:
2408 rel = "<"
2421 rel = "<"
2409 elif pa | pb:
2422 elif pa | pb:
2410 rel = "|"
2423 rel = "|"
2411 ui.write(_("a: %s\n") % pa)
2424 ui.write(_("a: %s\n") % pa)
2412 ui.write(_("b: %s\n") % pb)
2425 ui.write(_("b: %s\n") % pb)
2413 ui.write(_("depth(a): %d depth(b): %d\n") % (pa._depth, pb._depth))
2426 ui.write(_("depth(a): %d depth(b): %d\n") % (pa._depth, pb._depth))
2414 ui.write(_("delta: %d hdist: %d distance: %d relation: %s\n") %
2427 ui.write(_("delta: %d hdist: %d distance: %d relation: %s\n") %
2415 (abs(pa._depth - pb._depth), pvec._hamming(pa._vec, pb._vec),
2428 (abs(pa._depth - pb._depth), pvec._hamming(pa._vec, pb._vec),
2416 pa.distance(pb), rel))
2429 pa.distance(pb), rel))
2417
2430
2418 @command('debugrebuilddirstate|debugrebuildstate',
2431 @command('debugrebuilddirstate|debugrebuildstate',
2419 [('r', 'rev', '', _('revision to rebuild to'), _('REV'))],
2432 [('r', 'rev', '', _('revision to rebuild to'), _('REV'))],
2420 _('[-r REV]'))
2433 _('[-r REV]'))
2421 def debugrebuilddirstate(ui, repo, rev):
2434 def debugrebuilddirstate(ui, repo, rev):
2422 """rebuild the dirstate as it would look like for the given revision
2435 """rebuild the dirstate as it would look like for the given revision
2423
2436
2424 If no revision is specified the first current parent will be used.
2437 If no revision is specified the first current parent will be used.
2425
2438
2426 The dirstate will be set to the files of the given revision.
2439 The dirstate will be set to the files of the given revision.
2427 The actual working directory content or existing dirstate
2440 The actual working directory content or existing dirstate
2428 information such as adds or removes is not considered.
2441 information such as adds or removes is not considered.
2429
2442
2430 One use of this command is to make the next :hg:`status` invocation
2443 One use of this command is to make the next :hg:`status` invocation
2431 check the actual file content.
2444 check the actual file content.
2432 """
2445 """
2433 ctx = scmutil.revsingle(repo, rev)
2446 ctx = scmutil.revsingle(repo, rev)
2434 wlock = repo.wlock()
2447 wlock = repo.wlock()
2435 try:
2448 try:
2436 repo.dirstate.rebuild(ctx.node(), ctx.manifest())
2449 repo.dirstate.rebuild(ctx.node(), ctx.manifest())
2437 finally:
2450 finally:
2438 wlock.release()
2451 wlock.release()
2439
2452
2440 @command('debugrename',
2453 @command('debugrename',
2441 [('r', 'rev', '', _('revision to debug'), _('REV'))],
2454 [('r', 'rev', '', _('revision to debug'), _('REV'))],
2442 _('[-r REV] FILE'))
2455 _('[-r REV] FILE'))
2443 def debugrename(ui, repo, file1, *pats, **opts):
2456 def debugrename(ui, repo, file1, *pats, **opts):
2444 """dump rename information"""
2457 """dump rename information"""
2445
2458
2446 ctx = scmutil.revsingle(repo, opts.get('rev'))
2459 ctx = scmutil.revsingle(repo, opts.get('rev'))
2447 m = scmutil.match(ctx, (file1,) + pats, opts)
2460 m = scmutil.match(ctx, (file1,) + pats, opts)
2448 for abs in ctx.walk(m):
2461 for abs in ctx.walk(m):
2449 fctx = ctx[abs]
2462 fctx = ctx[abs]
2450 o = fctx.filelog().renamed(fctx.filenode())
2463 o = fctx.filelog().renamed(fctx.filenode())
2451 rel = m.rel(abs)
2464 rel = m.rel(abs)
2452 if o:
2465 if o:
2453 ui.write(_("%s renamed from %s:%s\n") % (rel, o[0], hex(o[1])))
2466 ui.write(_("%s renamed from %s:%s\n") % (rel, o[0], hex(o[1])))
2454 else:
2467 else:
2455 ui.write(_("%s not renamed\n") % rel)
2468 ui.write(_("%s not renamed\n") % rel)
2456
2469
2457 @command('debugrevlog',
2470 @command('debugrevlog',
2458 [('c', 'changelog', False, _('open changelog')),
2471 [('c', 'changelog', False, _('open changelog')),
2459 ('m', 'manifest', False, _('open manifest')),
2472 ('m', 'manifest', False, _('open manifest')),
2460 ('d', 'dump', False, _('dump index data'))],
2473 ('d', 'dump', False, _('dump index data'))],
2461 _('-c|-m|FILE'))
2474 _('-c|-m|FILE'))
2462 def debugrevlog(ui, repo, file_=None, **opts):
2475 def debugrevlog(ui, repo, file_=None, **opts):
2463 """show data and statistics about a revlog"""
2476 """show data and statistics about a revlog"""
2464 r = cmdutil.openrevlog(repo, 'debugrevlog', file_, opts)
2477 r = cmdutil.openrevlog(repo, 'debugrevlog', file_, opts)
2465
2478
2466 if opts.get("dump"):
2479 if opts.get("dump"):
2467 numrevs = len(r)
2480 numrevs = len(r)
2468 ui.write("# rev p1rev p2rev start end deltastart base p1 p2"
2481 ui.write("# rev p1rev p2rev start end deltastart base p1 p2"
2469 " rawsize totalsize compression heads\n")
2482 " rawsize totalsize compression heads\n")
2470 ts = 0
2483 ts = 0
2471 heads = set()
2484 heads = set()
2472 for rev in xrange(numrevs):
2485 for rev in xrange(numrevs):
2473 dbase = r.deltaparent(rev)
2486 dbase = r.deltaparent(rev)
2474 if dbase == -1:
2487 if dbase == -1:
2475 dbase = rev
2488 dbase = rev
2476 cbase = r.chainbase(rev)
2489 cbase = r.chainbase(rev)
2477 p1, p2 = r.parentrevs(rev)
2490 p1, p2 = r.parentrevs(rev)
2478 rs = r.rawsize(rev)
2491 rs = r.rawsize(rev)
2479 ts = ts + rs
2492 ts = ts + rs
2480 heads -= set(r.parentrevs(rev))
2493 heads -= set(r.parentrevs(rev))
2481 heads.add(rev)
2494 heads.add(rev)
2482 ui.write("%d %d %d %d %d %d %d %d %d %d %d %d %d\n" %
2495 ui.write("%d %d %d %d %d %d %d %d %d %d %d %d %d\n" %
2483 (rev, p1, p2, r.start(rev), r.end(rev),
2496 (rev, p1, p2, r.start(rev), r.end(rev),
2484 r.start(dbase), r.start(cbase),
2497 r.start(dbase), r.start(cbase),
2485 r.start(p1), r.start(p2),
2498 r.start(p1), r.start(p2),
2486 rs, ts, ts / r.end(rev), len(heads)))
2499 rs, ts, ts / r.end(rev), len(heads)))
2487 return 0
2500 return 0
2488
2501
2489 v = r.version
2502 v = r.version
2490 format = v & 0xFFFF
2503 format = v & 0xFFFF
2491 flags = []
2504 flags = []
2492 gdelta = False
2505 gdelta = False
2493 if v & revlog.REVLOGNGINLINEDATA:
2506 if v & revlog.REVLOGNGINLINEDATA:
2494 flags.append('inline')
2507 flags.append('inline')
2495 if v & revlog.REVLOGGENERALDELTA:
2508 if v & revlog.REVLOGGENERALDELTA:
2496 gdelta = True
2509 gdelta = True
2497 flags.append('generaldelta')
2510 flags.append('generaldelta')
2498 if not flags:
2511 if not flags:
2499 flags = ['(none)']
2512 flags = ['(none)']
2500
2513
2501 nummerges = 0
2514 nummerges = 0
2502 numfull = 0
2515 numfull = 0
2503 numprev = 0
2516 numprev = 0
2504 nump1 = 0
2517 nump1 = 0
2505 nump2 = 0
2518 nump2 = 0
2506 numother = 0
2519 numother = 0
2507 nump1prev = 0
2520 nump1prev = 0
2508 nump2prev = 0
2521 nump2prev = 0
2509 chainlengths = []
2522 chainlengths = []
2510
2523
2511 datasize = [None, 0, 0L]
2524 datasize = [None, 0, 0L]
2512 fullsize = [None, 0, 0L]
2525 fullsize = [None, 0, 0L]
2513 deltasize = [None, 0, 0L]
2526 deltasize = [None, 0, 0L]
2514
2527
2515 def addsize(size, l):
2528 def addsize(size, l):
2516 if l[0] is None or size < l[0]:
2529 if l[0] is None or size < l[0]:
2517 l[0] = size
2530 l[0] = size
2518 if size > l[1]:
2531 if size > l[1]:
2519 l[1] = size
2532 l[1] = size
2520 l[2] += size
2533 l[2] += size
2521
2534
2522 numrevs = len(r)
2535 numrevs = len(r)
2523 for rev in xrange(numrevs):
2536 for rev in xrange(numrevs):
2524 p1, p2 = r.parentrevs(rev)
2537 p1, p2 = r.parentrevs(rev)
2525 delta = r.deltaparent(rev)
2538 delta = r.deltaparent(rev)
2526 if format > 0:
2539 if format > 0:
2527 addsize(r.rawsize(rev), datasize)
2540 addsize(r.rawsize(rev), datasize)
2528 if p2 != nullrev:
2541 if p2 != nullrev:
2529 nummerges += 1
2542 nummerges += 1
2530 size = r.length(rev)
2543 size = r.length(rev)
2531 if delta == nullrev:
2544 if delta == nullrev:
2532 chainlengths.append(0)
2545 chainlengths.append(0)
2533 numfull += 1
2546 numfull += 1
2534 addsize(size, fullsize)
2547 addsize(size, fullsize)
2535 else:
2548 else:
2536 chainlengths.append(chainlengths[delta] + 1)
2549 chainlengths.append(chainlengths[delta] + 1)
2537 addsize(size, deltasize)
2550 addsize(size, deltasize)
2538 if delta == rev - 1:
2551 if delta == rev - 1:
2539 numprev += 1
2552 numprev += 1
2540 if delta == p1:
2553 if delta == p1:
2541 nump1prev += 1
2554 nump1prev += 1
2542 elif delta == p2:
2555 elif delta == p2:
2543 nump2prev += 1
2556 nump2prev += 1
2544 elif delta == p1:
2557 elif delta == p1:
2545 nump1 += 1
2558 nump1 += 1
2546 elif delta == p2:
2559 elif delta == p2:
2547 nump2 += 1
2560 nump2 += 1
2548 elif delta != nullrev:
2561 elif delta != nullrev:
2549 numother += 1
2562 numother += 1
2550
2563
2551 # Adjust size min value for empty cases
2564 # Adjust size min value for empty cases
2552 for size in (datasize, fullsize, deltasize):
2565 for size in (datasize, fullsize, deltasize):
2553 if size[0] is None:
2566 if size[0] is None:
2554 size[0] = 0
2567 size[0] = 0
2555
2568
2556 numdeltas = numrevs - numfull
2569 numdeltas = numrevs - numfull
2557 numoprev = numprev - nump1prev - nump2prev
2570 numoprev = numprev - nump1prev - nump2prev
2558 totalrawsize = datasize[2]
2571 totalrawsize = datasize[2]
2559 datasize[2] /= numrevs
2572 datasize[2] /= numrevs
2560 fulltotal = fullsize[2]
2573 fulltotal = fullsize[2]
2561 fullsize[2] /= numfull
2574 fullsize[2] /= numfull
2562 deltatotal = deltasize[2]
2575 deltatotal = deltasize[2]
2563 if numrevs - numfull > 0:
2576 if numrevs - numfull > 0:
2564 deltasize[2] /= numrevs - numfull
2577 deltasize[2] /= numrevs - numfull
2565 totalsize = fulltotal + deltatotal
2578 totalsize = fulltotal + deltatotal
2566 avgchainlen = sum(chainlengths) / numrevs
2579 avgchainlen = sum(chainlengths) / numrevs
2567 compratio = totalrawsize / totalsize
2580 compratio = totalrawsize / totalsize
2568
2581
2569 basedfmtstr = '%%%dd\n'
2582 basedfmtstr = '%%%dd\n'
2570 basepcfmtstr = '%%%dd %s(%%5.2f%%%%)\n'
2583 basepcfmtstr = '%%%dd %s(%%5.2f%%%%)\n'
2571
2584
2572 def dfmtstr(max):
2585 def dfmtstr(max):
2573 return basedfmtstr % len(str(max))
2586 return basedfmtstr % len(str(max))
2574 def pcfmtstr(max, padding=0):
2587 def pcfmtstr(max, padding=0):
2575 return basepcfmtstr % (len(str(max)), ' ' * padding)
2588 return basepcfmtstr % (len(str(max)), ' ' * padding)
2576
2589
2577 def pcfmt(value, total):
2590 def pcfmt(value, total):
2578 return (value, 100 * float(value) / total)
2591 return (value, 100 * float(value) / total)
2579
2592
2580 ui.write(('format : %d\n') % format)
2593 ui.write(('format : %d\n') % format)
2581 ui.write(('flags : %s\n') % ', '.join(flags))
2594 ui.write(('flags : %s\n') % ', '.join(flags))
2582
2595
2583 ui.write('\n')
2596 ui.write('\n')
2584 fmt = pcfmtstr(totalsize)
2597 fmt = pcfmtstr(totalsize)
2585 fmt2 = dfmtstr(totalsize)
2598 fmt2 = dfmtstr(totalsize)
2586 ui.write(('revisions : ') + fmt2 % numrevs)
2599 ui.write(('revisions : ') + fmt2 % numrevs)
2587 ui.write((' merges : ') + fmt % pcfmt(nummerges, numrevs))
2600 ui.write((' merges : ') + fmt % pcfmt(nummerges, numrevs))
2588 ui.write((' normal : ') + fmt % pcfmt(numrevs - nummerges, numrevs))
2601 ui.write((' normal : ') + fmt % pcfmt(numrevs - nummerges, numrevs))
2589 ui.write(('revisions : ') + fmt2 % numrevs)
2602 ui.write(('revisions : ') + fmt2 % numrevs)
2590 ui.write((' full : ') + fmt % pcfmt(numfull, numrevs))
2603 ui.write((' full : ') + fmt % pcfmt(numfull, numrevs))
2591 ui.write((' deltas : ') + fmt % pcfmt(numdeltas, numrevs))
2604 ui.write((' deltas : ') + fmt % pcfmt(numdeltas, numrevs))
2592 ui.write(('revision size : ') + fmt2 % totalsize)
2605 ui.write(('revision size : ') + fmt2 % totalsize)
2593 ui.write((' full : ') + fmt % pcfmt(fulltotal, totalsize))
2606 ui.write((' full : ') + fmt % pcfmt(fulltotal, totalsize))
2594 ui.write((' deltas : ') + fmt % pcfmt(deltatotal, totalsize))
2607 ui.write((' deltas : ') + fmt % pcfmt(deltatotal, totalsize))
2595
2608
2596 ui.write('\n')
2609 ui.write('\n')
2597 fmt = dfmtstr(max(avgchainlen, compratio))
2610 fmt = dfmtstr(max(avgchainlen, compratio))
2598 ui.write(('avg chain length : ') + fmt % avgchainlen)
2611 ui.write(('avg chain length : ') + fmt % avgchainlen)
2599 ui.write(('compression ratio : ') + fmt % compratio)
2612 ui.write(('compression ratio : ') + fmt % compratio)
2600
2613
2601 if format > 0:
2614 if format > 0:
2602 ui.write('\n')
2615 ui.write('\n')
2603 ui.write(('uncompressed data size (min/max/avg) : %d / %d / %d\n')
2616 ui.write(('uncompressed data size (min/max/avg) : %d / %d / %d\n')
2604 % tuple(datasize))
2617 % tuple(datasize))
2605 ui.write(('full revision size (min/max/avg) : %d / %d / %d\n')
2618 ui.write(('full revision size (min/max/avg) : %d / %d / %d\n')
2606 % tuple(fullsize))
2619 % tuple(fullsize))
2607 ui.write(('delta size (min/max/avg) : %d / %d / %d\n')
2620 ui.write(('delta size (min/max/avg) : %d / %d / %d\n')
2608 % tuple(deltasize))
2621 % tuple(deltasize))
2609
2622
2610 if numdeltas > 0:
2623 if numdeltas > 0:
2611 ui.write('\n')
2624 ui.write('\n')
2612 fmt = pcfmtstr(numdeltas)
2625 fmt = pcfmtstr(numdeltas)
2613 fmt2 = pcfmtstr(numdeltas, 4)
2626 fmt2 = pcfmtstr(numdeltas, 4)
2614 ui.write(('deltas against prev : ') + fmt % pcfmt(numprev, numdeltas))
2627 ui.write(('deltas against prev : ') + fmt % pcfmt(numprev, numdeltas))
2615 if numprev > 0:
2628 if numprev > 0:
2616 ui.write((' where prev = p1 : ') + fmt2 % pcfmt(nump1prev,
2629 ui.write((' where prev = p1 : ') + fmt2 % pcfmt(nump1prev,
2617 numprev))
2630 numprev))
2618 ui.write((' where prev = p2 : ') + fmt2 % pcfmt(nump2prev,
2631 ui.write((' where prev = p2 : ') + fmt2 % pcfmt(nump2prev,
2619 numprev))
2632 numprev))
2620 ui.write((' other : ') + fmt2 % pcfmt(numoprev,
2633 ui.write((' other : ') + fmt2 % pcfmt(numoprev,
2621 numprev))
2634 numprev))
2622 if gdelta:
2635 if gdelta:
2623 ui.write(('deltas against p1 : ')
2636 ui.write(('deltas against p1 : ')
2624 + fmt % pcfmt(nump1, numdeltas))
2637 + fmt % pcfmt(nump1, numdeltas))
2625 ui.write(('deltas against p2 : ')
2638 ui.write(('deltas against p2 : ')
2626 + fmt % pcfmt(nump2, numdeltas))
2639 + fmt % pcfmt(nump2, numdeltas))
2627 ui.write(('deltas against other : ') + fmt % pcfmt(numother,
2640 ui.write(('deltas against other : ') + fmt % pcfmt(numother,
2628 numdeltas))
2641 numdeltas))
2629
2642
2630 @command('debugrevspec',
2643 @command('debugrevspec',
2631 [('', 'optimize', None, _('print parsed tree after optimizing'))],
2644 [('', 'optimize', None, _('print parsed tree after optimizing'))],
2632 ('REVSPEC'))
2645 ('REVSPEC'))
2633 def debugrevspec(ui, repo, expr, **opts):
2646 def debugrevspec(ui, repo, expr, **opts):
2634 """parse and apply a revision specification
2647 """parse and apply a revision specification
2635
2648
2636 Use --verbose to print the parsed tree before and after aliases
2649 Use --verbose to print the parsed tree before and after aliases
2637 expansion.
2650 expansion.
2638 """
2651 """
2639 if ui.verbose:
2652 if ui.verbose:
2640 tree = revset.parse(expr)[0]
2653 tree = revset.parse(expr)[0]
2641 ui.note(revset.prettyformat(tree), "\n")
2654 ui.note(revset.prettyformat(tree), "\n")
2642 newtree = revset.findaliases(ui, tree)
2655 newtree = revset.findaliases(ui, tree)
2643 if newtree != tree:
2656 if newtree != tree:
2644 ui.note(revset.prettyformat(newtree), "\n")
2657 ui.note(revset.prettyformat(newtree), "\n")
2645 if opts["optimize"]:
2658 if opts["optimize"]:
2646 weight, optimizedtree = revset.optimize(newtree, True)
2659 weight, optimizedtree = revset.optimize(newtree, True)
2647 ui.note("* optimized:\n", revset.prettyformat(optimizedtree), "\n")
2660 ui.note("* optimized:\n", revset.prettyformat(optimizedtree), "\n")
2648 func = revset.match(ui, expr)
2661 func = revset.match(ui, expr)
2649 for c in func(repo, revset.spanset(repo)):
2662 for c in func(repo, revset.spanset(repo)):
2650 ui.write("%s\n" % c)
2663 ui.write("%s\n" % c)
2651
2664
2652 @command('debugsetparents', [], _('REV1 [REV2]'))
2665 @command('debugsetparents', [], _('REV1 [REV2]'))
2653 def debugsetparents(ui, repo, rev1, rev2=None):
2666 def debugsetparents(ui, repo, rev1, rev2=None):
2654 """manually set the parents of the current working directory
2667 """manually set the parents of the current working directory
2655
2668
2656 This is useful for writing repository conversion tools, but should
2669 This is useful for writing repository conversion tools, but should
2657 be used with care.
2670 be used with care.
2658
2671
2659 Returns 0 on success.
2672 Returns 0 on success.
2660 """
2673 """
2661
2674
2662 r1 = scmutil.revsingle(repo, rev1).node()
2675 r1 = scmutil.revsingle(repo, rev1).node()
2663 r2 = scmutil.revsingle(repo, rev2, 'null').node()
2676 r2 = scmutil.revsingle(repo, rev2, 'null').node()
2664
2677
2665 wlock = repo.wlock()
2678 wlock = repo.wlock()
2666 try:
2679 try:
2667 repo.setparents(r1, r2)
2680 repo.setparents(r1, r2)
2668 finally:
2681 finally:
2669 wlock.release()
2682 wlock.release()
2670
2683
2671 @command('debugdirstate|debugstate',
2684 @command('debugdirstate|debugstate',
2672 [('', 'nodates', None, _('do not display the saved mtime')),
2685 [('', 'nodates', None, _('do not display the saved mtime')),
2673 ('', 'datesort', None, _('sort by saved mtime'))],
2686 ('', 'datesort', None, _('sort by saved mtime'))],
2674 _('[OPTION]...'))
2687 _('[OPTION]...'))
2675 def debugstate(ui, repo, nodates=None, datesort=None):
2688 def debugstate(ui, repo, nodates=None, datesort=None):
2676 """show the contents of the current dirstate"""
2689 """show the contents of the current dirstate"""
2677 timestr = ""
2690 timestr = ""
2678 showdate = not nodates
2691 showdate = not nodates
2679 if datesort:
2692 if datesort:
2680 keyfunc = lambda x: (x[1][3], x[0]) # sort by mtime, then by filename
2693 keyfunc = lambda x: (x[1][3], x[0]) # sort by mtime, then by filename
2681 else:
2694 else:
2682 keyfunc = None # sort by filename
2695 keyfunc = None # sort by filename
2683 for file_, ent in sorted(repo.dirstate._map.iteritems(), key=keyfunc):
2696 for file_, ent in sorted(repo.dirstate._map.iteritems(), key=keyfunc):
2684 if showdate:
2697 if showdate:
2685 if ent[3] == -1:
2698 if ent[3] == -1:
2686 # Pad or slice to locale representation
2699 # Pad or slice to locale representation
2687 locale_len = len(time.strftime("%Y-%m-%d %H:%M:%S ",
2700 locale_len = len(time.strftime("%Y-%m-%d %H:%M:%S ",
2688 time.localtime(0)))
2701 time.localtime(0)))
2689 timestr = 'unset'
2702 timestr = 'unset'
2690 timestr = (timestr[:locale_len] +
2703 timestr = (timestr[:locale_len] +
2691 ' ' * (locale_len - len(timestr)))
2704 ' ' * (locale_len - len(timestr)))
2692 else:
2705 else:
2693 timestr = time.strftime("%Y-%m-%d %H:%M:%S ",
2706 timestr = time.strftime("%Y-%m-%d %H:%M:%S ",
2694 time.localtime(ent[3]))
2707 time.localtime(ent[3]))
2695 if ent[1] & 020000:
2708 if ent[1] & 020000:
2696 mode = 'lnk'
2709 mode = 'lnk'
2697 else:
2710 else:
2698 mode = '%3o' % (ent[1] & 0777 & ~util.umask)
2711 mode = '%3o' % (ent[1] & 0777 & ~util.umask)
2699 ui.write("%c %s %10d %s%s\n" % (ent[0], mode, ent[2], timestr, file_))
2712 ui.write("%c %s %10d %s%s\n" % (ent[0], mode, ent[2], timestr, file_))
2700 for f in repo.dirstate.copies():
2713 for f in repo.dirstate.copies():
2701 ui.write(_("copy: %s -> %s\n") % (repo.dirstate.copied(f), f))
2714 ui.write(_("copy: %s -> %s\n") % (repo.dirstate.copied(f), f))
2702
2715
2703 @command('debugsub',
2716 @command('debugsub',
2704 [('r', 'rev', '',
2717 [('r', 'rev', '',
2705 _('revision to check'), _('REV'))],
2718 _('revision to check'), _('REV'))],
2706 _('[-r REV] [REV]'))
2719 _('[-r REV] [REV]'))
2707 def debugsub(ui, repo, rev=None):
2720 def debugsub(ui, repo, rev=None):
2708 ctx = scmutil.revsingle(repo, rev, None)
2721 ctx = scmutil.revsingle(repo, rev, None)
2709 for k, v in sorted(ctx.substate.items()):
2722 for k, v in sorted(ctx.substate.items()):
2710 ui.write(('path %s\n') % k)
2723 ui.write(('path %s\n') % k)
2711 ui.write((' source %s\n') % v[0])
2724 ui.write((' source %s\n') % v[0])
2712 ui.write((' revision %s\n') % v[1])
2725 ui.write((' revision %s\n') % v[1])
2713
2726
2714 @command('debugsuccessorssets',
2727 @command('debugsuccessorssets',
2715 [],
2728 [],
2716 _('[REV]'))
2729 _('[REV]'))
2717 def debugsuccessorssets(ui, repo, *revs):
2730 def debugsuccessorssets(ui, repo, *revs):
2718 """show set of successors for revision
2731 """show set of successors for revision
2719
2732
2720 A successors set of changeset A is a consistent group of revisions that
2733 A successors set of changeset A is a consistent group of revisions that
2721 succeed A. It contains non-obsolete changesets only.
2734 succeed A. It contains non-obsolete changesets only.
2722
2735
2723 In most cases a changeset A has a single successors set containing a single
2736 In most cases a changeset A has a single successors set containing a single
2724 successor (changeset A replaced by A').
2737 successor (changeset A replaced by A').
2725
2738
2726 A changeset that is made obsolete with no successors are called "pruned".
2739 A changeset that is made obsolete with no successors are called "pruned".
2727 Such changesets have no successors sets at all.
2740 Such changesets have no successors sets at all.
2728
2741
2729 A changeset that has been "split" will have a successors set containing
2742 A changeset that has been "split" will have a successors set containing
2730 more than one successor.
2743 more than one successor.
2731
2744
2732 A changeset that has been rewritten in multiple different ways is called
2745 A changeset that has been rewritten in multiple different ways is called
2733 "divergent". Such changesets have multiple successor sets (each of which
2746 "divergent". Such changesets have multiple successor sets (each of which
2734 may also be split, i.e. have multiple successors).
2747 may also be split, i.e. have multiple successors).
2735
2748
2736 Results are displayed as follows::
2749 Results are displayed as follows::
2737
2750
2738 <rev1>
2751 <rev1>
2739 <successors-1A>
2752 <successors-1A>
2740 <rev2>
2753 <rev2>
2741 <successors-2A>
2754 <successors-2A>
2742 <successors-2B1> <successors-2B2> <successors-2B3>
2755 <successors-2B1> <successors-2B2> <successors-2B3>
2743
2756
2744 Here rev2 has two possible (i.e. divergent) successors sets. The first
2757 Here rev2 has two possible (i.e. divergent) successors sets. The first
2745 holds one element, whereas the second holds three (i.e. the changeset has
2758 holds one element, whereas the second holds three (i.e. the changeset has
2746 been split).
2759 been split).
2747 """
2760 """
2748 # passed to successorssets caching computation from one call to another
2761 # passed to successorssets caching computation from one call to another
2749 cache = {}
2762 cache = {}
2750 ctx2str = str
2763 ctx2str = str
2751 node2str = short
2764 node2str = short
2752 if ui.debug():
2765 if ui.debug():
2753 def ctx2str(ctx):
2766 def ctx2str(ctx):
2754 return ctx.hex()
2767 return ctx.hex()
2755 node2str = hex
2768 node2str = hex
2756 for rev in scmutil.revrange(repo, revs):
2769 for rev in scmutil.revrange(repo, revs):
2757 ctx = repo[rev]
2770 ctx = repo[rev]
2758 ui.write('%s\n'% ctx2str(ctx))
2771 ui.write('%s\n'% ctx2str(ctx))
2759 for succsset in obsolete.successorssets(repo, ctx.node(), cache):
2772 for succsset in obsolete.successorssets(repo, ctx.node(), cache):
2760 if succsset:
2773 if succsset:
2761 ui.write(' ')
2774 ui.write(' ')
2762 ui.write(node2str(succsset[0]))
2775 ui.write(node2str(succsset[0]))
2763 for node in succsset[1:]:
2776 for node in succsset[1:]:
2764 ui.write(' ')
2777 ui.write(' ')
2765 ui.write(node2str(node))
2778 ui.write(node2str(node))
2766 ui.write('\n')
2779 ui.write('\n')
2767
2780
2768 @command('debugwalk', walkopts, _('[OPTION]... [FILE]...'))
2781 @command('debugwalk', walkopts, _('[OPTION]... [FILE]...'))
2769 def debugwalk(ui, repo, *pats, **opts):
2782 def debugwalk(ui, repo, *pats, **opts):
2770 """show how files match on given patterns"""
2783 """show how files match on given patterns"""
2771 m = scmutil.match(repo[None], pats, opts)
2784 m = scmutil.match(repo[None], pats, opts)
2772 items = list(repo.walk(m))
2785 items = list(repo.walk(m))
2773 if not items:
2786 if not items:
2774 return
2787 return
2775 f = lambda fn: fn
2788 f = lambda fn: fn
2776 if ui.configbool('ui', 'slash') and os.sep != '/':
2789 if ui.configbool('ui', 'slash') and os.sep != '/':
2777 f = lambda fn: util.normpath(fn)
2790 f = lambda fn: util.normpath(fn)
2778 fmt = 'f %%-%ds %%-%ds %%s' % (
2791 fmt = 'f %%-%ds %%-%ds %%s' % (
2779 max([len(abs) for abs in items]),
2792 max([len(abs) for abs in items]),
2780 max([len(m.rel(abs)) for abs in items]))
2793 max([len(m.rel(abs)) for abs in items]))
2781 for abs in items:
2794 for abs in items:
2782 line = fmt % (abs, f(m.rel(abs)), m.exact(abs) and 'exact' or '')
2795 line = fmt % (abs, f(m.rel(abs)), m.exact(abs) and 'exact' or '')
2783 ui.write("%s\n" % line.rstrip())
2796 ui.write("%s\n" % line.rstrip())
2784
2797
2785 @command('debugwireargs',
2798 @command('debugwireargs',
2786 [('', 'three', '', 'three'),
2799 [('', 'three', '', 'three'),
2787 ('', 'four', '', 'four'),
2800 ('', 'four', '', 'four'),
2788 ('', 'five', '', 'five'),
2801 ('', 'five', '', 'five'),
2789 ] + remoteopts,
2802 ] + remoteopts,
2790 _('REPO [OPTIONS]... [ONE [TWO]]'))
2803 _('REPO [OPTIONS]... [ONE [TWO]]'))
2791 def debugwireargs(ui, repopath, *vals, **opts):
2804 def debugwireargs(ui, repopath, *vals, **opts):
2792 repo = hg.peer(ui, opts, repopath)
2805 repo = hg.peer(ui, opts, repopath)
2793 for opt in remoteopts:
2806 for opt in remoteopts:
2794 del opts[opt[1]]
2807 del opts[opt[1]]
2795 args = {}
2808 args = {}
2796 for k, v in opts.iteritems():
2809 for k, v in opts.iteritems():
2797 if v:
2810 if v:
2798 args[k] = v
2811 args[k] = v
2799 # run twice to check that we don't mess up the stream for the next command
2812 # run twice to check that we don't mess up the stream for the next command
2800 res1 = repo.debugwireargs(*vals, **args)
2813 res1 = repo.debugwireargs(*vals, **args)
2801 res2 = repo.debugwireargs(*vals, **args)
2814 res2 = repo.debugwireargs(*vals, **args)
2802 ui.write("%s\n" % res1)
2815 ui.write("%s\n" % res1)
2803 if res1 != res2:
2816 if res1 != res2:
2804 ui.warn("%s\n" % res2)
2817 ui.warn("%s\n" % res2)
2805
2818
2806 @command('^diff',
2819 @command('^diff',
2807 [('r', 'rev', [], _('revision'), _('REV')),
2820 [('r', 'rev', [], _('revision'), _('REV')),
2808 ('c', 'change', '', _('change made by revision'), _('REV'))
2821 ('c', 'change', '', _('change made by revision'), _('REV'))
2809 ] + diffopts + diffopts2 + walkopts + subrepoopts,
2822 ] + diffopts + diffopts2 + walkopts + subrepoopts,
2810 _('[OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...'))
2823 _('[OPTION]... ([-c REV] | [-r REV1 [-r REV2]]) [FILE]...'))
2811 def diff(ui, repo, *pats, **opts):
2824 def diff(ui, repo, *pats, **opts):
2812 """diff repository (or selected files)
2825 """diff repository (or selected files)
2813
2826
2814 Show differences between revisions for the specified files.
2827 Show differences between revisions for the specified files.
2815
2828
2816 Differences between files are shown using the unified diff format.
2829 Differences between files are shown using the unified diff format.
2817
2830
2818 .. note::
2831 .. note::
2819
2832
2820 diff may generate unexpected results for merges, as it will
2833 diff may generate unexpected results for merges, as it will
2821 default to comparing against the working directory's first
2834 default to comparing against the working directory's first
2822 parent changeset if no revisions are specified.
2835 parent changeset if no revisions are specified.
2823
2836
2824 When two revision arguments are given, then changes are shown
2837 When two revision arguments are given, then changes are shown
2825 between those revisions. If only one revision is specified then
2838 between those revisions. If only one revision is specified then
2826 that revision is compared to the working directory, and, when no
2839 that revision is compared to the working directory, and, when no
2827 revisions are specified, the working directory files are compared
2840 revisions are specified, the working directory files are compared
2828 to its parent.
2841 to its parent.
2829
2842
2830 Alternatively you can specify -c/--change with a revision to see
2843 Alternatively you can specify -c/--change with a revision to see
2831 the changes in that changeset relative to its first parent.
2844 the changes in that changeset relative to its first parent.
2832
2845
2833 Without the -a/--text option, diff will avoid generating diffs of
2846 Without the -a/--text option, diff will avoid generating diffs of
2834 files it detects as binary. With -a, diff will generate a diff
2847 files it detects as binary. With -a, diff will generate a diff
2835 anyway, probably with undesirable results.
2848 anyway, probably with undesirable results.
2836
2849
2837 Use the -g/--git option to generate diffs in the git extended diff
2850 Use the -g/--git option to generate diffs in the git extended diff
2838 format. For more information, read :hg:`help diffs`.
2851 format. For more information, read :hg:`help diffs`.
2839
2852
2840 .. container:: verbose
2853 .. container:: verbose
2841
2854
2842 Examples:
2855 Examples:
2843
2856
2844 - compare a file in the current working directory to its parent::
2857 - compare a file in the current working directory to its parent::
2845
2858
2846 hg diff foo.c
2859 hg diff foo.c
2847
2860
2848 - compare two historical versions of a directory, with rename info::
2861 - compare two historical versions of a directory, with rename info::
2849
2862
2850 hg diff --git -r 1.0:1.2 lib/
2863 hg diff --git -r 1.0:1.2 lib/
2851
2864
2852 - get change stats relative to the last change on some date::
2865 - get change stats relative to the last change on some date::
2853
2866
2854 hg diff --stat -r "date('may 2')"
2867 hg diff --stat -r "date('may 2')"
2855
2868
2856 - diff all newly-added files that contain a keyword::
2869 - diff all newly-added files that contain a keyword::
2857
2870
2858 hg diff "set:added() and grep(GNU)"
2871 hg diff "set:added() and grep(GNU)"
2859
2872
2860 - compare a revision and its parents::
2873 - compare a revision and its parents::
2861
2874
2862 hg diff -c 9353 # compare against first parent
2875 hg diff -c 9353 # compare against first parent
2863 hg diff -r 9353^:9353 # same using revset syntax
2876 hg diff -r 9353^:9353 # same using revset syntax
2864 hg diff -r 9353^2:9353 # compare against the second parent
2877 hg diff -r 9353^2:9353 # compare against the second parent
2865
2878
2866 Returns 0 on success.
2879 Returns 0 on success.
2867 """
2880 """
2868
2881
2869 revs = opts.get('rev')
2882 revs = opts.get('rev')
2870 change = opts.get('change')
2883 change = opts.get('change')
2871 stat = opts.get('stat')
2884 stat = opts.get('stat')
2872 reverse = opts.get('reverse')
2885 reverse = opts.get('reverse')
2873
2886
2874 if revs and change:
2887 if revs and change:
2875 msg = _('cannot specify --rev and --change at the same time')
2888 msg = _('cannot specify --rev and --change at the same time')
2876 raise util.Abort(msg)
2889 raise util.Abort(msg)
2877 elif change:
2890 elif change:
2878 node2 = scmutil.revsingle(repo, change, None).node()
2891 node2 = scmutil.revsingle(repo, change, None).node()
2879 node1 = repo[node2].p1().node()
2892 node1 = repo[node2].p1().node()
2880 else:
2893 else:
2881 node1, node2 = scmutil.revpair(repo, revs)
2894 node1, node2 = scmutil.revpair(repo, revs)
2882
2895
2883 if reverse:
2896 if reverse:
2884 node1, node2 = node2, node1
2897 node1, node2 = node2, node1
2885
2898
2886 diffopts = patch.diffopts(ui, opts)
2899 diffopts = patch.diffopts(ui, opts)
2887 m = scmutil.match(repo[node2], pats, opts)
2900 m = scmutil.match(repo[node2], pats, opts)
2888 cmdutil.diffordiffstat(ui, repo, diffopts, node1, node2, m, stat=stat,
2901 cmdutil.diffordiffstat(ui, repo, diffopts, node1, node2, m, stat=stat,
2889 listsubrepos=opts.get('subrepos'))
2902 listsubrepos=opts.get('subrepos'))
2890
2903
2891 @command('^export',
2904 @command('^export',
2892 [('o', 'output', '',
2905 [('o', 'output', '',
2893 _('print output to file with formatted name'), _('FORMAT')),
2906 _('print output to file with formatted name'), _('FORMAT')),
2894 ('', 'switch-parent', None, _('diff against the second parent')),
2907 ('', 'switch-parent', None, _('diff against the second parent')),
2895 ('r', 'rev', [], _('revisions to export'), _('REV')),
2908 ('r', 'rev', [], _('revisions to export'), _('REV')),
2896 ] + diffopts,
2909 ] + diffopts,
2897 _('[OPTION]... [-o OUTFILESPEC] [-r] [REV]...'))
2910 _('[OPTION]... [-o OUTFILESPEC] [-r] [REV]...'))
2898 def export(ui, repo, *changesets, **opts):
2911 def export(ui, repo, *changesets, **opts):
2899 """dump the header and diffs for one or more changesets
2912 """dump the header and diffs for one or more changesets
2900
2913
2901 Print the changeset header and diffs for one or more revisions.
2914 Print the changeset header and diffs for one or more revisions.
2902 If no revision is given, the parent of the working directory is used.
2915 If no revision is given, the parent of the working directory is used.
2903
2916
2904 The information shown in the changeset header is: author, date,
2917 The information shown in the changeset header is: author, date,
2905 branch name (if non-default), changeset hash, parent(s) and commit
2918 branch name (if non-default), changeset hash, parent(s) and commit
2906 comment.
2919 comment.
2907
2920
2908 .. note::
2921 .. note::
2909
2922
2910 export may generate unexpected diff output for merge
2923 export may generate unexpected diff output for merge
2911 changesets, as it will compare the merge changeset against its
2924 changesets, as it will compare the merge changeset against its
2912 first parent only.
2925 first parent only.
2913
2926
2914 Output may be to a file, in which case the name of the file is
2927 Output may be to a file, in which case the name of the file is
2915 given using a format string. The formatting rules are as follows:
2928 given using a format string. The formatting rules are as follows:
2916
2929
2917 :``%%``: literal "%" character
2930 :``%%``: literal "%" character
2918 :``%H``: changeset hash (40 hexadecimal digits)
2931 :``%H``: changeset hash (40 hexadecimal digits)
2919 :``%N``: number of patches being generated
2932 :``%N``: number of patches being generated
2920 :``%R``: changeset revision number
2933 :``%R``: changeset revision number
2921 :``%b``: basename of the exporting repository
2934 :``%b``: basename of the exporting repository
2922 :``%h``: short-form changeset hash (12 hexadecimal digits)
2935 :``%h``: short-form changeset hash (12 hexadecimal digits)
2923 :``%m``: first line of the commit message (only alphanumeric characters)
2936 :``%m``: first line of the commit message (only alphanumeric characters)
2924 :``%n``: zero-padded sequence number, starting at 1
2937 :``%n``: zero-padded sequence number, starting at 1
2925 :``%r``: zero-padded changeset revision number
2938 :``%r``: zero-padded changeset revision number
2926
2939
2927 Without the -a/--text option, export will avoid generating diffs
2940 Without the -a/--text option, export will avoid generating diffs
2928 of files it detects as binary. With -a, export will generate a
2941 of files it detects as binary. With -a, export will generate a
2929 diff anyway, probably with undesirable results.
2942 diff anyway, probably with undesirable results.
2930
2943
2931 Use the -g/--git option to generate diffs in the git extended diff
2944 Use the -g/--git option to generate diffs in the git extended diff
2932 format. See :hg:`help diffs` for more information.
2945 format. See :hg:`help diffs` for more information.
2933
2946
2934 With the --switch-parent option, the diff will be against the
2947 With the --switch-parent option, the diff will be against the
2935 second parent. It can be useful to review a merge.
2948 second parent. It can be useful to review a merge.
2936
2949
2937 .. container:: verbose
2950 .. container:: verbose
2938
2951
2939 Examples:
2952 Examples:
2940
2953
2941 - use export and import to transplant a bugfix to the current
2954 - use export and import to transplant a bugfix to the current
2942 branch::
2955 branch::
2943
2956
2944 hg export -r 9353 | hg import -
2957 hg export -r 9353 | hg import -
2945
2958
2946 - export all the changesets between two revisions to a file with
2959 - export all the changesets between two revisions to a file with
2947 rename information::
2960 rename information::
2948
2961
2949 hg export --git -r 123:150 > changes.txt
2962 hg export --git -r 123:150 > changes.txt
2950
2963
2951 - split outgoing changes into a series of patches with
2964 - split outgoing changes into a series of patches with
2952 descriptive names::
2965 descriptive names::
2953
2966
2954 hg export -r "outgoing()" -o "%n-%m.patch"
2967 hg export -r "outgoing()" -o "%n-%m.patch"
2955
2968
2956 Returns 0 on success.
2969 Returns 0 on success.
2957 """
2970 """
2958 changesets += tuple(opts.get('rev', []))
2971 changesets += tuple(opts.get('rev', []))
2959 if not changesets:
2972 if not changesets:
2960 changesets = ['.']
2973 changesets = ['.']
2961 revs = scmutil.revrange(repo, changesets)
2974 revs = scmutil.revrange(repo, changesets)
2962 if not revs:
2975 if not revs:
2963 raise util.Abort(_("export requires at least one changeset"))
2976 raise util.Abort(_("export requires at least one changeset"))
2964 if len(revs) > 1:
2977 if len(revs) > 1:
2965 ui.note(_('exporting patches:\n'))
2978 ui.note(_('exporting patches:\n'))
2966 else:
2979 else:
2967 ui.note(_('exporting patch:\n'))
2980 ui.note(_('exporting patch:\n'))
2968 cmdutil.export(repo, revs, template=opts.get('output'),
2981 cmdutil.export(repo, revs, template=opts.get('output'),
2969 switch_parent=opts.get('switch_parent'),
2982 switch_parent=opts.get('switch_parent'),
2970 opts=patch.diffopts(ui, opts))
2983 opts=patch.diffopts(ui, opts))
2971
2984
2972 @command('^forget', walkopts, _('[OPTION]... FILE...'))
2985 @command('^forget', walkopts, _('[OPTION]... FILE...'))
2973 def forget(ui, repo, *pats, **opts):
2986 def forget(ui, repo, *pats, **opts):
2974 """forget the specified files on the next commit
2987 """forget the specified files on the next commit
2975
2988
2976 Mark the specified files so they will no longer be tracked
2989 Mark the specified files so they will no longer be tracked
2977 after the next commit.
2990 after the next commit.
2978
2991
2979 This only removes files from the current branch, not from the
2992 This only removes files from the current branch, not from the
2980 entire project history, and it does not delete them from the
2993 entire project history, and it does not delete them from the
2981 working directory.
2994 working directory.
2982
2995
2983 To undo a forget before the next commit, see :hg:`add`.
2996 To undo a forget before the next commit, see :hg:`add`.
2984
2997
2985 .. container:: verbose
2998 .. container:: verbose
2986
2999
2987 Examples:
3000 Examples:
2988
3001
2989 - forget newly-added binary files::
3002 - forget newly-added binary files::
2990
3003
2991 hg forget "set:added() and binary()"
3004 hg forget "set:added() and binary()"
2992
3005
2993 - forget files that would be excluded by .hgignore::
3006 - forget files that would be excluded by .hgignore::
2994
3007
2995 hg forget "set:hgignore()"
3008 hg forget "set:hgignore()"
2996
3009
2997 Returns 0 on success.
3010 Returns 0 on success.
2998 """
3011 """
2999
3012
3000 if not pats:
3013 if not pats:
3001 raise util.Abort(_('no files specified'))
3014 raise util.Abort(_('no files specified'))
3002
3015
3003 m = scmutil.match(repo[None], pats, opts)
3016 m = scmutil.match(repo[None], pats, opts)
3004 rejected = cmdutil.forget(ui, repo, m, prefix="", explicitonly=False)[0]
3017 rejected = cmdutil.forget(ui, repo, m, prefix="", explicitonly=False)[0]
3005 return rejected and 1 or 0
3018 return rejected and 1 or 0
3006
3019
3007 @command(
3020 @command(
3008 'graft',
3021 'graft',
3009 [('r', 'rev', [], _('revisions to graft'), _('REV')),
3022 [('r', 'rev', [], _('revisions to graft'), _('REV')),
3010 ('c', 'continue', False, _('resume interrupted graft')),
3023 ('c', 'continue', False, _('resume interrupted graft')),
3011 ('e', 'edit', False, _('invoke editor on commit messages')),
3024 ('e', 'edit', False, _('invoke editor on commit messages')),
3012 ('', 'log', None, _('append graft info to log message')),
3025 ('', 'log', None, _('append graft info to log message')),
3013 ('D', 'currentdate', False,
3026 ('D', 'currentdate', False,
3014 _('record the current date as commit date')),
3027 _('record the current date as commit date')),
3015 ('U', 'currentuser', False,
3028 ('U', 'currentuser', False,
3016 _('record the current user as committer'), _('DATE'))]
3029 _('record the current user as committer'), _('DATE'))]
3017 + commitopts2 + mergetoolopts + dryrunopts,
3030 + commitopts2 + mergetoolopts + dryrunopts,
3018 _('[OPTION]... [-r] REV...'))
3031 _('[OPTION]... [-r] REV...'))
3019 def graft(ui, repo, *revs, **opts):
3032 def graft(ui, repo, *revs, **opts):
3020 '''copy changes from other branches onto the current branch
3033 '''copy changes from other branches onto the current branch
3021
3034
3022 This command uses Mercurial's merge logic to copy individual
3035 This command uses Mercurial's merge logic to copy individual
3023 changes from other branches without merging branches in the
3036 changes from other branches without merging branches in the
3024 history graph. This is sometimes known as 'backporting' or
3037 history graph. This is sometimes known as 'backporting' or
3025 'cherry-picking'. By default, graft will copy user, date, and
3038 'cherry-picking'. By default, graft will copy user, date, and
3026 description from the source changesets.
3039 description from the source changesets.
3027
3040
3028 Changesets that are ancestors of the current revision, that have
3041 Changesets that are ancestors of the current revision, that have
3029 already been grafted, or that are merges will be skipped.
3042 already been grafted, or that are merges will be skipped.
3030
3043
3031 If --log is specified, log messages will have a comment appended
3044 If --log is specified, log messages will have a comment appended
3032 of the form::
3045 of the form::
3033
3046
3034 (grafted from CHANGESETHASH)
3047 (grafted from CHANGESETHASH)
3035
3048
3036 If a graft merge results in conflicts, the graft process is
3049 If a graft merge results in conflicts, the graft process is
3037 interrupted so that the current merge can be manually resolved.
3050 interrupted so that the current merge can be manually resolved.
3038 Once all conflicts are addressed, the graft process can be
3051 Once all conflicts are addressed, the graft process can be
3039 continued with the -c/--continue option.
3052 continued with the -c/--continue option.
3040
3053
3041 .. note::
3054 .. note::
3042
3055
3043 The -c/--continue option does not reapply earlier options.
3056 The -c/--continue option does not reapply earlier options.
3044
3057
3045 .. container:: verbose
3058 .. container:: verbose
3046
3059
3047 Examples:
3060 Examples:
3048
3061
3049 - copy a single change to the stable branch and edit its description::
3062 - copy a single change to the stable branch and edit its description::
3050
3063
3051 hg update stable
3064 hg update stable
3052 hg graft --edit 9393
3065 hg graft --edit 9393
3053
3066
3054 - graft a range of changesets with one exception, updating dates::
3067 - graft a range of changesets with one exception, updating dates::
3055
3068
3056 hg graft -D "2085::2093 and not 2091"
3069 hg graft -D "2085::2093 and not 2091"
3057
3070
3058 - continue a graft after resolving conflicts::
3071 - continue a graft after resolving conflicts::
3059
3072
3060 hg graft -c
3073 hg graft -c
3061
3074
3062 - show the source of a grafted changeset::
3075 - show the source of a grafted changeset::
3063
3076
3064 hg log --debug -r .
3077 hg log --debug -r .
3065
3078
3066 Returns 0 on successful completion.
3079 Returns 0 on successful completion.
3067 '''
3080 '''
3068
3081
3069 revs = list(revs)
3082 revs = list(revs)
3070 revs.extend(opts['rev'])
3083 revs.extend(opts['rev'])
3071
3084
3072 if not opts.get('user') and opts.get('currentuser'):
3085 if not opts.get('user') and opts.get('currentuser'):
3073 opts['user'] = ui.username()
3086 opts['user'] = ui.username()
3074 if not opts.get('date') and opts.get('currentdate'):
3087 if not opts.get('date') and opts.get('currentdate'):
3075 opts['date'] = "%d %d" % util.makedate()
3088 opts['date'] = "%d %d" % util.makedate()
3076
3089
3077 editor = None
3090 editor = None
3078 if opts.get('edit'):
3091 if opts.get('edit'):
3079 editor = cmdutil.commitforceeditor
3092 editor = cmdutil.commitforceeditor
3080
3093
3081 cont = False
3094 cont = False
3082 if opts['continue']:
3095 if opts['continue']:
3083 cont = True
3096 cont = True
3084 if revs:
3097 if revs:
3085 raise util.Abort(_("can't specify --continue and revisions"))
3098 raise util.Abort(_("can't specify --continue and revisions"))
3086 # read in unfinished revisions
3099 # read in unfinished revisions
3087 try:
3100 try:
3088 nodes = repo.opener.read('graftstate').splitlines()
3101 nodes = repo.opener.read('graftstate').splitlines()
3089 revs = [repo[node].rev() for node in nodes]
3102 revs = [repo[node].rev() for node in nodes]
3090 except IOError, inst:
3103 except IOError, inst:
3091 if inst.errno != errno.ENOENT:
3104 if inst.errno != errno.ENOENT:
3092 raise
3105 raise
3093 raise util.Abort(_("no graft state found, can't continue"))
3106 raise util.Abort(_("no graft state found, can't continue"))
3094 else:
3107 else:
3095 cmdutil.checkunfinished(repo)
3108 cmdutil.checkunfinished(repo)
3096 cmdutil.bailifchanged(repo)
3109 cmdutil.bailifchanged(repo)
3097 if not revs:
3110 if not revs:
3098 raise util.Abort(_('no revisions specified'))
3111 raise util.Abort(_('no revisions specified'))
3099 revs = scmutil.revrange(repo, revs)
3112 revs = scmutil.revrange(repo, revs)
3100
3113
3101 # check for merges
3114 # check for merges
3102 for rev in repo.revs('%ld and merge()', revs):
3115 for rev in repo.revs('%ld and merge()', revs):
3103 ui.warn(_('skipping ungraftable merge revision %s\n') % rev)
3116 ui.warn(_('skipping ungraftable merge revision %s\n') % rev)
3104 revs.remove(rev)
3117 revs.remove(rev)
3105 if not revs:
3118 if not revs:
3106 return -1
3119 return -1
3107
3120
3108 # check for ancestors of dest branch
3121 # check for ancestors of dest branch
3109 crev = repo['.'].rev()
3122 crev = repo['.'].rev()
3110 ancestors = repo.changelog.ancestors([crev], inclusive=True)
3123 ancestors = repo.changelog.ancestors([crev], inclusive=True)
3111 # don't mutate while iterating, create a copy
3124 # don't mutate while iterating, create a copy
3112 for rev in list(revs):
3125 for rev in list(revs):
3113 if rev in ancestors:
3126 if rev in ancestors:
3114 ui.warn(_('skipping ancestor revision %s\n') % rev)
3127 ui.warn(_('skipping ancestor revision %s\n') % rev)
3115 revs.remove(rev)
3128 revs.remove(rev)
3116 if not revs:
3129 if not revs:
3117 return -1
3130 return -1
3118
3131
3119 # analyze revs for earlier grafts
3132 # analyze revs for earlier grafts
3120 ids = {}
3133 ids = {}
3121 for ctx in repo.set("%ld", revs):
3134 for ctx in repo.set("%ld", revs):
3122 ids[ctx.hex()] = ctx.rev()
3135 ids[ctx.hex()] = ctx.rev()
3123 n = ctx.extra().get('source')
3136 n = ctx.extra().get('source')
3124 if n:
3137 if n:
3125 ids[n] = ctx.rev()
3138 ids[n] = ctx.rev()
3126
3139
3127 # check ancestors for earlier grafts
3140 # check ancestors for earlier grafts
3128 ui.debug('scanning for duplicate grafts\n')
3141 ui.debug('scanning for duplicate grafts\n')
3129
3142
3130 for rev in repo.changelog.findmissingrevs(revs, [crev]):
3143 for rev in repo.changelog.findmissingrevs(revs, [crev]):
3131 ctx = repo[rev]
3144 ctx = repo[rev]
3132 n = ctx.extra().get('source')
3145 n = ctx.extra().get('source')
3133 if n in ids:
3146 if n in ids:
3134 r = repo[n].rev()
3147 r = repo[n].rev()
3135 if r in revs:
3148 if r in revs:
3136 ui.warn(_('skipping revision %s (already grafted to %s)\n')
3149 ui.warn(_('skipping revision %s (already grafted to %s)\n')
3137 % (r, rev))
3150 % (r, rev))
3138 revs.remove(r)
3151 revs.remove(r)
3139 elif ids[n] in revs:
3152 elif ids[n] in revs:
3140 ui.warn(_('skipping already grafted revision %s '
3153 ui.warn(_('skipping already grafted revision %s '
3141 '(%s also has origin %d)\n') % (ids[n], rev, r))
3154 '(%s also has origin %d)\n') % (ids[n], rev, r))
3142 revs.remove(ids[n])
3155 revs.remove(ids[n])
3143 elif ctx.hex() in ids:
3156 elif ctx.hex() in ids:
3144 r = ids[ctx.hex()]
3157 r = ids[ctx.hex()]
3145 ui.warn(_('skipping already grafted revision %s '
3158 ui.warn(_('skipping already grafted revision %s '
3146 '(was grafted from %d)\n') % (r, rev))
3159 '(was grafted from %d)\n') % (r, rev))
3147 revs.remove(r)
3160 revs.remove(r)
3148 if not revs:
3161 if not revs:
3149 return -1
3162 return -1
3150
3163
3151 wlock = repo.wlock()
3164 wlock = repo.wlock()
3152 try:
3165 try:
3153 current = repo['.']
3166 current = repo['.']
3154 for pos, ctx in enumerate(repo.set("%ld", revs)):
3167 for pos, ctx in enumerate(repo.set("%ld", revs)):
3155
3168
3156 ui.status(_('grafting revision %s\n') % ctx.rev())
3169 ui.status(_('grafting revision %s\n') % ctx.rev())
3157 if opts.get('dry_run'):
3170 if opts.get('dry_run'):
3158 continue
3171 continue
3159
3172
3160 source = ctx.extra().get('source')
3173 source = ctx.extra().get('source')
3161 if not source:
3174 if not source:
3162 source = ctx.hex()
3175 source = ctx.hex()
3163 extra = {'source': source}
3176 extra = {'source': source}
3164 user = ctx.user()
3177 user = ctx.user()
3165 if opts.get('user'):
3178 if opts.get('user'):
3166 user = opts['user']
3179 user = opts['user']
3167 date = ctx.date()
3180 date = ctx.date()
3168 if opts.get('date'):
3181 if opts.get('date'):
3169 date = opts['date']
3182 date = opts['date']
3170 message = ctx.description()
3183 message = ctx.description()
3171 if opts.get('log'):
3184 if opts.get('log'):
3172 message += '\n(grafted from %s)' % ctx.hex()
3185 message += '\n(grafted from %s)' % ctx.hex()
3173
3186
3174 # we don't merge the first commit when continuing
3187 # we don't merge the first commit when continuing
3175 if not cont:
3188 if not cont:
3176 # perform the graft merge with p1(rev) as 'ancestor'
3189 # perform the graft merge with p1(rev) as 'ancestor'
3177 try:
3190 try:
3178 # ui.forcemerge is an internal variable, do not document
3191 # ui.forcemerge is an internal variable, do not document
3179 repo.ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
3192 repo.ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
3180 stats = mergemod.update(repo, ctx.node(), True, True, False,
3193 stats = mergemod.update(repo, ctx.node(), True, True, False,
3181 ctx.p1().node())
3194 ctx.p1().node())
3182 finally:
3195 finally:
3183 repo.ui.setconfig('ui', 'forcemerge', '')
3196 repo.ui.setconfig('ui', 'forcemerge', '')
3184 # report any conflicts
3197 # report any conflicts
3185 if stats and stats[3] > 0:
3198 if stats and stats[3] > 0:
3186 # write out state for --continue
3199 # write out state for --continue
3187 nodelines = [repo[rev].hex() + "\n" for rev in revs[pos:]]
3200 nodelines = [repo[rev].hex() + "\n" for rev in revs[pos:]]
3188 repo.opener.write('graftstate', ''.join(nodelines))
3201 repo.opener.write('graftstate', ''.join(nodelines))
3189 raise util.Abort(
3202 raise util.Abort(
3190 _("unresolved conflicts, can't continue"),
3203 _("unresolved conflicts, can't continue"),
3191 hint=_('use hg resolve and hg graft --continue'))
3204 hint=_('use hg resolve and hg graft --continue'))
3192 else:
3205 else:
3193 cont = False
3206 cont = False
3194
3207
3195 # drop the second merge parent
3208 # drop the second merge parent
3196 repo.setparents(current.node(), nullid)
3209 repo.setparents(current.node(), nullid)
3197 repo.dirstate.write()
3210 repo.dirstate.write()
3198 # fix up dirstate for copies and renames
3211 # fix up dirstate for copies and renames
3199 cmdutil.duplicatecopies(repo, ctx.rev(), ctx.p1().rev())
3212 cmdutil.duplicatecopies(repo, ctx.rev(), ctx.p1().rev())
3200
3213
3201 # commit
3214 # commit
3202 node = repo.commit(text=message, user=user,
3215 node = repo.commit(text=message, user=user,
3203 date=date, extra=extra, editor=editor)
3216 date=date, extra=extra, editor=editor)
3204 if node is None:
3217 if node is None:
3205 ui.status(_('graft for revision %s is empty\n') % ctx.rev())
3218 ui.status(_('graft for revision %s is empty\n') % ctx.rev())
3206 else:
3219 else:
3207 current = repo[node]
3220 current = repo[node]
3208 finally:
3221 finally:
3209 wlock.release()
3222 wlock.release()
3210
3223
3211 # remove state when we complete successfully
3224 # remove state when we complete successfully
3212 if not opts.get('dry_run'):
3225 if not opts.get('dry_run'):
3213 util.unlinkpath(repo.join('graftstate'), ignoremissing=True)
3226 util.unlinkpath(repo.join('graftstate'), ignoremissing=True)
3214
3227
3215 return 0
3228 return 0
3216
3229
3217 @command('grep',
3230 @command('grep',
3218 [('0', 'print0', None, _('end fields with NUL')),
3231 [('0', 'print0', None, _('end fields with NUL')),
3219 ('', 'all', None, _('print all revisions that match')),
3232 ('', 'all', None, _('print all revisions that match')),
3220 ('a', 'text', None, _('treat all files as text')),
3233 ('a', 'text', None, _('treat all files as text')),
3221 ('f', 'follow', None,
3234 ('f', 'follow', None,
3222 _('follow changeset history,'
3235 _('follow changeset history,'
3223 ' or file history across copies and renames')),
3236 ' or file history across copies and renames')),
3224 ('i', 'ignore-case', None, _('ignore case when matching')),
3237 ('i', 'ignore-case', None, _('ignore case when matching')),
3225 ('l', 'files-with-matches', None,
3238 ('l', 'files-with-matches', None,
3226 _('print only filenames and revisions that match')),
3239 _('print only filenames and revisions that match')),
3227 ('n', 'line-number', None, _('print matching line numbers')),
3240 ('n', 'line-number', None, _('print matching line numbers')),
3228 ('r', 'rev', [],
3241 ('r', 'rev', [],
3229 _('only search files changed within revision range'), _('REV')),
3242 _('only search files changed within revision range'), _('REV')),
3230 ('u', 'user', None, _('list the author (long with -v)')),
3243 ('u', 'user', None, _('list the author (long with -v)')),
3231 ('d', 'date', None, _('list the date (short with -q)')),
3244 ('d', 'date', None, _('list the date (short with -q)')),
3232 ] + walkopts,
3245 ] + walkopts,
3233 _('[OPTION]... PATTERN [FILE]...'))
3246 _('[OPTION]... PATTERN [FILE]...'))
3234 def grep(ui, repo, pattern, *pats, **opts):
3247 def grep(ui, repo, pattern, *pats, **opts):
3235 """search for a pattern in specified files and revisions
3248 """search for a pattern in specified files and revisions
3236
3249
3237 Search revisions of files for a regular expression.
3250 Search revisions of files for a regular expression.
3238
3251
3239 This command behaves differently than Unix grep. It only accepts
3252 This command behaves differently than Unix grep. It only accepts
3240 Python/Perl regexps. It searches repository history, not the
3253 Python/Perl regexps. It searches repository history, not the
3241 working directory. It always prints the revision number in which a
3254 working directory. It always prints the revision number in which a
3242 match appears.
3255 match appears.
3243
3256
3244 By default, grep only prints output for the first revision of a
3257 By default, grep only prints output for the first revision of a
3245 file in which it finds a match. To get it to print every revision
3258 file in which it finds a match. To get it to print every revision
3246 that contains a change in match status ("-" for a match that
3259 that contains a change in match status ("-" for a match that
3247 becomes a non-match, or "+" for a non-match that becomes a match),
3260 becomes a non-match, or "+" for a non-match that becomes a match),
3248 use the --all flag.
3261 use the --all flag.
3249
3262
3250 Returns 0 if a match is found, 1 otherwise.
3263 Returns 0 if a match is found, 1 otherwise.
3251 """
3264 """
3252 reflags = re.M
3265 reflags = re.M
3253 if opts.get('ignore_case'):
3266 if opts.get('ignore_case'):
3254 reflags |= re.I
3267 reflags |= re.I
3255 try:
3268 try:
3256 regexp = util.compilere(pattern, reflags)
3269 regexp = util.compilere(pattern, reflags)
3257 except re.error, inst:
3270 except re.error, inst:
3258 ui.warn(_("grep: invalid match pattern: %s\n") % inst)
3271 ui.warn(_("grep: invalid match pattern: %s\n") % inst)
3259 return 1
3272 return 1
3260 sep, eol = ':', '\n'
3273 sep, eol = ':', '\n'
3261 if opts.get('print0'):
3274 if opts.get('print0'):
3262 sep = eol = '\0'
3275 sep = eol = '\0'
3263
3276
3264 getfile = util.lrucachefunc(repo.file)
3277 getfile = util.lrucachefunc(repo.file)
3265
3278
3266 def matchlines(body):
3279 def matchlines(body):
3267 begin = 0
3280 begin = 0
3268 linenum = 0
3281 linenum = 0
3269 while begin < len(body):
3282 while begin < len(body):
3270 match = regexp.search(body, begin)
3283 match = regexp.search(body, begin)
3271 if not match:
3284 if not match:
3272 break
3285 break
3273 mstart, mend = match.span()
3286 mstart, mend = match.span()
3274 linenum += body.count('\n', begin, mstart) + 1
3287 linenum += body.count('\n', begin, mstart) + 1
3275 lstart = body.rfind('\n', begin, mstart) + 1 or begin
3288 lstart = body.rfind('\n', begin, mstart) + 1 or begin
3276 begin = body.find('\n', mend) + 1 or len(body) + 1
3289 begin = body.find('\n', mend) + 1 or len(body) + 1
3277 lend = begin - 1
3290 lend = begin - 1
3278 yield linenum, mstart - lstart, mend - lstart, body[lstart:lend]
3291 yield linenum, mstart - lstart, mend - lstart, body[lstart:lend]
3279
3292
3280 class linestate(object):
3293 class linestate(object):
3281 def __init__(self, line, linenum, colstart, colend):
3294 def __init__(self, line, linenum, colstart, colend):
3282 self.line = line
3295 self.line = line
3283 self.linenum = linenum
3296 self.linenum = linenum
3284 self.colstart = colstart
3297 self.colstart = colstart
3285 self.colend = colend
3298 self.colend = colend
3286
3299
3287 def __hash__(self):
3300 def __hash__(self):
3288 return hash((self.linenum, self.line))
3301 return hash((self.linenum, self.line))
3289
3302
3290 def __eq__(self, other):
3303 def __eq__(self, other):
3291 return self.line == other.line
3304 return self.line == other.line
3292
3305
3293 matches = {}
3306 matches = {}
3294 copies = {}
3307 copies = {}
3295 def grepbody(fn, rev, body):
3308 def grepbody(fn, rev, body):
3296 matches[rev].setdefault(fn, [])
3309 matches[rev].setdefault(fn, [])
3297 m = matches[rev][fn]
3310 m = matches[rev][fn]
3298 for lnum, cstart, cend, line in matchlines(body):
3311 for lnum, cstart, cend, line in matchlines(body):
3299 s = linestate(line, lnum, cstart, cend)
3312 s = linestate(line, lnum, cstart, cend)
3300 m.append(s)
3313 m.append(s)
3301
3314
3302 def difflinestates(a, b):
3315 def difflinestates(a, b):
3303 sm = difflib.SequenceMatcher(None, a, b)
3316 sm = difflib.SequenceMatcher(None, a, b)
3304 for tag, alo, ahi, blo, bhi in sm.get_opcodes():
3317 for tag, alo, ahi, blo, bhi in sm.get_opcodes():
3305 if tag == 'insert':
3318 if tag == 'insert':
3306 for i in xrange(blo, bhi):
3319 for i in xrange(blo, bhi):
3307 yield ('+', b[i])
3320 yield ('+', b[i])
3308 elif tag == 'delete':
3321 elif tag == 'delete':
3309 for i in xrange(alo, ahi):
3322 for i in xrange(alo, ahi):
3310 yield ('-', a[i])
3323 yield ('-', a[i])
3311 elif tag == 'replace':
3324 elif tag == 'replace':
3312 for i in xrange(alo, ahi):
3325 for i in xrange(alo, ahi):
3313 yield ('-', a[i])
3326 yield ('-', a[i])
3314 for i in xrange(blo, bhi):
3327 for i in xrange(blo, bhi):
3315 yield ('+', b[i])
3328 yield ('+', b[i])
3316
3329
3317 def display(fn, ctx, pstates, states):
3330 def display(fn, ctx, pstates, states):
3318 rev = ctx.rev()
3331 rev = ctx.rev()
3319 datefunc = ui.quiet and util.shortdate or util.datestr
3332 datefunc = ui.quiet and util.shortdate or util.datestr
3320 found = False
3333 found = False
3321 filerevmatches = {}
3334 filerevmatches = {}
3322 def binary():
3335 def binary():
3323 flog = getfile(fn)
3336 flog = getfile(fn)
3324 return util.binary(flog.read(ctx.filenode(fn)))
3337 return util.binary(flog.read(ctx.filenode(fn)))
3325
3338
3326 if opts.get('all'):
3339 if opts.get('all'):
3327 iter = difflinestates(pstates, states)
3340 iter = difflinestates(pstates, states)
3328 else:
3341 else:
3329 iter = [('', l) for l in states]
3342 iter = [('', l) for l in states]
3330 for change, l in iter:
3343 for change, l in iter:
3331 cols = [(fn, 'grep.filename'), (str(rev), 'grep.rev')]
3344 cols = [(fn, 'grep.filename'), (str(rev), 'grep.rev')]
3332 before, match, after = None, None, None
3345 before, match, after = None, None, None
3333
3346
3334 if opts.get('line_number'):
3347 if opts.get('line_number'):
3335 cols.append((str(l.linenum), 'grep.linenumber'))
3348 cols.append((str(l.linenum), 'grep.linenumber'))
3336 if opts.get('all'):
3349 if opts.get('all'):
3337 cols.append((change, 'grep.change'))
3350 cols.append((change, 'grep.change'))
3338 if opts.get('user'):
3351 if opts.get('user'):
3339 cols.append((ui.shortuser(ctx.user()), 'grep.user'))
3352 cols.append((ui.shortuser(ctx.user()), 'grep.user'))
3340 if opts.get('date'):
3353 if opts.get('date'):
3341 cols.append((datefunc(ctx.date()), 'grep.date'))
3354 cols.append((datefunc(ctx.date()), 'grep.date'))
3342 if opts.get('files_with_matches'):
3355 if opts.get('files_with_matches'):
3343 c = (fn, rev)
3356 c = (fn, rev)
3344 if c in filerevmatches:
3357 if c in filerevmatches:
3345 continue
3358 continue
3346 filerevmatches[c] = 1
3359 filerevmatches[c] = 1
3347 else:
3360 else:
3348 before = l.line[:l.colstart]
3361 before = l.line[:l.colstart]
3349 match = l.line[l.colstart:l.colend]
3362 match = l.line[l.colstart:l.colend]
3350 after = l.line[l.colend:]
3363 after = l.line[l.colend:]
3351 for col, label in cols[:-1]:
3364 for col, label in cols[:-1]:
3352 ui.write(col, label=label)
3365 ui.write(col, label=label)
3353 ui.write(sep, label='grep.sep')
3366 ui.write(sep, label='grep.sep')
3354 ui.write(cols[-1][0], label=cols[-1][1])
3367 ui.write(cols[-1][0], label=cols[-1][1])
3355 if before is not None:
3368 if before is not None:
3356 ui.write(sep, label='grep.sep')
3369 ui.write(sep, label='grep.sep')
3357 if not opts.get('text') and binary():
3370 if not opts.get('text') and binary():
3358 ui.write(" Binary file matches")
3371 ui.write(" Binary file matches")
3359 else:
3372 else:
3360 ui.write(before)
3373 ui.write(before)
3361 ui.write(match, label='grep.match')
3374 ui.write(match, label='grep.match')
3362 ui.write(after)
3375 ui.write(after)
3363 ui.write(eol)
3376 ui.write(eol)
3364 found = True
3377 found = True
3365 return found
3378 return found
3366
3379
3367 skip = {}
3380 skip = {}
3368 revfiles = {}
3381 revfiles = {}
3369 matchfn = scmutil.match(repo[None], pats, opts)
3382 matchfn = scmutil.match(repo[None], pats, opts)
3370 found = False
3383 found = False
3371 follow = opts.get('follow')
3384 follow = opts.get('follow')
3372
3385
3373 def prep(ctx, fns):
3386 def prep(ctx, fns):
3374 rev = ctx.rev()
3387 rev = ctx.rev()
3375 pctx = ctx.p1()
3388 pctx = ctx.p1()
3376 parent = pctx.rev()
3389 parent = pctx.rev()
3377 matches.setdefault(rev, {})
3390 matches.setdefault(rev, {})
3378 matches.setdefault(parent, {})
3391 matches.setdefault(parent, {})
3379 files = revfiles.setdefault(rev, [])
3392 files = revfiles.setdefault(rev, [])
3380 for fn in fns:
3393 for fn in fns:
3381 flog = getfile(fn)
3394 flog = getfile(fn)
3382 try:
3395 try:
3383 fnode = ctx.filenode(fn)
3396 fnode = ctx.filenode(fn)
3384 except error.LookupError:
3397 except error.LookupError:
3385 continue
3398 continue
3386
3399
3387 copied = flog.renamed(fnode)
3400 copied = flog.renamed(fnode)
3388 copy = follow and copied and copied[0]
3401 copy = follow and copied and copied[0]
3389 if copy:
3402 if copy:
3390 copies.setdefault(rev, {})[fn] = copy
3403 copies.setdefault(rev, {})[fn] = copy
3391 if fn in skip:
3404 if fn in skip:
3392 if copy:
3405 if copy:
3393 skip[copy] = True
3406 skip[copy] = True
3394 continue
3407 continue
3395 files.append(fn)
3408 files.append(fn)
3396
3409
3397 if fn not in matches[rev]:
3410 if fn not in matches[rev]:
3398 grepbody(fn, rev, flog.read(fnode))
3411 grepbody(fn, rev, flog.read(fnode))
3399
3412
3400 pfn = copy or fn
3413 pfn = copy or fn
3401 if pfn not in matches[parent]:
3414 if pfn not in matches[parent]:
3402 try:
3415 try:
3403 fnode = pctx.filenode(pfn)
3416 fnode = pctx.filenode(pfn)
3404 grepbody(pfn, parent, flog.read(fnode))
3417 grepbody(pfn, parent, flog.read(fnode))
3405 except error.LookupError:
3418 except error.LookupError:
3406 pass
3419 pass
3407
3420
3408 for ctx in cmdutil.walkchangerevs(repo, matchfn, opts, prep):
3421 for ctx in cmdutil.walkchangerevs(repo, matchfn, opts, prep):
3409 rev = ctx.rev()
3422 rev = ctx.rev()
3410 parent = ctx.p1().rev()
3423 parent = ctx.p1().rev()
3411 for fn in sorted(revfiles.get(rev, [])):
3424 for fn in sorted(revfiles.get(rev, [])):
3412 states = matches[rev][fn]
3425 states = matches[rev][fn]
3413 copy = copies.get(rev, {}).get(fn)
3426 copy = copies.get(rev, {}).get(fn)
3414 if fn in skip:
3427 if fn in skip:
3415 if copy:
3428 if copy:
3416 skip[copy] = True
3429 skip[copy] = True
3417 continue
3430 continue
3418 pstates = matches.get(parent, {}).get(copy or fn, [])
3431 pstates = matches.get(parent, {}).get(copy or fn, [])
3419 if pstates or states:
3432 if pstates or states:
3420 r = display(fn, ctx, pstates, states)
3433 r = display(fn, ctx, pstates, states)
3421 found = found or r
3434 found = found or r
3422 if r and not opts.get('all'):
3435 if r and not opts.get('all'):
3423 skip[fn] = True
3436 skip[fn] = True
3424 if copy:
3437 if copy:
3425 skip[copy] = True
3438 skip[copy] = True
3426 del matches[rev]
3439 del matches[rev]
3427 del revfiles[rev]
3440 del revfiles[rev]
3428
3441
3429 return not found
3442 return not found
3430
3443
3431 @command('heads',
3444 @command('heads',
3432 [('r', 'rev', '',
3445 [('r', 'rev', '',
3433 _('show only heads which are descendants of STARTREV'), _('STARTREV')),
3446 _('show only heads which are descendants of STARTREV'), _('STARTREV')),
3434 ('t', 'topo', False, _('show topological heads only')),
3447 ('t', 'topo', False, _('show topological heads only')),
3435 ('a', 'active', False, _('show active branchheads only (DEPRECATED)')),
3448 ('a', 'active', False, _('show active branchheads only (DEPRECATED)')),
3436 ('c', 'closed', False, _('show normal and closed branch heads')),
3449 ('c', 'closed', False, _('show normal and closed branch heads')),
3437 ] + templateopts,
3450 ] + templateopts,
3438 _('[-ct] [-r STARTREV] [REV]...'))
3451 _('[-ct] [-r STARTREV] [REV]...'))
3439 def heads(ui, repo, *branchrevs, **opts):
3452 def heads(ui, repo, *branchrevs, **opts):
3440 """show branch heads
3453 """show branch heads
3441
3454
3442 With no arguments, show all open branch heads in the repository.
3455 With no arguments, show all open branch heads in the repository.
3443 Branch heads are changesets that have no descendants on the
3456 Branch heads are changesets that have no descendants on the
3444 same branch. They are where development generally takes place and
3457 same branch. They are where development generally takes place and
3445 are the usual targets for update and merge operations.
3458 are the usual targets for update and merge operations.
3446
3459
3447 If one or more REVs are given, only open branch heads on the
3460 If one or more REVs are given, only open branch heads on the
3448 branches associated with the specified changesets are shown. This
3461 branches associated with the specified changesets are shown. This
3449 means that you can use :hg:`heads .` to see the heads on the
3462 means that you can use :hg:`heads .` to see the heads on the
3450 currently checked-out branch.
3463 currently checked-out branch.
3451
3464
3452 If -c/--closed is specified, also show branch heads marked closed
3465 If -c/--closed is specified, also show branch heads marked closed
3453 (see :hg:`commit --close-branch`).
3466 (see :hg:`commit --close-branch`).
3454
3467
3455 If STARTREV is specified, only those heads that are descendants of
3468 If STARTREV is specified, only those heads that are descendants of
3456 STARTREV will be displayed.
3469 STARTREV will be displayed.
3457
3470
3458 If -t/--topo is specified, named branch mechanics will be ignored and only
3471 If -t/--topo is specified, named branch mechanics will be ignored and only
3459 topological heads (changesets with no children) will be shown.
3472 topological heads (changesets with no children) will be shown.
3460
3473
3461 Returns 0 if matching heads are found, 1 if not.
3474 Returns 0 if matching heads are found, 1 if not.
3462 """
3475 """
3463
3476
3464 start = None
3477 start = None
3465 if 'rev' in opts:
3478 if 'rev' in opts:
3466 start = scmutil.revsingle(repo, opts['rev'], None).node()
3479 start = scmutil.revsingle(repo, opts['rev'], None).node()
3467
3480
3468 if opts.get('topo'):
3481 if opts.get('topo'):
3469 heads = [repo[h] for h in repo.heads(start)]
3482 heads = [repo[h] for h in repo.heads(start)]
3470 else:
3483 else:
3471 heads = []
3484 heads = []
3472 for branch in repo.branchmap():
3485 for branch in repo.branchmap():
3473 heads += repo.branchheads(branch, start, opts.get('closed'))
3486 heads += repo.branchheads(branch, start, opts.get('closed'))
3474 heads = [repo[h] for h in heads]
3487 heads = [repo[h] for h in heads]
3475
3488
3476 if branchrevs:
3489 if branchrevs:
3477 branches = set(repo[br].branch() for br in branchrevs)
3490 branches = set(repo[br].branch() for br in branchrevs)
3478 heads = [h for h in heads if h.branch() in branches]
3491 heads = [h for h in heads if h.branch() in branches]
3479
3492
3480 if opts.get('active') and branchrevs:
3493 if opts.get('active') and branchrevs:
3481 dagheads = repo.heads(start)
3494 dagheads = repo.heads(start)
3482 heads = [h for h in heads if h.node() in dagheads]
3495 heads = [h for h in heads if h.node() in dagheads]
3483
3496
3484 if branchrevs:
3497 if branchrevs:
3485 haveheads = set(h.branch() for h in heads)
3498 haveheads = set(h.branch() for h in heads)
3486 if branches - haveheads:
3499 if branches - haveheads:
3487 headless = ', '.join(b for b in branches - haveheads)
3500 headless = ', '.join(b for b in branches - haveheads)
3488 msg = _('no open branch heads found on branches %s')
3501 msg = _('no open branch heads found on branches %s')
3489 if opts.get('rev'):
3502 if opts.get('rev'):
3490 msg += _(' (started at %s)') % opts['rev']
3503 msg += _(' (started at %s)') % opts['rev']
3491 ui.warn((msg + '\n') % headless)
3504 ui.warn((msg + '\n') % headless)
3492
3505
3493 if not heads:
3506 if not heads:
3494 return 1
3507 return 1
3495
3508
3496 heads = sorted(heads, key=lambda x: -x.rev())
3509 heads = sorted(heads, key=lambda x: -x.rev())
3497 displayer = cmdutil.show_changeset(ui, repo, opts)
3510 displayer = cmdutil.show_changeset(ui, repo, opts)
3498 for ctx in heads:
3511 for ctx in heads:
3499 displayer.show(ctx)
3512 displayer.show(ctx)
3500 displayer.close()
3513 displayer.close()
3501
3514
3502 @command('help',
3515 @command('help',
3503 [('e', 'extension', None, _('show only help for extensions')),
3516 [('e', 'extension', None, _('show only help for extensions')),
3504 ('c', 'command', None, _('show only help for commands')),
3517 ('c', 'command', None, _('show only help for commands')),
3505 ('k', 'keyword', '', _('show topics matching keyword')),
3518 ('k', 'keyword', '', _('show topics matching keyword')),
3506 ],
3519 ],
3507 _('[-ec] [TOPIC]'))
3520 _('[-ec] [TOPIC]'))
3508 def help_(ui, name=None, **opts):
3521 def help_(ui, name=None, **opts):
3509 """show help for a given topic or a help overview
3522 """show help for a given topic or a help overview
3510
3523
3511 With no arguments, print a list of commands with short help messages.
3524 With no arguments, print a list of commands with short help messages.
3512
3525
3513 Given a topic, extension, or command name, print help for that
3526 Given a topic, extension, or command name, print help for that
3514 topic.
3527 topic.
3515
3528
3516 Returns 0 if successful.
3529 Returns 0 if successful.
3517 """
3530 """
3518
3531
3519 textwidth = min(ui.termwidth(), 80) - 2
3532 textwidth = min(ui.termwidth(), 80) - 2
3520
3533
3521 keep = ui.verbose and ['verbose'] or []
3534 keep = ui.verbose and ['verbose'] or []
3522 text = help.help_(ui, name, **opts)
3535 text = help.help_(ui, name, **opts)
3523
3536
3524 formatted, pruned = minirst.format(text, textwidth, keep=keep)
3537 formatted, pruned = minirst.format(text, textwidth, keep=keep)
3525 if 'verbose' in pruned:
3538 if 'verbose' in pruned:
3526 keep.append('omitted')
3539 keep.append('omitted')
3527 else:
3540 else:
3528 keep.append('notomitted')
3541 keep.append('notomitted')
3529 formatted, pruned = minirst.format(text, textwidth, keep=keep)
3542 formatted, pruned = minirst.format(text, textwidth, keep=keep)
3530 ui.write(formatted)
3543 ui.write(formatted)
3531
3544
3532
3545
3533 @command('identify|id',
3546 @command('identify|id',
3534 [('r', 'rev', '',
3547 [('r', 'rev', '',
3535 _('identify the specified revision'), _('REV')),
3548 _('identify the specified revision'), _('REV')),
3536 ('n', 'num', None, _('show local revision number')),
3549 ('n', 'num', None, _('show local revision number')),
3537 ('i', 'id', None, _('show global revision id')),
3550 ('i', 'id', None, _('show global revision id')),
3538 ('b', 'branch', None, _('show branch')),
3551 ('b', 'branch', None, _('show branch')),
3539 ('t', 'tags', None, _('show tags')),
3552 ('t', 'tags', None, _('show tags')),
3540 ('B', 'bookmarks', None, _('show bookmarks')),
3553 ('B', 'bookmarks', None, _('show bookmarks')),
3541 ] + remoteopts,
3554 ] + remoteopts,
3542 _('[-nibtB] [-r REV] [SOURCE]'))
3555 _('[-nibtB] [-r REV] [SOURCE]'))
3543 def identify(ui, repo, source=None, rev=None,
3556 def identify(ui, repo, source=None, rev=None,
3544 num=None, id=None, branch=None, tags=None, bookmarks=None, **opts):
3557 num=None, id=None, branch=None, tags=None, bookmarks=None, **opts):
3545 """identify the working copy or specified revision
3558 """identify the working copy or specified revision
3546
3559
3547 Print a summary identifying the repository state at REV using one or
3560 Print a summary identifying the repository state at REV using one or
3548 two parent hash identifiers, followed by a "+" if the working
3561 two parent hash identifiers, followed by a "+" if the working
3549 directory has uncommitted changes, the branch name (if not default),
3562 directory has uncommitted changes, the branch name (if not default),
3550 a list of tags, and a list of bookmarks.
3563 a list of tags, and a list of bookmarks.
3551
3564
3552 When REV is not given, print a summary of the current state of the
3565 When REV is not given, print a summary of the current state of the
3553 repository.
3566 repository.
3554
3567
3555 Specifying a path to a repository root or Mercurial bundle will
3568 Specifying a path to a repository root or Mercurial bundle will
3556 cause lookup to operate on that repository/bundle.
3569 cause lookup to operate on that repository/bundle.
3557
3570
3558 .. container:: verbose
3571 .. container:: verbose
3559
3572
3560 Examples:
3573 Examples:
3561
3574
3562 - generate a build identifier for the working directory::
3575 - generate a build identifier for the working directory::
3563
3576
3564 hg id --id > build-id.dat
3577 hg id --id > build-id.dat
3565
3578
3566 - find the revision corresponding to a tag::
3579 - find the revision corresponding to a tag::
3567
3580
3568 hg id -n -r 1.3
3581 hg id -n -r 1.3
3569
3582
3570 - check the most recent revision of a remote repository::
3583 - check the most recent revision of a remote repository::
3571
3584
3572 hg id -r tip http://selenic.com/hg/
3585 hg id -r tip http://selenic.com/hg/
3573
3586
3574 Returns 0 if successful.
3587 Returns 0 if successful.
3575 """
3588 """
3576
3589
3577 if not repo and not source:
3590 if not repo and not source:
3578 raise util.Abort(_("there is no Mercurial repository here "
3591 raise util.Abort(_("there is no Mercurial repository here "
3579 "(.hg not found)"))
3592 "(.hg not found)"))
3580
3593
3581 hexfunc = ui.debugflag and hex or short
3594 hexfunc = ui.debugflag and hex or short
3582 default = not (num or id or branch or tags or bookmarks)
3595 default = not (num or id or branch or tags or bookmarks)
3583 output = []
3596 output = []
3584 revs = []
3597 revs = []
3585
3598
3586 if source:
3599 if source:
3587 source, branches = hg.parseurl(ui.expandpath(source))
3600 source, branches = hg.parseurl(ui.expandpath(source))
3588 peer = hg.peer(repo or ui, opts, source) # only pass ui when no repo
3601 peer = hg.peer(repo or ui, opts, source) # only pass ui when no repo
3589 repo = peer.local()
3602 repo = peer.local()
3590 revs, checkout = hg.addbranchrevs(repo, peer, branches, None)
3603 revs, checkout = hg.addbranchrevs(repo, peer, branches, None)
3591
3604
3592 if not repo:
3605 if not repo:
3593 if num or branch or tags:
3606 if num or branch or tags:
3594 raise util.Abort(
3607 raise util.Abort(
3595 _("can't query remote revision number, branch, or tags"))
3608 _("can't query remote revision number, branch, or tags"))
3596 if not rev and revs:
3609 if not rev and revs:
3597 rev = revs[0]
3610 rev = revs[0]
3598 if not rev:
3611 if not rev:
3599 rev = "tip"
3612 rev = "tip"
3600
3613
3601 remoterev = peer.lookup(rev)
3614 remoterev = peer.lookup(rev)
3602 if default or id:
3615 if default or id:
3603 output = [hexfunc(remoterev)]
3616 output = [hexfunc(remoterev)]
3604
3617
3605 def getbms():
3618 def getbms():
3606 bms = []
3619 bms = []
3607
3620
3608 if 'bookmarks' in peer.listkeys('namespaces'):
3621 if 'bookmarks' in peer.listkeys('namespaces'):
3609 hexremoterev = hex(remoterev)
3622 hexremoterev = hex(remoterev)
3610 bms = [bm for bm, bmr in peer.listkeys('bookmarks').iteritems()
3623 bms = [bm for bm, bmr in peer.listkeys('bookmarks').iteritems()
3611 if bmr == hexremoterev]
3624 if bmr == hexremoterev]
3612
3625
3613 return sorted(bms)
3626 return sorted(bms)
3614
3627
3615 if bookmarks:
3628 if bookmarks:
3616 output.extend(getbms())
3629 output.extend(getbms())
3617 elif default and not ui.quiet:
3630 elif default and not ui.quiet:
3618 # multiple bookmarks for a single parent separated by '/'
3631 # multiple bookmarks for a single parent separated by '/'
3619 bm = '/'.join(getbms())
3632 bm = '/'.join(getbms())
3620 if bm:
3633 if bm:
3621 output.append(bm)
3634 output.append(bm)
3622 else:
3635 else:
3623 if not rev:
3636 if not rev:
3624 ctx = repo[None]
3637 ctx = repo[None]
3625 parents = ctx.parents()
3638 parents = ctx.parents()
3626 changed = ""
3639 changed = ""
3627 if default or id or num:
3640 if default or id or num:
3628 if (util.any(repo.status())
3641 if (util.any(repo.status())
3629 or util.any(ctx.sub(s).dirty() for s in ctx.substate)):
3642 or util.any(ctx.sub(s).dirty() for s in ctx.substate)):
3630 changed = '+'
3643 changed = '+'
3631 if default or id:
3644 if default or id:
3632 output = ["%s%s" %
3645 output = ["%s%s" %
3633 ('+'.join([hexfunc(p.node()) for p in parents]), changed)]
3646 ('+'.join([hexfunc(p.node()) for p in parents]), changed)]
3634 if num:
3647 if num:
3635 output.append("%s%s" %
3648 output.append("%s%s" %
3636 ('+'.join([str(p.rev()) for p in parents]), changed))
3649 ('+'.join([str(p.rev()) for p in parents]), changed))
3637 else:
3650 else:
3638 ctx = scmutil.revsingle(repo, rev)
3651 ctx = scmutil.revsingle(repo, rev)
3639 if default or id:
3652 if default or id:
3640 output = [hexfunc(ctx.node())]
3653 output = [hexfunc(ctx.node())]
3641 if num:
3654 if num:
3642 output.append(str(ctx.rev()))
3655 output.append(str(ctx.rev()))
3643
3656
3644 if default and not ui.quiet:
3657 if default and not ui.quiet:
3645 b = ctx.branch()
3658 b = ctx.branch()
3646 if b != 'default':
3659 if b != 'default':
3647 output.append("(%s)" % b)
3660 output.append("(%s)" % b)
3648
3661
3649 # multiple tags for a single parent separated by '/'
3662 # multiple tags for a single parent separated by '/'
3650 t = '/'.join(ctx.tags())
3663 t = '/'.join(ctx.tags())
3651 if t:
3664 if t:
3652 output.append(t)
3665 output.append(t)
3653
3666
3654 # multiple bookmarks for a single parent separated by '/'
3667 # multiple bookmarks for a single parent separated by '/'
3655 bm = '/'.join(ctx.bookmarks())
3668 bm = '/'.join(ctx.bookmarks())
3656 if bm:
3669 if bm:
3657 output.append(bm)
3670 output.append(bm)
3658 else:
3671 else:
3659 if branch:
3672 if branch:
3660 output.append(ctx.branch())
3673 output.append(ctx.branch())
3661
3674
3662 if tags:
3675 if tags:
3663 output.extend(ctx.tags())
3676 output.extend(ctx.tags())
3664
3677
3665 if bookmarks:
3678 if bookmarks:
3666 output.extend(ctx.bookmarks())
3679 output.extend(ctx.bookmarks())
3667
3680
3668 ui.write("%s\n" % ' '.join(output))
3681 ui.write("%s\n" % ' '.join(output))
3669
3682
3670 @command('import|patch',
3683 @command('import|patch',
3671 [('p', 'strip', 1,
3684 [('p', 'strip', 1,
3672 _('directory strip option for patch. This has the same '
3685 _('directory strip option for patch. This has the same '
3673 'meaning as the corresponding patch option'), _('NUM')),
3686 'meaning as the corresponding patch option'), _('NUM')),
3674 ('b', 'base', '', _('base path (DEPRECATED)'), _('PATH')),
3687 ('b', 'base', '', _('base path (DEPRECATED)'), _('PATH')),
3675 ('e', 'edit', False, _('invoke editor on commit messages')),
3688 ('e', 'edit', False, _('invoke editor on commit messages')),
3676 ('f', 'force', None,
3689 ('f', 'force', None,
3677 _('skip check for outstanding uncommitted changes (DEPRECATED)')),
3690 _('skip check for outstanding uncommitted changes (DEPRECATED)')),
3678 ('', 'no-commit', None,
3691 ('', 'no-commit', None,
3679 _("don't commit, just update the working directory")),
3692 _("don't commit, just update the working directory")),
3680 ('', 'bypass', None,
3693 ('', 'bypass', None,
3681 _("apply patch without touching the working directory")),
3694 _("apply patch without touching the working directory")),
3682 ('', 'exact', None,
3695 ('', 'exact', None,
3683 _('apply patch to the nodes from which it was generated')),
3696 _('apply patch to the nodes from which it was generated')),
3684 ('', 'import-branch', None,
3697 ('', 'import-branch', None,
3685 _('use any branch information in patch (implied by --exact)'))] +
3698 _('use any branch information in patch (implied by --exact)'))] +
3686 commitopts + commitopts2 + similarityopts,
3699 commitopts + commitopts2 + similarityopts,
3687 _('[OPTION]... PATCH...'))
3700 _('[OPTION]... PATCH...'))
3688 def import_(ui, repo, patch1=None, *patches, **opts):
3701 def import_(ui, repo, patch1=None, *patches, **opts):
3689 """import an ordered set of patches
3702 """import an ordered set of patches
3690
3703
3691 Import a list of patches and commit them individually (unless
3704 Import a list of patches and commit them individually (unless
3692 --no-commit is specified).
3705 --no-commit is specified).
3693
3706
3694 Because import first applies changes to the working directory,
3707 Because import first applies changes to the working directory,
3695 import will abort if there are outstanding changes.
3708 import will abort if there are outstanding changes.
3696
3709
3697 You can import a patch straight from a mail message. Even patches
3710 You can import a patch straight from a mail message. Even patches
3698 as attachments work (to use the body part, it must have type
3711 as attachments work (to use the body part, it must have type
3699 text/plain or text/x-patch). From and Subject headers of email
3712 text/plain or text/x-patch). From and Subject headers of email
3700 message are used as default committer and commit message. All
3713 message are used as default committer and commit message. All
3701 text/plain body parts before first diff are added to commit
3714 text/plain body parts before first diff are added to commit
3702 message.
3715 message.
3703
3716
3704 If the imported patch was generated by :hg:`export`, user and
3717 If the imported patch was generated by :hg:`export`, user and
3705 description from patch override values from message headers and
3718 description from patch override values from message headers and
3706 body. Values given on command line with -m/--message and -u/--user
3719 body. Values given on command line with -m/--message and -u/--user
3707 override these.
3720 override these.
3708
3721
3709 If --exact is specified, import will set the working directory to
3722 If --exact is specified, import will set the working directory to
3710 the parent of each patch before applying it, and will abort if the
3723 the parent of each patch before applying it, and will abort if the
3711 resulting changeset has a different ID than the one recorded in
3724 resulting changeset has a different ID than the one recorded in
3712 the patch. This may happen due to character set problems or other
3725 the patch. This may happen due to character set problems or other
3713 deficiencies in the text patch format.
3726 deficiencies in the text patch format.
3714
3727
3715 Use --bypass to apply and commit patches directly to the
3728 Use --bypass to apply and commit patches directly to the
3716 repository, not touching the working directory. Without --exact,
3729 repository, not touching the working directory. Without --exact,
3717 patches will be applied on top of the working directory parent
3730 patches will be applied on top of the working directory parent
3718 revision.
3731 revision.
3719
3732
3720 With -s/--similarity, hg will attempt to discover renames and
3733 With -s/--similarity, hg will attempt to discover renames and
3721 copies in the patch in the same way as :hg:`addremove`.
3734 copies in the patch in the same way as :hg:`addremove`.
3722
3735
3723 To read a patch from standard input, use "-" as the patch name. If
3736 To read a patch from standard input, use "-" as the patch name. If
3724 a URL is specified, the patch will be downloaded from it.
3737 a URL is specified, the patch will be downloaded from it.
3725 See :hg:`help dates` for a list of formats valid for -d/--date.
3738 See :hg:`help dates` for a list of formats valid for -d/--date.
3726
3739
3727 .. container:: verbose
3740 .. container:: verbose
3728
3741
3729 Examples:
3742 Examples:
3730
3743
3731 - import a traditional patch from a website and detect renames::
3744 - import a traditional patch from a website and detect renames::
3732
3745
3733 hg import -s 80 http://example.com/bugfix.patch
3746 hg import -s 80 http://example.com/bugfix.patch
3734
3747
3735 - import a changeset from an hgweb server::
3748 - import a changeset from an hgweb server::
3736
3749
3737 hg import http://www.selenic.com/hg/rev/5ca8c111e9aa
3750 hg import http://www.selenic.com/hg/rev/5ca8c111e9aa
3738
3751
3739 - import all the patches in an Unix-style mbox::
3752 - import all the patches in an Unix-style mbox::
3740
3753
3741 hg import incoming-patches.mbox
3754 hg import incoming-patches.mbox
3742
3755
3743 - attempt to exactly restore an exported changeset (not always
3756 - attempt to exactly restore an exported changeset (not always
3744 possible)::
3757 possible)::
3745
3758
3746 hg import --exact proposed-fix.patch
3759 hg import --exact proposed-fix.patch
3747
3760
3748 Returns 0 on success.
3761 Returns 0 on success.
3749 """
3762 """
3750
3763
3751 if not patch1:
3764 if not patch1:
3752 raise util.Abort(_('need at least one patch to import'))
3765 raise util.Abort(_('need at least one patch to import'))
3753
3766
3754 patches = (patch1,) + patches
3767 patches = (patch1,) + patches
3755
3768
3756 date = opts.get('date')
3769 date = opts.get('date')
3757 if date:
3770 if date:
3758 opts['date'] = util.parsedate(date)
3771 opts['date'] = util.parsedate(date)
3759
3772
3760 update = not opts.get('bypass')
3773 update = not opts.get('bypass')
3761 if not update and opts.get('no_commit'):
3774 if not update and opts.get('no_commit'):
3762 raise util.Abort(_('cannot use --no-commit with --bypass'))
3775 raise util.Abort(_('cannot use --no-commit with --bypass'))
3763 try:
3776 try:
3764 sim = float(opts.get('similarity') or 0)
3777 sim = float(opts.get('similarity') or 0)
3765 except ValueError:
3778 except ValueError:
3766 raise util.Abort(_('similarity must be a number'))
3779 raise util.Abort(_('similarity must be a number'))
3767 if sim < 0 or sim > 100:
3780 if sim < 0 or sim > 100:
3768 raise util.Abort(_('similarity must be between 0 and 100'))
3781 raise util.Abort(_('similarity must be between 0 and 100'))
3769 if sim and not update:
3782 if sim and not update:
3770 raise util.Abort(_('cannot use --similarity with --bypass'))
3783 raise util.Abort(_('cannot use --similarity with --bypass'))
3771
3784
3772 if update:
3785 if update:
3773 cmdutil.checkunfinished(repo)
3786 cmdutil.checkunfinished(repo)
3774 if (opts.get('exact') or not opts.get('force')) and update:
3787 if (opts.get('exact') or not opts.get('force')) and update:
3775 cmdutil.bailifchanged(repo)
3788 cmdutil.bailifchanged(repo)
3776
3789
3777 base = opts["base"]
3790 base = opts["base"]
3778 wlock = lock = tr = None
3791 wlock = lock = tr = None
3779 msgs = []
3792 msgs = []
3780
3793
3781
3794
3782 try:
3795 try:
3783 try:
3796 try:
3784 wlock = repo.wlock()
3797 wlock = repo.wlock()
3785 if not opts.get('no_commit'):
3798 if not opts.get('no_commit'):
3786 lock = repo.lock()
3799 lock = repo.lock()
3787 tr = repo.transaction('import')
3800 tr = repo.transaction('import')
3788 parents = repo.parents()
3801 parents = repo.parents()
3789 for patchurl in patches:
3802 for patchurl in patches:
3790 if patchurl == '-':
3803 if patchurl == '-':
3791 ui.status(_('applying patch from stdin\n'))
3804 ui.status(_('applying patch from stdin\n'))
3792 patchfile = ui.fin
3805 patchfile = ui.fin
3793 patchurl = 'stdin' # for error message
3806 patchurl = 'stdin' # for error message
3794 else:
3807 else:
3795 patchurl = os.path.join(base, patchurl)
3808 patchurl = os.path.join(base, patchurl)
3796 ui.status(_('applying %s\n') % patchurl)
3809 ui.status(_('applying %s\n') % patchurl)
3797 patchfile = hg.openpath(ui, patchurl)
3810 patchfile = hg.openpath(ui, patchurl)
3798
3811
3799 haspatch = False
3812 haspatch = False
3800 for hunk in patch.split(patchfile):
3813 for hunk in patch.split(patchfile):
3801 (msg, node) = cmdutil.tryimportone(ui, repo, hunk, parents,
3814 (msg, node) = cmdutil.tryimportone(ui, repo, hunk, parents,
3802 opts, msgs, hg.clean)
3815 opts, msgs, hg.clean)
3803 if msg:
3816 if msg:
3804 haspatch = True
3817 haspatch = True
3805 ui.note(msg + '\n')
3818 ui.note(msg + '\n')
3806 if update or opts.get('exact'):
3819 if update or opts.get('exact'):
3807 parents = repo.parents()
3820 parents = repo.parents()
3808 else:
3821 else:
3809 parents = [repo[node]]
3822 parents = [repo[node]]
3810
3823
3811 if not haspatch:
3824 if not haspatch:
3812 raise util.Abort(_('%s: no diffs found') % patchurl)
3825 raise util.Abort(_('%s: no diffs found') % patchurl)
3813
3826
3814 if tr:
3827 if tr:
3815 tr.close()
3828 tr.close()
3816 if msgs:
3829 if msgs:
3817 repo.savecommitmessage('\n* * *\n'.join(msgs))
3830 repo.savecommitmessage('\n* * *\n'.join(msgs))
3818 except: # re-raises
3831 except: # re-raises
3819 # wlock.release() indirectly calls dirstate.write(): since
3832 # wlock.release() indirectly calls dirstate.write(): since
3820 # we're crashing, we do not want to change the working dir
3833 # we're crashing, we do not want to change the working dir
3821 # parent after all, so make sure it writes nothing
3834 # parent after all, so make sure it writes nothing
3822 repo.dirstate.invalidate()
3835 repo.dirstate.invalidate()
3823 raise
3836 raise
3824 finally:
3837 finally:
3825 if tr:
3838 if tr:
3826 tr.release()
3839 tr.release()
3827 release(lock, wlock)
3840 release(lock, wlock)
3828
3841
3829 @command('incoming|in',
3842 @command('incoming|in',
3830 [('f', 'force', None,
3843 [('f', 'force', None,
3831 _('run even if remote repository is unrelated')),
3844 _('run even if remote repository is unrelated')),
3832 ('n', 'newest-first', None, _('show newest record first')),
3845 ('n', 'newest-first', None, _('show newest record first')),
3833 ('', 'bundle', '',
3846 ('', 'bundle', '',
3834 _('file to store the bundles into'), _('FILE')),
3847 _('file to store the bundles into'), _('FILE')),
3835 ('r', 'rev', [], _('a remote changeset intended to be added'), _('REV')),
3848 ('r', 'rev', [], _('a remote changeset intended to be added'), _('REV')),
3836 ('B', 'bookmarks', False, _("compare bookmarks")),
3849 ('B', 'bookmarks', False, _("compare bookmarks")),
3837 ('b', 'branch', [],
3850 ('b', 'branch', [],
3838 _('a specific branch you would like to pull'), _('BRANCH')),
3851 _('a specific branch you would like to pull'), _('BRANCH')),
3839 ] + logopts + remoteopts + subrepoopts,
3852 ] + logopts + remoteopts + subrepoopts,
3840 _('[-p] [-n] [-M] [-f] [-r REV]... [--bundle FILENAME] [SOURCE]'))
3853 _('[-p] [-n] [-M] [-f] [-r REV]... [--bundle FILENAME] [SOURCE]'))
3841 def incoming(ui, repo, source="default", **opts):
3854 def incoming(ui, repo, source="default", **opts):
3842 """show new changesets found in source
3855 """show new changesets found in source
3843
3856
3844 Show new changesets found in the specified path/URL or the default
3857 Show new changesets found in the specified path/URL or the default
3845 pull location. These are the changesets that would have been pulled
3858 pull location. These are the changesets that would have been pulled
3846 if a pull at the time you issued this command.
3859 if a pull at the time you issued this command.
3847
3860
3848 For remote repository, using --bundle avoids downloading the
3861 For remote repository, using --bundle avoids downloading the
3849 changesets twice if the incoming is followed by a pull.
3862 changesets twice if the incoming is followed by a pull.
3850
3863
3851 See pull for valid source format details.
3864 See pull for valid source format details.
3852
3865
3853 Returns 0 if there are incoming changes, 1 otherwise.
3866 Returns 0 if there are incoming changes, 1 otherwise.
3854 """
3867 """
3855 if opts.get('graph'):
3868 if opts.get('graph'):
3856 cmdutil.checkunsupportedgraphflags([], opts)
3869 cmdutil.checkunsupportedgraphflags([], opts)
3857 def display(other, chlist, displayer):
3870 def display(other, chlist, displayer):
3858 revdag = cmdutil.graphrevs(other, chlist, opts)
3871 revdag = cmdutil.graphrevs(other, chlist, opts)
3859 showparents = [ctx.node() for ctx in repo[None].parents()]
3872 showparents = [ctx.node() for ctx in repo[None].parents()]
3860 cmdutil.displaygraph(ui, revdag, displayer, showparents,
3873 cmdutil.displaygraph(ui, revdag, displayer, showparents,
3861 graphmod.asciiedges)
3874 graphmod.asciiedges)
3862
3875
3863 hg._incoming(display, lambda: 1, ui, repo, source, opts, buffered=True)
3876 hg._incoming(display, lambda: 1, ui, repo, source, opts, buffered=True)
3864 return 0
3877 return 0
3865
3878
3866 if opts.get('bundle') and opts.get('subrepos'):
3879 if opts.get('bundle') and opts.get('subrepos'):
3867 raise util.Abort(_('cannot combine --bundle and --subrepos'))
3880 raise util.Abort(_('cannot combine --bundle and --subrepos'))
3868
3881
3869 if opts.get('bookmarks'):
3882 if opts.get('bookmarks'):
3870 source, branches = hg.parseurl(ui.expandpath(source),
3883 source, branches = hg.parseurl(ui.expandpath(source),
3871 opts.get('branch'))
3884 opts.get('branch'))
3872 other = hg.peer(repo, opts, source)
3885 other = hg.peer(repo, opts, source)
3873 if 'bookmarks' not in other.listkeys('namespaces'):
3886 if 'bookmarks' not in other.listkeys('namespaces'):
3874 ui.warn(_("remote doesn't support bookmarks\n"))
3887 ui.warn(_("remote doesn't support bookmarks\n"))
3875 return 0
3888 return 0
3876 ui.status(_('comparing with %s\n') % util.hidepassword(source))
3889 ui.status(_('comparing with %s\n') % util.hidepassword(source))
3877 return bookmarks.diff(ui, repo, other)
3890 return bookmarks.diff(ui, repo, other)
3878
3891
3879 repo._subtoppath = ui.expandpath(source)
3892 repo._subtoppath = ui.expandpath(source)
3880 try:
3893 try:
3881 return hg.incoming(ui, repo, source, opts)
3894 return hg.incoming(ui, repo, source, opts)
3882 finally:
3895 finally:
3883 del repo._subtoppath
3896 del repo._subtoppath
3884
3897
3885
3898
3886 @command('^init', remoteopts, _('[-e CMD] [--remotecmd CMD] [DEST]'))
3899 @command('^init', remoteopts, _('[-e CMD] [--remotecmd CMD] [DEST]'))
3887 def init(ui, dest=".", **opts):
3900 def init(ui, dest=".", **opts):
3888 """create a new repository in the given directory
3901 """create a new repository in the given directory
3889
3902
3890 Initialize a new repository in the given directory. If the given
3903 Initialize a new repository in the given directory. If the given
3891 directory does not exist, it will be created.
3904 directory does not exist, it will be created.
3892
3905
3893 If no directory is given, the current directory is used.
3906 If no directory is given, the current directory is used.
3894
3907
3895 It is possible to specify an ``ssh://`` URL as the destination.
3908 It is possible to specify an ``ssh://`` URL as the destination.
3896 See :hg:`help urls` for more information.
3909 See :hg:`help urls` for more information.
3897
3910
3898 Returns 0 on success.
3911 Returns 0 on success.
3899 """
3912 """
3900 hg.peer(ui, opts, ui.expandpath(dest), create=True)
3913 hg.peer(ui, opts, ui.expandpath(dest), create=True)
3901
3914
3902 @command('locate',
3915 @command('locate',
3903 [('r', 'rev', '', _('search the repository as it is in REV'), _('REV')),
3916 [('r', 'rev', '', _('search the repository as it is in REV'), _('REV')),
3904 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
3917 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
3905 ('f', 'fullpath', None, _('print complete paths from the filesystem root')),
3918 ('f', 'fullpath', None, _('print complete paths from the filesystem root')),
3906 ] + walkopts,
3919 ] + walkopts,
3907 _('[OPTION]... [PATTERN]...'))
3920 _('[OPTION]... [PATTERN]...'))
3908 def locate(ui, repo, *pats, **opts):
3921 def locate(ui, repo, *pats, **opts):
3909 """locate files matching specific patterns
3922 """locate files matching specific patterns
3910
3923
3911 Print files under Mercurial control in the working directory whose
3924 Print files under Mercurial control in the working directory whose
3912 names match the given patterns.
3925 names match the given patterns.
3913
3926
3914 By default, this command searches all directories in the working
3927 By default, this command searches all directories in the working
3915 directory. To search just the current directory and its
3928 directory. To search just the current directory and its
3916 subdirectories, use "--include .".
3929 subdirectories, use "--include .".
3917
3930
3918 If no patterns are given to match, this command prints the names
3931 If no patterns are given to match, this command prints the names
3919 of all files under Mercurial control in the working directory.
3932 of all files under Mercurial control in the working directory.
3920
3933
3921 If you want to feed the output of this command into the "xargs"
3934 If you want to feed the output of this command into the "xargs"
3922 command, use the -0 option to both this command and "xargs". This
3935 command, use the -0 option to both this command and "xargs". This
3923 will avoid the problem of "xargs" treating single filenames that
3936 will avoid the problem of "xargs" treating single filenames that
3924 contain whitespace as multiple filenames.
3937 contain whitespace as multiple filenames.
3925
3938
3926 Returns 0 if a match is found, 1 otherwise.
3939 Returns 0 if a match is found, 1 otherwise.
3927 """
3940 """
3928 end = opts.get('print0') and '\0' or '\n'
3941 end = opts.get('print0') and '\0' or '\n'
3929 rev = scmutil.revsingle(repo, opts.get('rev'), None).node()
3942 rev = scmutil.revsingle(repo, opts.get('rev'), None).node()
3930
3943
3931 ret = 1
3944 ret = 1
3932 m = scmutil.match(repo[rev], pats, opts, default='relglob')
3945 m = scmutil.match(repo[rev], pats, opts, default='relglob')
3933 m.bad = lambda x, y: False
3946 m.bad = lambda x, y: False
3934 for abs in repo[rev].walk(m):
3947 for abs in repo[rev].walk(m):
3935 if not rev and abs not in repo.dirstate:
3948 if not rev and abs not in repo.dirstate:
3936 continue
3949 continue
3937 if opts.get('fullpath'):
3950 if opts.get('fullpath'):
3938 ui.write(repo.wjoin(abs), end)
3951 ui.write(repo.wjoin(abs), end)
3939 else:
3952 else:
3940 ui.write(((pats and m.rel(abs)) or abs), end)
3953 ui.write(((pats and m.rel(abs)) or abs), end)
3941 ret = 0
3954 ret = 0
3942
3955
3943 return ret
3956 return ret
3944
3957
3945 @command('^log|history',
3958 @command('^log|history',
3946 [('f', 'follow', None,
3959 [('f', 'follow', None,
3947 _('follow changeset history, or file history across copies and renames')),
3960 _('follow changeset history, or file history across copies and renames')),
3948 ('', 'follow-first', None,
3961 ('', 'follow-first', None,
3949 _('only follow the first parent of merge changesets (DEPRECATED)')),
3962 _('only follow the first parent of merge changesets (DEPRECATED)')),
3950 ('d', 'date', '', _('show revisions matching date spec'), _('DATE')),
3963 ('d', 'date', '', _('show revisions matching date spec'), _('DATE')),
3951 ('C', 'copies', None, _('show copied files')),
3964 ('C', 'copies', None, _('show copied files')),
3952 ('k', 'keyword', [],
3965 ('k', 'keyword', [],
3953 _('do case-insensitive search for a given text'), _('TEXT')),
3966 _('do case-insensitive search for a given text'), _('TEXT')),
3954 ('r', 'rev', [], _('show the specified revision or range'), _('REV')),
3967 ('r', 'rev', [], _('show the specified revision or range'), _('REV')),
3955 ('', 'removed', None, _('include revisions where files were removed')),
3968 ('', 'removed', None, _('include revisions where files were removed')),
3956 ('m', 'only-merges', None, _('show only merges (DEPRECATED)')),
3969 ('m', 'only-merges', None, _('show only merges (DEPRECATED)')),
3957 ('u', 'user', [], _('revisions committed by user'), _('USER')),
3970 ('u', 'user', [], _('revisions committed by user'), _('USER')),
3958 ('', 'only-branch', [],
3971 ('', 'only-branch', [],
3959 _('show only changesets within the given named branch (DEPRECATED)'),
3972 _('show only changesets within the given named branch (DEPRECATED)'),
3960 _('BRANCH')),
3973 _('BRANCH')),
3961 ('b', 'branch', [],
3974 ('b', 'branch', [],
3962 _('show changesets within the given named branch'), _('BRANCH')),
3975 _('show changesets within the given named branch'), _('BRANCH')),
3963 ('P', 'prune', [],
3976 ('P', 'prune', [],
3964 _('do not display revision or any of its ancestors'), _('REV')),
3977 _('do not display revision or any of its ancestors'), _('REV')),
3965 ] + logopts + walkopts,
3978 ] + logopts + walkopts,
3966 _('[OPTION]... [FILE]'))
3979 _('[OPTION]... [FILE]'))
3967 def log(ui, repo, *pats, **opts):
3980 def log(ui, repo, *pats, **opts):
3968 """show revision history of entire repository or files
3981 """show revision history of entire repository or files
3969
3982
3970 Print the revision history of the specified files or the entire
3983 Print the revision history of the specified files or the entire
3971 project.
3984 project.
3972
3985
3973 If no revision range is specified, the default is ``tip:0`` unless
3986 If no revision range is specified, the default is ``tip:0`` unless
3974 --follow is set, in which case the working directory parent is
3987 --follow is set, in which case the working directory parent is
3975 used as the starting revision.
3988 used as the starting revision.
3976
3989
3977 File history is shown without following rename or copy history of
3990 File history is shown without following rename or copy history of
3978 files. Use -f/--follow with a filename to follow history across
3991 files. Use -f/--follow with a filename to follow history across
3979 renames and copies. --follow without a filename will only show
3992 renames and copies. --follow without a filename will only show
3980 ancestors or descendants of the starting revision.
3993 ancestors or descendants of the starting revision.
3981
3994
3982 By default this command prints revision number and changeset id,
3995 By default this command prints revision number and changeset id,
3983 tags, non-trivial parents, user, date and time, and a summary for
3996 tags, non-trivial parents, user, date and time, and a summary for
3984 each commit. When the -v/--verbose switch is used, the list of
3997 each commit. When the -v/--verbose switch is used, the list of
3985 changed files and full commit message are shown.
3998 changed files and full commit message are shown.
3986
3999
3987 With --graph the revisions are shown as an ASCII art DAG with the most
4000 With --graph the revisions are shown as an ASCII art DAG with the most
3988 recent changeset at the top.
4001 recent changeset at the top.
3989 'o' is a changeset, '@' is a working directory parent, 'x' is obsolete,
4002 'o' is a changeset, '@' is a working directory parent, 'x' is obsolete,
3990 and '+' represents a fork where the changeset from the lines below is a
4003 and '+' represents a fork where the changeset from the lines below is a
3991 parent of the 'o' merge on the same same line.
4004 parent of the 'o' merge on the same same line.
3992
4005
3993 .. note::
4006 .. note::
3994
4007
3995 log -p/--patch may generate unexpected diff output for merge
4008 log -p/--patch may generate unexpected diff output for merge
3996 changesets, as it will only compare the merge changeset against
4009 changesets, as it will only compare the merge changeset against
3997 its first parent. Also, only files different from BOTH parents
4010 its first parent. Also, only files different from BOTH parents
3998 will appear in files:.
4011 will appear in files:.
3999
4012
4000 .. note::
4013 .. note::
4001
4014
4002 for performance reasons, log FILE may omit duplicate changes
4015 for performance reasons, log FILE may omit duplicate changes
4003 made on branches and will not show deletions. To see all
4016 made on branches and will not show deletions. To see all
4004 changes including duplicates and deletions, use the --removed
4017 changes including duplicates and deletions, use the --removed
4005 switch.
4018 switch.
4006
4019
4007 .. container:: verbose
4020 .. container:: verbose
4008
4021
4009 Some examples:
4022 Some examples:
4010
4023
4011 - changesets with full descriptions and file lists::
4024 - changesets with full descriptions and file lists::
4012
4025
4013 hg log -v
4026 hg log -v
4014
4027
4015 - changesets ancestral to the working directory::
4028 - changesets ancestral to the working directory::
4016
4029
4017 hg log -f
4030 hg log -f
4018
4031
4019 - last 10 commits on the current branch::
4032 - last 10 commits on the current branch::
4020
4033
4021 hg log -l 10 -b .
4034 hg log -l 10 -b .
4022
4035
4023 - changesets showing all modifications of a file, including removals::
4036 - changesets showing all modifications of a file, including removals::
4024
4037
4025 hg log --removed file.c
4038 hg log --removed file.c
4026
4039
4027 - all changesets that touch a directory, with diffs, excluding merges::
4040 - all changesets that touch a directory, with diffs, excluding merges::
4028
4041
4029 hg log -Mp lib/
4042 hg log -Mp lib/
4030
4043
4031 - all revision numbers that match a keyword::
4044 - all revision numbers that match a keyword::
4032
4045
4033 hg log -k bug --template "{rev}\\n"
4046 hg log -k bug --template "{rev}\\n"
4034
4047
4035 - check if a given changeset is included is a tagged release::
4048 - check if a given changeset is included is a tagged release::
4036
4049
4037 hg log -r "a21ccf and ancestor(1.9)"
4050 hg log -r "a21ccf and ancestor(1.9)"
4038
4051
4039 - find all changesets by some user in a date range::
4052 - find all changesets by some user in a date range::
4040
4053
4041 hg log -k alice -d "may 2008 to jul 2008"
4054 hg log -k alice -d "may 2008 to jul 2008"
4042
4055
4043 - summary of all changesets after the last tag::
4056 - summary of all changesets after the last tag::
4044
4057
4045 hg log -r "last(tagged())::" --template "{desc|firstline}\\n"
4058 hg log -r "last(tagged())::" --template "{desc|firstline}\\n"
4046
4059
4047 See :hg:`help dates` for a list of formats valid for -d/--date.
4060 See :hg:`help dates` for a list of formats valid for -d/--date.
4048
4061
4049 See :hg:`help revisions` and :hg:`help revsets` for more about
4062 See :hg:`help revisions` and :hg:`help revsets` for more about
4050 specifying revisions.
4063 specifying revisions.
4051
4064
4052 See :hg:`help templates` for more about pre-packaged styles and
4065 See :hg:`help templates` for more about pre-packaged styles and
4053 specifying custom templates.
4066 specifying custom templates.
4054
4067
4055 Returns 0 on success.
4068 Returns 0 on success.
4056 """
4069 """
4057 if opts.get('graph'):
4070 if opts.get('graph'):
4058 return cmdutil.graphlog(ui, repo, *pats, **opts)
4071 return cmdutil.graphlog(ui, repo, *pats, **opts)
4059
4072
4060 matchfn = scmutil.match(repo[None], pats, opts)
4073 matchfn = scmutil.match(repo[None], pats, opts)
4061 limit = cmdutil.loglimit(opts)
4074 limit = cmdutil.loglimit(opts)
4062 count = 0
4075 count = 0
4063
4076
4064 getrenamed, endrev = None, None
4077 getrenamed, endrev = None, None
4065 if opts.get('copies'):
4078 if opts.get('copies'):
4066 if opts.get('rev'):
4079 if opts.get('rev'):
4067 endrev = max(scmutil.revrange(repo, opts.get('rev'))) + 1
4080 endrev = max(scmutil.revrange(repo, opts.get('rev'))) + 1
4068 getrenamed = templatekw.getrenamedfn(repo, endrev=endrev)
4081 getrenamed = templatekw.getrenamedfn(repo, endrev=endrev)
4069
4082
4070 df = False
4083 df = False
4071 if opts.get("date"):
4084 if opts.get("date"):
4072 df = util.matchdate(opts["date"])
4085 df = util.matchdate(opts["date"])
4073
4086
4074 branches = opts.get('branch', []) + opts.get('only_branch', [])
4087 branches = opts.get('branch', []) + opts.get('only_branch', [])
4075 opts['branch'] = [repo.lookupbranch(b) for b in branches]
4088 opts['branch'] = [repo.lookupbranch(b) for b in branches]
4076
4089
4077 displayer = cmdutil.show_changeset(ui, repo, opts, True)
4090 displayer = cmdutil.show_changeset(ui, repo, opts, True)
4078 def prep(ctx, fns):
4091 def prep(ctx, fns):
4079 rev = ctx.rev()
4092 rev = ctx.rev()
4080 parents = [p for p in repo.changelog.parentrevs(rev)
4093 parents = [p for p in repo.changelog.parentrevs(rev)
4081 if p != nullrev]
4094 if p != nullrev]
4082 if opts.get('no_merges') and len(parents) == 2:
4095 if opts.get('no_merges') and len(parents) == 2:
4083 return
4096 return
4084 if opts.get('only_merges') and len(parents) != 2:
4097 if opts.get('only_merges') and len(parents) != 2:
4085 return
4098 return
4086 if opts.get('branch') and ctx.branch() not in opts['branch']:
4099 if opts.get('branch') and ctx.branch() not in opts['branch']:
4087 return
4100 return
4088 if df and not df(ctx.date()[0]):
4101 if df and not df(ctx.date()[0]):
4089 return
4102 return
4090
4103
4091 lower = encoding.lower
4104 lower = encoding.lower
4092 if opts.get('user'):
4105 if opts.get('user'):
4093 luser = lower(ctx.user())
4106 luser = lower(ctx.user())
4094 for k in [lower(x) for x in opts['user']]:
4107 for k in [lower(x) for x in opts['user']]:
4095 if (k in luser):
4108 if (k in luser):
4096 break
4109 break
4097 else:
4110 else:
4098 return
4111 return
4099 if opts.get('keyword'):
4112 if opts.get('keyword'):
4100 luser = lower(ctx.user())
4113 luser = lower(ctx.user())
4101 ldesc = lower(ctx.description())
4114 ldesc = lower(ctx.description())
4102 lfiles = lower(" ".join(ctx.files()))
4115 lfiles = lower(" ".join(ctx.files()))
4103 for k in [lower(x) for x in opts['keyword']]:
4116 for k in [lower(x) for x in opts['keyword']]:
4104 if (k in luser or k in ldesc or k in lfiles):
4117 if (k in luser or k in ldesc or k in lfiles):
4105 break
4118 break
4106 else:
4119 else:
4107 return
4120 return
4108
4121
4109 copies = None
4122 copies = None
4110 if getrenamed is not None and rev:
4123 if getrenamed is not None and rev:
4111 copies = []
4124 copies = []
4112 for fn in ctx.files():
4125 for fn in ctx.files():
4113 rename = getrenamed(fn, rev)
4126 rename = getrenamed(fn, rev)
4114 if rename:
4127 if rename:
4115 copies.append((fn, rename[0]))
4128 copies.append((fn, rename[0]))
4116
4129
4117 revmatchfn = None
4130 revmatchfn = None
4118 if opts.get('patch') or opts.get('stat'):
4131 if opts.get('patch') or opts.get('stat'):
4119 if opts.get('follow') or opts.get('follow_first'):
4132 if opts.get('follow') or opts.get('follow_first'):
4120 # note: this might be wrong when following through merges
4133 # note: this might be wrong when following through merges
4121 revmatchfn = scmutil.match(repo[None], fns, default='path')
4134 revmatchfn = scmutil.match(repo[None], fns, default='path')
4122 else:
4135 else:
4123 revmatchfn = matchfn
4136 revmatchfn = matchfn
4124
4137
4125 displayer.show(ctx, copies=copies, matchfn=revmatchfn)
4138 displayer.show(ctx, copies=copies, matchfn=revmatchfn)
4126
4139
4127 for ctx in cmdutil.walkchangerevs(repo, matchfn, opts, prep):
4140 for ctx in cmdutil.walkchangerevs(repo, matchfn, opts, prep):
4128 if displayer.flush(ctx.rev()):
4141 if displayer.flush(ctx.rev()):
4129 count += 1
4142 count += 1
4130 if count == limit:
4143 if count == limit:
4131 break
4144 break
4132 displayer.close()
4145 displayer.close()
4133
4146
4134 @command('manifest',
4147 @command('manifest',
4135 [('r', 'rev', '', _('revision to display'), _('REV')),
4148 [('r', 'rev', '', _('revision to display'), _('REV')),
4136 ('', 'all', False, _("list files from all revisions"))],
4149 ('', 'all', False, _("list files from all revisions"))],
4137 _('[-r REV]'))
4150 _('[-r REV]'))
4138 def manifest(ui, repo, node=None, rev=None, **opts):
4151 def manifest(ui, repo, node=None, rev=None, **opts):
4139 """output the current or given revision of the project manifest
4152 """output the current or given revision of the project manifest
4140
4153
4141 Print a list of version controlled files for the given revision.
4154 Print a list of version controlled files for the given revision.
4142 If no revision is given, the first parent of the working directory
4155 If no revision is given, the first parent of the working directory
4143 is used, or the null revision if no revision is checked out.
4156 is used, or the null revision if no revision is checked out.
4144
4157
4145 With -v, print file permissions, symlink and executable bits.
4158 With -v, print file permissions, symlink and executable bits.
4146 With --debug, print file revision hashes.
4159 With --debug, print file revision hashes.
4147
4160
4148 If option --all is specified, the list of all files from all revisions
4161 If option --all is specified, the list of all files from all revisions
4149 is printed. This includes deleted and renamed files.
4162 is printed. This includes deleted and renamed files.
4150
4163
4151 Returns 0 on success.
4164 Returns 0 on success.
4152 """
4165 """
4153
4166
4154 fm = ui.formatter('manifest', opts)
4167 fm = ui.formatter('manifest', opts)
4155
4168
4156 if opts.get('all'):
4169 if opts.get('all'):
4157 if rev or node:
4170 if rev or node:
4158 raise util.Abort(_("can't specify a revision with --all"))
4171 raise util.Abort(_("can't specify a revision with --all"))
4159
4172
4160 res = []
4173 res = []
4161 prefix = "data/"
4174 prefix = "data/"
4162 suffix = ".i"
4175 suffix = ".i"
4163 plen = len(prefix)
4176 plen = len(prefix)
4164 slen = len(suffix)
4177 slen = len(suffix)
4165 lock = repo.lock()
4178 lock = repo.lock()
4166 try:
4179 try:
4167 for fn, b, size in repo.store.datafiles():
4180 for fn, b, size in repo.store.datafiles():
4168 if size != 0 and fn[-slen:] == suffix and fn[:plen] == prefix:
4181 if size != 0 and fn[-slen:] == suffix and fn[:plen] == prefix:
4169 res.append(fn[plen:-slen])
4182 res.append(fn[plen:-slen])
4170 finally:
4183 finally:
4171 lock.release()
4184 lock.release()
4172 for f in res:
4185 for f in res:
4173 fm.startitem()
4186 fm.startitem()
4174 fm.write("path", '%s\n', f)
4187 fm.write("path", '%s\n', f)
4175 fm.end()
4188 fm.end()
4176 return
4189 return
4177
4190
4178 if rev and node:
4191 if rev and node:
4179 raise util.Abort(_("please specify just one revision"))
4192 raise util.Abort(_("please specify just one revision"))
4180
4193
4181 if not node:
4194 if not node:
4182 node = rev
4195 node = rev
4183
4196
4184 char = {'l': '@', 'x': '*', '': ''}
4197 char = {'l': '@', 'x': '*', '': ''}
4185 mode = {'l': '644', 'x': '755', '': '644'}
4198 mode = {'l': '644', 'x': '755', '': '644'}
4186 ctx = scmutil.revsingle(repo, node)
4199 ctx = scmutil.revsingle(repo, node)
4187 mf = ctx.manifest()
4200 mf = ctx.manifest()
4188 for f in ctx:
4201 for f in ctx:
4189 fm.startitem()
4202 fm.startitem()
4190 fl = ctx[f].flags()
4203 fl = ctx[f].flags()
4191 fm.condwrite(ui.debugflag, 'hash', '%s ', hex(mf[f]))
4204 fm.condwrite(ui.debugflag, 'hash', '%s ', hex(mf[f]))
4192 fm.condwrite(ui.verbose, 'mode type', '%s %1s ', mode[fl], char[fl])
4205 fm.condwrite(ui.verbose, 'mode type', '%s %1s ', mode[fl], char[fl])
4193 fm.write('path', '%s\n', f)
4206 fm.write('path', '%s\n', f)
4194 fm.end()
4207 fm.end()
4195
4208
4196 @command('^merge',
4209 @command('^merge',
4197 [('f', 'force', None,
4210 [('f', 'force', None,
4198 _('force a merge including outstanding changes (DEPRECATED)')),
4211 _('force a merge including outstanding changes (DEPRECATED)')),
4199 ('r', 'rev', '', _('revision to merge'), _('REV')),
4212 ('r', 'rev', '', _('revision to merge'), _('REV')),
4200 ('P', 'preview', None,
4213 ('P', 'preview', None,
4201 _('review revisions to merge (no merge is performed)'))
4214 _('review revisions to merge (no merge is performed)'))
4202 ] + mergetoolopts,
4215 ] + mergetoolopts,
4203 _('[-P] [-f] [[-r] REV]'))
4216 _('[-P] [-f] [[-r] REV]'))
4204 def merge(ui, repo, node=None, **opts):
4217 def merge(ui, repo, node=None, **opts):
4205 """merge working directory with another revision
4218 """merge working directory with another revision
4206
4219
4207 The current working directory is updated with all changes made in
4220 The current working directory is updated with all changes made in
4208 the requested revision since the last common predecessor revision.
4221 the requested revision since the last common predecessor revision.
4209
4222
4210 Files that changed between either parent are marked as changed for
4223 Files that changed between either parent are marked as changed for
4211 the next commit and a commit must be performed before any further
4224 the next commit and a commit must be performed before any further
4212 updates to the repository are allowed. The next commit will have
4225 updates to the repository are allowed. The next commit will have
4213 two parents.
4226 two parents.
4214
4227
4215 ``--tool`` can be used to specify the merge tool used for file
4228 ``--tool`` can be used to specify the merge tool used for file
4216 merges. It overrides the HGMERGE environment variable and your
4229 merges. It overrides the HGMERGE environment variable and your
4217 configuration files. See :hg:`help merge-tools` for options.
4230 configuration files. See :hg:`help merge-tools` for options.
4218
4231
4219 If no revision is specified, the working directory's parent is a
4232 If no revision is specified, the working directory's parent is a
4220 head revision, and the current branch contains exactly one other
4233 head revision, and the current branch contains exactly one other
4221 head, the other head is merged with by default. Otherwise, an
4234 head, the other head is merged with by default. Otherwise, an
4222 explicit revision with which to merge with must be provided.
4235 explicit revision with which to merge with must be provided.
4223
4236
4224 :hg:`resolve` must be used to resolve unresolved files.
4237 :hg:`resolve` must be used to resolve unresolved files.
4225
4238
4226 To undo an uncommitted merge, use :hg:`update --clean .` which
4239 To undo an uncommitted merge, use :hg:`update --clean .` which
4227 will check out a clean copy of the original merge parent, losing
4240 will check out a clean copy of the original merge parent, losing
4228 all changes.
4241 all changes.
4229
4242
4230 Returns 0 on success, 1 if there are unresolved files.
4243 Returns 0 on success, 1 if there are unresolved files.
4231 """
4244 """
4232
4245
4233 if opts.get('rev') and node:
4246 if opts.get('rev') and node:
4234 raise util.Abort(_("please specify just one revision"))
4247 raise util.Abort(_("please specify just one revision"))
4235 if not node:
4248 if not node:
4236 node = opts.get('rev')
4249 node = opts.get('rev')
4237
4250
4238 if node:
4251 if node:
4239 node = scmutil.revsingle(repo, node).node()
4252 node = scmutil.revsingle(repo, node).node()
4240
4253
4241 if not node and repo._bookmarkcurrent:
4254 if not node and repo._bookmarkcurrent:
4242 bmheads = repo.bookmarkheads(repo._bookmarkcurrent)
4255 bmheads = repo.bookmarkheads(repo._bookmarkcurrent)
4243 curhead = repo[repo._bookmarkcurrent].node()
4256 curhead = repo[repo._bookmarkcurrent].node()
4244 if len(bmheads) == 2:
4257 if len(bmheads) == 2:
4245 if curhead == bmheads[0]:
4258 if curhead == bmheads[0]:
4246 node = bmheads[1]
4259 node = bmheads[1]
4247 else:
4260 else:
4248 node = bmheads[0]
4261 node = bmheads[0]
4249 elif len(bmheads) > 2:
4262 elif len(bmheads) > 2:
4250 raise util.Abort(_("multiple matching bookmarks to merge - "
4263 raise util.Abort(_("multiple matching bookmarks to merge - "
4251 "please merge with an explicit rev or bookmark"),
4264 "please merge with an explicit rev or bookmark"),
4252 hint=_("run 'hg heads' to see all heads"))
4265 hint=_("run 'hg heads' to see all heads"))
4253 elif len(bmheads) <= 1:
4266 elif len(bmheads) <= 1:
4254 raise util.Abort(_("no matching bookmark to merge - "
4267 raise util.Abort(_("no matching bookmark to merge - "
4255 "please merge with an explicit rev or bookmark"),
4268 "please merge with an explicit rev or bookmark"),
4256 hint=_("run 'hg heads' to see all heads"))
4269 hint=_("run 'hg heads' to see all heads"))
4257
4270
4258 if not node and not repo._bookmarkcurrent:
4271 if not node and not repo._bookmarkcurrent:
4259 branch = repo[None].branch()
4272 branch = repo[None].branch()
4260 bheads = repo.branchheads(branch)
4273 bheads = repo.branchheads(branch)
4261 nbhs = [bh for bh in bheads if not repo[bh].bookmarks()]
4274 nbhs = [bh for bh in bheads if not repo[bh].bookmarks()]
4262
4275
4263 if len(nbhs) > 2:
4276 if len(nbhs) > 2:
4264 raise util.Abort(_("branch '%s' has %d heads - "
4277 raise util.Abort(_("branch '%s' has %d heads - "
4265 "please merge with an explicit rev")
4278 "please merge with an explicit rev")
4266 % (branch, len(bheads)),
4279 % (branch, len(bheads)),
4267 hint=_("run 'hg heads .' to see heads"))
4280 hint=_("run 'hg heads .' to see heads"))
4268
4281
4269 parent = repo.dirstate.p1()
4282 parent = repo.dirstate.p1()
4270 if len(nbhs) <= 1:
4283 if len(nbhs) <= 1:
4271 if len(bheads) > 1:
4284 if len(bheads) > 1:
4272 raise util.Abort(_("heads are bookmarked - "
4285 raise util.Abort(_("heads are bookmarked - "
4273 "please merge with an explicit rev"),
4286 "please merge with an explicit rev"),
4274 hint=_("run 'hg heads' to see all heads"))
4287 hint=_("run 'hg heads' to see all heads"))
4275 if len(repo.heads()) > 1:
4288 if len(repo.heads()) > 1:
4276 raise util.Abort(_("branch '%s' has one head - "
4289 raise util.Abort(_("branch '%s' has one head - "
4277 "please merge with an explicit rev")
4290 "please merge with an explicit rev")
4278 % branch,
4291 % branch,
4279 hint=_("run 'hg heads' to see all heads"))
4292 hint=_("run 'hg heads' to see all heads"))
4280 msg, hint = _('nothing to merge'), None
4293 msg, hint = _('nothing to merge'), None
4281 if parent != repo.lookup(branch):
4294 if parent != repo.lookup(branch):
4282 hint = _("use 'hg update' instead")
4295 hint = _("use 'hg update' instead")
4283 raise util.Abort(msg, hint=hint)
4296 raise util.Abort(msg, hint=hint)
4284
4297
4285 if parent not in bheads:
4298 if parent not in bheads:
4286 raise util.Abort(_('working directory not at a head revision'),
4299 raise util.Abort(_('working directory not at a head revision'),
4287 hint=_("use 'hg update' or merge with an "
4300 hint=_("use 'hg update' or merge with an "
4288 "explicit revision"))
4301 "explicit revision"))
4289 if parent == nbhs[0]:
4302 if parent == nbhs[0]:
4290 node = nbhs[-1]
4303 node = nbhs[-1]
4291 else:
4304 else:
4292 node = nbhs[0]
4305 node = nbhs[0]
4293
4306
4294 if opts.get('preview'):
4307 if opts.get('preview'):
4295 # find nodes that are ancestors of p2 but not of p1
4308 # find nodes that are ancestors of p2 but not of p1
4296 p1 = repo.lookup('.')
4309 p1 = repo.lookup('.')
4297 p2 = repo.lookup(node)
4310 p2 = repo.lookup(node)
4298 nodes = repo.changelog.findmissing(common=[p1], heads=[p2])
4311 nodes = repo.changelog.findmissing(common=[p1], heads=[p2])
4299
4312
4300 displayer = cmdutil.show_changeset(ui, repo, opts)
4313 displayer = cmdutil.show_changeset(ui, repo, opts)
4301 for node in nodes:
4314 for node in nodes:
4302 displayer.show(repo[node])
4315 displayer.show(repo[node])
4303 displayer.close()
4316 displayer.close()
4304 return 0
4317 return 0
4305
4318
4306 try:
4319 try:
4307 # ui.forcemerge is an internal variable, do not document
4320 # ui.forcemerge is an internal variable, do not document
4308 repo.ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
4321 repo.ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
4309 return hg.merge(repo, node, force=opts.get('force'))
4322 return hg.merge(repo, node, force=opts.get('force'))
4310 finally:
4323 finally:
4311 ui.setconfig('ui', 'forcemerge', '')
4324 ui.setconfig('ui', 'forcemerge', '')
4312
4325
4313 @command('outgoing|out',
4326 @command('outgoing|out',
4314 [('f', 'force', None, _('run even when the destination is unrelated')),
4327 [('f', 'force', None, _('run even when the destination is unrelated')),
4315 ('r', 'rev', [],
4328 ('r', 'rev', [],
4316 _('a changeset intended to be included in the destination'), _('REV')),
4329 _('a changeset intended to be included in the destination'), _('REV')),
4317 ('n', 'newest-first', None, _('show newest record first')),
4330 ('n', 'newest-first', None, _('show newest record first')),
4318 ('B', 'bookmarks', False, _('compare bookmarks')),
4331 ('B', 'bookmarks', False, _('compare bookmarks')),
4319 ('b', 'branch', [], _('a specific branch you would like to push'),
4332 ('b', 'branch', [], _('a specific branch you would like to push'),
4320 _('BRANCH')),
4333 _('BRANCH')),
4321 ] + logopts + remoteopts + subrepoopts,
4334 ] + logopts + remoteopts + subrepoopts,
4322 _('[-M] [-p] [-n] [-f] [-r REV]... [DEST]'))
4335 _('[-M] [-p] [-n] [-f] [-r REV]... [DEST]'))
4323 def outgoing(ui, repo, dest=None, **opts):
4336 def outgoing(ui, repo, dest=None, **opts):
4324 """show changesets not found in the destination
4337 """show changesets not found in the destination
4325
4338
4326 Show changesets not found in the specified destination repository
4339 Show changesets not found in the specified destination repository
4327 or the default push location. These are the changesets that would
4340 or the default push location. These are the changesets that would
4328 be pushed if a push was requested.
4341 be pushed if a push was requested.
4329
4342
4330 See pull for details of valid destination formats.
4343 See pull for details of valid destination formats.
4331
4344
4332 Returns 0 if there are outgoing changes, 1 otherwise.
4345 Returns 0 if there are outgoing changes, 1 otherwise.
4333 """
4346 """
4334 if opts.get('graph'):
4347 if opts.get('graph'):
4335 cmdutil.checkunsupportedgraphflags([], opts)
4348 cmdutil.checkunsupportedgraphflags([], opts)
4336 o = hg._outgoing(ui, repo, dest, opts)
4349 o = hg._outgoing(ui, repo, dest, opts)
4337 if o is None:
4350 if o is None:
4338 return
4351 return
4339
4352
4340 revdag = cmdutil.graphrevs(repo, o, opts)
4353 revdag = cmdutil.graphrevs(repo, o, opts)
4341 displayer = cmdutil.show_changeset(ui, repo, opts, buffered=True)
4354 displayer = cmdutil.show_changeset(ui, repo, opts, buffered=True)
4342 showparents = [ctx.node() for ctx in repo[None].parents()]
4355 showparents = [ctx.node() for ctx in repo[None].parents()]
4343 cmdutil.displaygraph(ui, revdag, displayer, showparents,
4356 cmdutil.displaygraph(ui, revdag, displayer, showparents,
4344 graphmod.asciiedges)
4357 graphmod.asciiedges)
4345 return 0
4358 return 0
4346
4359
4347 if opts.get('bookmarks'):
4360 if opts.get('bookmarks'):
4348 dest = ui.expandpath(dest or 'default-push', dest or 'default')
4361 dest = ui.expandpath(dest or 'default-push', dest or 'default')
4349 dest, branches = hg.parseurl(dest, opts.get('branch'))
4362 dest, branches = hg.parseurl(dest, opts.get('branch'))
4350 other = hg.peer(repo, opts, dest)
4363 other = hg.peer(repo, opts, dest)
4351 if 'bookmarks' not in other.listkeys('namespaces'):
4364 if 'bookmarks' not in other.listkeys('namespaces'):
4352 ui.warn(_("remote doesn't support bookmarks\n"))
4365 ui.warn(_("remote doesn't support bookmarks\n"))
4353 return 0
4366 return 0
4354 ui.status(_('comparing with %s\n') % util.hidepassword(dest))
4367 ui.status(_('comparing with %s\n') % util.hidepassword(dest))
4355 return bookmarks.diff(ui, other, repo)
4368 return bookmarks.diff(ui, other, repo)
4356
4369
4357 repo._subtoppath = ui.expandpath(dest or 'default-push', dest or 'default')
4370 repo._subtoppath = ui.expandpath(dest or 'default-push', dest or 'default')
4358 try:
4371 try:
4359 return hg.outgoing(ui, repo, dest, opts)
4372 return hg.outgoing(ui, repo, dest, opts)
4360 finally:
4373 finally:
4361 del repo._subtoppath
4374 del repo._subtoppath
4362
4375
4363 @command('parents',
4376 @command('parents',
4364 [('r', 'rev', '', _('show parents of the specified revision'), _('REV')),
4377 [('r', 'rev', '', _('show parents of the specified revision'), _('REV')),
4365 ] + templateopts,
4378 ] + templateopts,
4366 _('[-r REV] [FILE]'))
4379 _('[-r REV] [FILE]'))
4367 def parents(ui, repo, file_=None, **opts):
4380 def parents(ui, repo, file_=None, **opts):
4368 """show the parents of the working directory or revision
4381 """show the parents of the working directory or revision
4369
4382
4370 Print the working directory's parent revisions. If a revision is
4383 Print the working directory's parent revisions. If a revision is
4371 given via -r/--rev, the parent of that revision will be printed.
4384 given via -r/--rev, the parent of that revision will be printed.
4372 If a file argument is given, the revision in which the file was
4385 If a file argument is given, the revision in which the file was
4373 last changed (before the working directory revision or the
4386 last changed (before the working directory revision or the
4374 argument to --rev if given) is printed.
4387 argument to --rev if given) is printed.
4375
4388
4376 Returns 0 on success.
4389 Returns 0 on success.
4377 """
4390 """
4378
4391
4379 ctx = scmutil.revsingle(repo, opts.get('rev'), None)
4392 ctx = scmutil.revsingle(repo, opts.get('rev'), None)
4380
4393
4381 if file_:
4394 if file_:
4382 m = scmutil.match(ctx, (file_,), opts)
4395 m = scmutil.match(ctx, (file_,), opts)
4383 if m.anypats() or len(m.files()) != 1:
4396 if m.anypats() or len(m.files()) != 1:
4384 raise util.Abort(_('can only specify an explicit filename'))
4397 raise util.Abort(_('can only specify an explicit filename'))
4385 file_ = m.files()[0]
4398 file_ = m.files()[0]
4386 filenodes = []
4399 filenodes = []
4387 for cp in ctx.parents():
4400 for cp in ctx.parents():
4388 if not cp:
4401 if not cp:
4389 continue
4402 continue
4390 try:
4403 try:
4391 filenodes.append(cp.filenode(file_))
4404 filenodes.append(cp.filenode(file_))
4392 except error.LookupError:
4405 except error.LookupError:
4393 pass
4406 pass
4394 if not filenodes:
4407 if not filenodes:
4395 raise util.Abort(_("'%s' not found in manifest!") % file_)
4408 raise util.Abort(_("'%s' not found in manifest!") % file_)
4396 p = []
4409 p = []
4397 for fn in filenodes:
4410 for fn in filenodes:
4398 fctx = repo.filectx(file_, fileid=fn)
4411 fctx = repo.filectx(file_, fileid=fn)
4399 p.append(fctx.node())
4412 p.append(fctx.node())
4400 else:
4413 else:
4401 p = [cp.node() for cp in ctx.parents()]
4414 p = [cp.node() for cp in ctx.parents()]
4402
4415
4403 displayer = cmdutil.show_changeset(ui, repo, opts)
4416 displayer = cmdutil.show_changeset(ui, repo, opts)
4404 for n in p:
4417 for n in p:
4405 if n != nullid:
4418 if n != nullid:
4406 displayer.show(repo[n])
4419 displayer.show(repo[n])
4407 displayer.close()
4420 displayer.close()
4408
4421
4409 @command('paths', [], _('[NAME]'))
4422 @command('paths', [], _('[NAME]'))
4410 def paths(ui, repo, search=None):
4423 def paths(ui, repo, search=None):
4411 """show aliases for remote repositories
4424 """show aliases for remote repositories
4412
4425
4413 Show definition of symbolic path name NAME. If no name is given,
4426 Show definition of symbolic path name NAME. If no name is given,
4414 show definition of all available names.
4427 show definition of all available names.
4415
4428
4416 Option -q/--quiet suppresses all output when searching for NAME
4429 Option -q/--quiet suppresses all output when searching for NAME
4417 and shows only the path names when listing all definitions.
4430 and shows only the path names when listing all definitions.
4418
4431
4419 Path names are defined in the [paths] section of your
4432 Path names are defined in the [paths] section of your
4420 configuration file and in ``/etc/mercurial/hgrc``. If run inside a
4433 configuration file and in ``/etc/mercurial/hgrc``. If run inside a
4421 repository, ``.hg/hgrc`` is used, too.
4434 repository, ``.hg/hgrc`` is used, too.
4422
4435
4423 The path names ``default`` and ``default-push`` have a special
4436 The path names ``default`` and ``default-push`` have a special
4424 meaning. When performing a push or pull operation, they are used
4437 meaning. When performing a push or pull operation, they are used
4425 as fallbacks if no location is specified on the command-line.
4438 as fallbacks if no location is specified on the command-line.
4426 When ``default-push`` is set, it will be used for push and
4439 When ``default-push`` is set, it will be used for push and
4427 ``default`` will be used for pull; otherwise ``default`` is used
4440 ``default`` will be used for pull; otherwise ``default`` is used
4428 as the fallback for both. When cloning a repository, the clone
4441 as the fallback for both. When cloning a repository, the clone
4429 source is written as ``default`` in ``.hg/hgrc``. Note that
4442 source is written as ``default`` in ``.hg/hgrc``. Note that
4430 ``default`` and ``default-push`` apply to all inbound (e.g.
4443 ``default`` and ``default-push`` apply to all inbound (e.g.
4431 :hg:`incoming`) and outbound (e.g. :hg:`outgoing`, :hg:`email` and
4444 :hg:`incoming`) and outbound (e.g. :hg:`outgoing`, :hg:`email` and
4432 :hg:`bundle`) operations.
4445 :hg:`bundle`) operations.
4433
4446
4434 See :hg:`help urls` for more information.
4447 See :hg:`help urls` for more information.
4435
4448
4436 Returns 0 on success.
4449 Returns 0 on success.
4437 """
4450 """
4438 if search:
4451 if search:
4439 for name, path in ui.configitems("paths"):
4452 for name, path in ui.configitems("paths"):
4440 if name == search:
4453 if name == search:
4441 ui.status("%s\n" % util.hidepassword(path))
4454 ui.status("%s\n" % util.hidepassword(path))
4442 return
4455 return
4443 if not ui.quiet:
4456 if not ui.quiet:
4444 ui.warn(_("not found!\n"))
4457 ui.warn(_("not found!\n"))
4445 return 1
4458 return 1
4446 else:
4459 else:
4447 for name, path in ui.configitems("paths"):
4460 for name, path in ui.configitems("paths"):
4448 if ui.quiet:
4461 if ui.quiet:
4449 ui.write("%s\n" % name)
4462 ui.write("%s\n" % name)
4450 else:
4463 else:
4451 ui.write("%s = %s\n" % (name, util.hidepassword(path)))
4464 ui.write("%s = %s\n" % (name, util.hidepassword(path)))
4452
4465
4453 @command('phase',
4466 @command('phase',
4454 [('p', 'public', False, _('set changeset phase to public')),
4467 [('p', 'public', False, _('set changeset phase to public')),
4455 ('d', 'draft', False, _('set changeset phase to draft')),
4468 ('d', 'draft', False, _('set changeset phase to draft')),
4456 ('s', 'secret', False, _('set changeset phase to secret')),
4469 ('s', 'secret', False, _('set changeset phase to secret')),
4457 ('f', 'force', False, _('allow to move boundary backward')),
4470 ('f', 'force', False, _('allow to move boundary backward')),
4458 ('r', 'rev', [], _('target revision'), _('REV')),
4471 ('r', 'rev', [], _('target revision'), _('REV')),
4459 ],
4472 ],
4460 _('[-p|-d|-s] [-f] [-r] REV...'))
4473 _('[-p|-d|-s] [-f] [-r] REV...'))
4461 def phase(ui, repo, *revs, **opts):
4474 def phase(ui, repo, *revs, **opts):
4462 """set or show the current phase name
4475 """set or show the current phase name
4463
4476
4464 With no argument, show the phase name of specified revisions.
4477 With no argument, show the phase name of specified revisions.
4465
4478
4466 With one of -p/--public, -d/--draft or -s/--secret, change the
4479 With one of -p/--public, -d/--draft or -s/--secret, change the
4467 phase value of the specified revisions.
4480 phase value of the specified revisions.
4468
4481
4469 Unless -f/--force is specified, :hg:`phase` won't move changeset from a
4482 Unless -f/--force is specified, :hg:`phase` won't move changeset from a
4470 lower phase to an higher phase. Phases are ordered as follows::
4483 lower phase to an higher phase. Phases are ordered as follows::
4471
4484
4472 public < draft < secret
4485 public < draft < secret
4473
4486
4474 Returns 0 on success, 1 if no phases were changed or some could not
4487 Returns 0 on success, 1 if no phases were changed or some could not
4475 be changed.
4488 be changed.
4476 """
4489 """
4477 # search for a unique phase argument
4490 # search for a unique phase argument
4478 targetphase = None
4491 targetphase = None
4479 for idx, name in enumerate(phases.phasenames):
4492 for idx, name in enumerate(phases.phasenames):
4480 if opts[name]:
4493 if opts[name]:
4481 if targetphase is not None:
4494 if targetphase is not None:
4482 raise util.Abort(_('only one phase can be specified'))
4495 raise util.Abort(_('only one phase can be specified'))
4483 targetphase = idx
4496 targetphase = idx
4484
4497
4485 # look for specified revision
4498 # look for specified revision
4486 revs = list(revs)
4499 revs = list(revs)
4487 revs.extend(opts['rev'])
4500 revs.extend(opts['rev'])
4488 if not revs:
4501 if not revs:
4489 raise util.Abort(_('no revisions specified'))
4502 raise util.Abort(_('no revisions specified'))
4490
4503
4491 revs = scmutil.revrange(repo, revs)
4504 revs = scmutil.revrange(repo, revs)
4492
4505
4493 lock = None
4506 lock = None
4494 ret = 0
4507 ret = 0
4495 if targetphase is None:
4508 if targetphase is None:
4496 # display
4509 # display
4497 for r in revs:
4510 for r in revs:
4498 ctx = repo[r]
4511 ctx = repo[r]
4499 ui.write('%i: %s\n' % (ctx.rev(), ctx.phasestr()))
4512 ui.write('%i: %s\n' % (ctx.rev(), ctx.phasestr()))
4500 else:
4513 else:
4501 lock = repo.lock()
4514 lock = repo.lock()
4502 try:
4515 try:
4503 # set phase
4516 # set phase
4504 if not revs:
4517 if not revs:
4505 raise util.Abort(_('empty revision set'))
4518 raise util.Abort(_('empty revision set'))
4506 nodes = [repo[r].node() for r in revs]
4519 nodes = [repo[r].node() for r in revs]
4507 olddata = repo._phasecache.getphaserevs(repo)[:]
4520 olddata = repo._phasecache.getphaserevs(repo)[:]
4508 phases.advanceboundary(repo, targetphase, nodes)
4521 phases.advanceboundary(repo, targetphase, nodes)
4509 if opts['force']:
4522 if opts['force']:
4510 phases.retractboundary(repo, targetphase, nodes)
4523 phases.retractboundary(repo, targetphase, nodes)
4511 finally:
4524 finally:
4512 lock.release()
4525 lock.release()
4513 # moving revision from public to draft may hide them
4526 # moving revision from public to draft may hide them
4514 # We have to check result on an unfiltered repository
4527 # We have to check result on an unfiltered repository
4515 unfi = repo.unfiltered()
4528 unfi = repo.unfiltered()
4516 newdata = repo._phasecache.getphaserevs(unfi)
4529 newdata = repo._phasecache.getphaserevs(unfi)
4517 changes = sum(o != newdata[i] for i, o in enumerate(olddata))
4530 changes = sum(o != newdata[i] for i, o in enumerate(olddata))
4518 cl = unfi.changelog
4531 cl = unfi.changelog
4519 rejected = [n for n in nodes
4532 rejected = [n for n in nodes
4520 if newdata[cl.rev(n)] < targetphase]
4533 if newdata[cl.rev(n)] < targetphase]
4521 if rejected:
4534 if rejected:
4522 ui.warn(_('cannot move %i changesets to a higher '
4535 ui.warn(_('cannot move %i changesets to a higher '
4523 'phase, use --force\n') % len(rejected))
4536 'phase, use --force\n') % len(rejected))
4524 ret = 1
4537 ret = 1
4525 if changes:
4538 if changes:
4526 msg = _('phase changed for %i changesets\n') % changes
4539 msg = _('phase changed for %i changesets\n') % changes
4527 if ret:
4540 if ret:
4528 ui.status(msg)
4541 ui.status(msg)
4529 else:
4542 else:
4530 ui.note(msg)
4543 ui.note(msg)
4531 else:
4544 else:
4532 ui.warn(_('no phases changed\n'))
4545 ui.warn(_('no phases changed\n'))
4533 ret = 1
4546 ret = 1
4534 return ret
4547 return ret
4535
4548
4536 def postincoming(ui, repo, modheads, optupdate, checkout):
4549 def postincoming(ui, repo, modheads, optupdate, checkout):
4537 if modheads == 0:
4550 if modheads == 0:
4538 return
4551 return
4539 if optupdate:
4552 if optupdate:
4540 checkout, movemarkfrom = bookmarks.calculateupdate(ui, repo, checkout)
4553 checkout, movemarkfrom = bookmarks.calculateupdate(ui, repo, checkout)
4541 try:
4554 try:
4542 ret = hg.update(repo, checkout)
4555 ret = hg.update(repo, checkout)
4543 except util.Abort, inst:
4556 except util.Abort, inst:
4544 ui.warn(_("not updating: %s\n") % str(inst))
4557 ui.warn(_("not updating: %s\n") % str(inst))
4545 if inst.hint:
4558 if inst.hint:
4546 ui.warn(_("(%s)\n") % inst.hint)
4559 ui.warn(_("(%s)\n") % inst.hint)
4547 return 0
4560 return 0
4548 if not ret and not checkout:
4561 if not ret and not checkout:
4549 if bookmarks.update(repo, [movemarkfrom], repo['.'].node()):
4562 if bookmarks.update(repo, [movemarkfrom], repo['.'].node()):
4550 ui.status(_("updating bookmark %s\n") % repo._bookmarkcurrent)
4563 ui.status(_("updating bookmark %s\n") % repo._bookmarkcurrent)
4551 return ret
4564 return ret
4552 if modheads > 1:
4565 if modheads > 1:
4553 currentbranchheads = len(repo.branchheads())
4566 currentbranchheads = len(repo.branchheads())
4554 if currentbranchheads == modheads:
4567 if currentbranchheads == modheads:
4555 ui.status(_("(run 'hg heads' to see heads, 'hg merge' to merge)\n"))
4568 ui.status(_("(run 'hg heads' to see heads, 'hg merge' to merge)\n"))
4556 elif currentbranchheads > 1:
4569 elif currentbranchheads > 1:
4557 ui.status(_("(run 'hg heads .' to see heads, 'hg merge' to "
4570 ui.status(_("(run 'hg heads .' to see heads, 'hg merge' to "
4558 "merge)\n"))
4571 "merge)\n"))
4559 else:
4572 else:
4560 ui.status(_("(run 'hg heads' to see heads)\n"))
4573 ui.status(_("(run 'hg heads' to see heads)\n"))
4561 else:
4574 else:
4562 ui.status(_("(run 'hg update' to get a working copy)\n"))
4575 ui.status(_("(run 'hg update' to get a working copy)\n"))
4563
4576
4564 @command('^pull',
4577 @command('^pull',
4565 [('u', 'update', None,
4578 [('u', 'update', None,
4566 _('update to new branch head if changesets were pulled')),
4579 _('update to new branch head if changesets were pulled')),
4567 ('f', 'force', None, _('run even when remote repository is unrelated')),
4580 ('f', 'force', None, _('run even when remote repository is unrelated')),
4568 ('r', 'rev', [], _('a remote changeset intended to be added'), _('REV')),
4581 ('r', 'rev', [], _('a remote changeset intended to be added'), _('REV')),
4569 ('B', 'bookmark', [], _("bookmark to pull"), _('BOOKMARK')),
4582 ('B', 'bookmark', [], _("bookmark to pull"), _('BOOKMARK')),
4570 ('b', 'branch', [], _('a specific branch you would like to pull'),
4583 ('b', 'branch', [], _('a specific branch you would like to pull'),
4571 _('BRANCH')),
4584 _('BRANCH')),
4572 ] + remoteopts,
4585 ] + remoteopts,
4573 _('[-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]'))
4586 _('[-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]'))
4574 def pull(ui, repo, source="default", **opts):
4587 def pull(ui, repo, source="default", **opts):
4575 """pull changes from the specified source
4588 """pull changes from the specified source
4576
4589
4577 Pull changes from a remote repository to a local one.
4590 Pull changes from a remote repository to a local one.
4578
4591
4579 This finds all changes from the repository at the specified path
4592 This finds all changes from the repository at the specified path
4580 or URL and adds them to a local repository (the current one unless
4593 or URL and adds them to a local repository (the current one unless
4581 -R is specified). By default, this does not update the copy of the
4594 -R is specified). By default, this does not update the copy of the
4582 project in the working directory.
4595 project in the working directory.
4583
4596
4584 Use :hg:`incoming` if you want to see what would have been added
4597 Use :hg:`incoming` if you want to see what would have been added
4585 by a pull at the time you issued this command. If you then decide
4598 by a pull at the time you issued this command. If you then decide
4586 to add those changes to the repository, you should use :hg:`pull
4599 to add those changes to the repository, you should use :hg:`pull
4587 -r X` where ``X`` is the last changeset listed by :hg:`incoming`.
4600 -r X` where ``X`` is the last changeset listed by :hg:`incoming`.
4588
4601
4589 If SOURCE is omitted, the 'default' path will be used.
4602 If SOURCE is omitted, the 'default' path will be used.
4590 See :hg:`help urls` for more information.
4603 See :hg:`help urls` for more information.
4591
4604
4592 Returns 0 on success, 1 if an update had unresolved files.
4605 Returns 0 on success, 1 if an update had unresolved files.
4593 """
4606 """
4594 source, branches = hg.parseurl(ui.expandpath(source), opts.get('branch'))
4607 source, branches = hg.parseurl(ui.expandpath(source), opts.get('branch'))
4595 other = hg.peer(repo, opts, source)
4608 other = hg.peer(repo, opts, source)
4596 try:
4609 try:
4597 ui.status(_('pulling from %s\n') % util.hidepassword(source))
4610 ui.status(_('pulling from %s\n') % util.hidepassword(source))
4598 revs, checkout = hg.addbranchrevs(repo, other, branches,
4611 revs, checkout = hg.addbranchrevs(repo, other, branches,
4599 opts.get('rev'))
4612 opts.get('rev'))
4600
4613
4601 remotebookmarks = other.listkeys('bookmarks')
4614 remotebookmarks = other.listkeys('bookmarks')
4602
4615
4603 if opts.get('bookmark'):
4616 if opts.get('bookmark'):
4604 if not revs:
4617 if not revs:
4605 revs = []
4618 revs = []
4606 for b in opts['bookmark']:
4619 for b in opts['bookmark']:
4607 if b not in remotebookmarks:
4620 if b not in remotebookmarks:
4608 raise util.Abort(_('remote bookmark %s not found!') % b)
4621 raise util.Abort(_('remote bookmark %s not found!') % b)
4609 revs.append(remotebookmarks[b])
4622 revs.append(remotebookmarks[b])
4610
4623
4611 if revs:
4624 if revs:
4612 try:
4625 try:
4613 revs = [other.lookup(rev) for rev in revs]
4626 revs = [other.lookup(rev) for rev in revs]
4614 except error.CapabilityError:
4627 except error.CapabilityError:
4615 err = _("other repository doesn't support revision lookup, "
4628 err = _("other repository doesn't support revision lookup, "
4616 "so a rev cannot be specified.")
4629 "so a rev cannot be specified.")
4617 raise util.Abort(err)
4630 raise util.Abort(err)
4618
4631
4619 modheads = repo.pull(other, heads=revs, force=opts.get('force'))
4632 modheads = repo.pull(other, heads=revs, force=opts.get('force'))
4620 bookmarks.updatefromremote(ui, repo, remotebookmarks, source)
4633 bookmarks.updatefromremote(ui, repo, remotebookmarks, source)
4621 if checkout:
4634 if checkout:
4622 checkout = str(repo.changelog.rev(other.lookup(checkout)))
4635 checkout = str(repo.changelog.rev(other.lookup(checkout)))
4623 repo._subtoppath = source
4636 repo._subtoppath = source
4624 try:
4637 try:
4625 ret = postincoming(ui, repo, modheads, opts.get('update'), checkout)
4638 ret = postincoming(ui, repo, modheads, opts.get('update'), checkout)
4626
4639
4627 finally:
4640 finally:
4628 del repo._subtoppath
4641 del repo._subtoppath
4629
4642
4630 # update specified bookmarks
4643 # update specified bookmarks
4631 if opts.get('bookmark'):
4644 if opts.get('bookmark'):
4632 marks = repo._bookmarks
4645 marks = repo._bookmarks
4633 for b in opts['bookmark']:
4646 for b in opts['bookmark']:
4634 # explicit pull overrides local bookmark if any
4647 # explicit pull overrides local bookmark if any
4635 ui.status(_("importing bookmark %s\n") % b)
4648 ui.status(_("importing bookmark %s\n") % b)
4636 marks[b] = repo[remotebookmarks[b]].node()
4649 marks[b] = repo[remotebookmarks[b]].node()
4637 marks.write()
4650 marks.write()
4638 finally:
4651 finally:
4639 other.close()
4652 other.close()
4640 return ret
4653 return ret
4641
4654
4642 @command('^push',
4655 @command('^push',
4643 [('f', 'force', None, _('force push')),
4656 [('f', 'force', None, _('force push')),
4644 ('r', 'rev', [],
4657 ('r', 'rev', [],
4645 _('a changeset intended to be included in the destination'),
4658 _('a changeset intended to be included in the destination'),
4646 _('REV')),
4659 _('REV')),
4647 ('B', 'bookmark', [], _("bookmark to push"), _('BOOKMARK')),
4660 ('B', 'bookmark', [], _("bookmark to push"), _('BOOKMARK')),
4648 ('b', 'branch', [],
4661 ('b', 'branch', [],
4649 _('a specific branch you would like to push'), _('BRANCH')),
4662 _('a specific branch you would like to push'), _('BRANCH')),
4650 ('', 'new-branch', False, _('allow pushing a new branch')),
4663 ('', 'new-branch', False, _('allow pushing a new branch')),
4651 ] + remoteopts,
4664 ] + remoteopts,
4652 _('[-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]'))
4665 _('[-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]'))
4653 def push(ui, repo, dest=None, **opts):
4666 def push(ui, repo, dest=None, **opts):
4654 """push changes to the specified destination
4667 """push changes to the specified destination
4655
4668
4656 Push changesets from the local repository to the specified
4669 Push changesets from the local repository to the specified
4657 destination.
4670 destination.
4658
4671
4659 This operation is symmetrical to pull: it is identical to a pull
4672 This operation is symmetrical to pull: it is identical to a pull
4660 in the destination repository from the current one.
4673 in the destination repository from the current one.
4661
4674
4662 By default, push will not allow creation of new heads at the
4675 By default, push will not allow creation of new heads at the
4663 destination, since multiple heads would make it unclear which head
4676 destination, since multiple heads would make it unclear which head
4664 to use. In this situation, it is recommended to pull and merge
4677 to use. In this situation, it is recommended to pull and merge
4665 before pushing.
4678 before pushing.
4666
4679
4667 Use --new-branch if you want to allow push to create a new named
4680 Use --new-branch if you want to allow push to create a new named
4668 branch that is not present at the destination. This allows you to
4681 branch that is not present at the destination. This allows you to
4669 only create a new branch without forcing other changes.
4682 only create a new branch without forcing other changes.
4670
4683
4671 .. note::
4684 .. note::
4672
4685
4673 Extra care should be taken with the -f/--force option,
4686 Extra care should be taken with the -f/--force option,
4674 which will push all new heads on all branches, an action which will
4687 which will push all new heads on all branches, an action which will
4675 almost always cause confusion for collaborators.
4688 almost always cause confusion for collaborators.
4676
4689
4677 If -r/--rev is used, the specified revision and all its ancestors
4690 If -r/--rev is used, the specified revision and all its ancestors
4678 will be pushed to the remote repository.
4691 will be pushed to the remote repository.
4679
4692
4680 If -B/--bookmark is used, the specified bookmarked revision, its
4693 If -B/--bookmark is used, the specified bookmarked revision, its
4681 ancestors, and the bookmark will be pushed to the remote
4694 ancestors, and the bookmark will be pushed to the remote
4682 repository.
4695 repository.
4683
4696
4684 Please see :hg:`help urls` for important details about ``ssh://``
4697 Please see :hg:`help urls` for important details about ``ssh://``
4685 URLs. If DESTINATION is omitted, a default path will be used.
4698 URLs. If DESTINATION is omitted, a default path will be used.
4686
4699
4687 Returns 0 if push was successful, 1 if nothing to push.
4700 Returns 0 if push was successful, 1 if nothing to push.
4688 """
4701 """
4689
4702
4690 if opts.get('bookmark'):
4703 if opts.get('bookmark'):
4691 ui.setconfig('bookmarks', 'pushing', opts['bookmark'])
4704 ui.setconfig('bookmarks', 'pushing', opts['bookmark'])
4692 for b in opts['bookmark']:
4705 for b in opts['bookmark']:
4693 # translate -B options to -r so changesets get pushed
4706 # translate -B options to -r so changesets get pushed
4694 if b in repo._bookmarks:
4707 if b in repo._bookmarks:
4695 opts.setdefault('rev', []).append(b)
4708 opts.setdefault('rev', []).append(b)
4696 else:
4709 else:
4697 # if we try to push a deleted bookmark, translate it to null
4710 # if we try to push a deleted bookmark, translate it to null
4698 # this lets simultaneous -r, -b options continue working
4711 # this lets simultaneous -r, -b options continue working
4699 opts.setdefault('rev', []).append("null")
4712 opts.setdefault('rev', []).append("null")
4700
4713
4701 dest = ui.expandpath(dest or 'default-push', dest or 'default')
4714 dest = ui.expandpath(dest or 'default-push', dest or 'default')
4702 dest, branches = hg.parseurl(dest, opts.get('branch'))
4715 dest, branches = hg.parseurl(dest, opts.get('branch'))
4703 ui.status(_('pushing to %s\n') % util.hidepassword(dest))
4716 ui.status(_('pushing to %s\n') % util.hidepassword(dest))
4704 revs, checkout = hg.addbranchrevs(repo, repo, branches, opts.get('rev'))
4717 revs, checkout = hg.addbranchrevs(repo, repo, branches, opts.get('rev'))
4705 try:
4718 try:
4706 other = hg.peer(repo, opts, dest)
4719 other = hg.peer(repo, opts, dest)
4707 except error.RepoError:
4720 except error.RepoError:
4708 if dest == "default-push":
4721 if dest == "default-push":
4709 raise util.Abort(_("default repository not configured!"),
4722 raise util.Abort(_("default repository not configured!"),
4710 hint=_('see the "path" section in "hg help config"'))
4723 hint=_('see the "path" section in "hg help config"'))
4711 else:
4724 else:
4712 raise
4725 raise
4713
4726
4714 if revs:
4727 if revs:
4715 revs = [repo.lookup(r) for r in scmutil.revrange(repo, revs)]
4728 revs = [repo.lookup(r) for r in scmutil.revrange(repo, revs)]
4716
4729
4717 repo._subtoppath = dest
4730 repo._subtoppath = dest
4718 try:
4731 try:
4719 # push subrepos depth-first for coherent ordering
4732 # push subrepos depth-first for coherent ordering
4720 c = repo['']
4733 c = repo['']
4721 subs = c.substate # only repos that are committed
4734 subs = c.substate # only repos that are committed
4722 for s in sorted(subs):
4735 for s in sorted(subs):
4723 if c.sub(s).push(opts) == 0:
4736 if c.sub(s).push(opts) == 0:
4724 return False
4737 return False
4725 finally:
4738 finally:
4726 del repo._subtoppath
4739 del repo._subtoppath
4727 result = repo.push(other, opts.get('force'), revs=revs,
4740 result = repo.push(other, opts.get('force'), revs=revs,
4728 newbranch=opts.get('new_branch'))
4741 newbranch=opts.get('new_branch'))
4729
4742
4730 result = not result
4743 result = not result
4731
4744
4732 if opts.get('bookmark'):
4745 if opts.get('bookmark'):
4733 bresult = bookmarks.pushtoremote(ui, repo, other, opts['bookmark'])
4746 bresult = bookmarks.pushtoremote(ui, repo, other, opts['bookmark'])
4734 if bresult == 2:
4747 if bresult == 2:
4735 return 2
4748 return 2
4736 if not result and bresult:
4749 if not result and bresult:
4737 result = 2
4750 result = 2
4738
4751
4739 return result
4752 return result
4740
4753
4741 @command('recover', [])
4754 @command('recover', [])
4742 def recover(ui, repo):
4755 def recover(ui, repo):
4743 """roll back an interrupted transaction
4756 """roll back an interrupted transaction
4744
4757
4745 Recover from an interrupted commit or pull.
4758 Recover from an interrupted commit or pull.
4746
4759
4747 This command tries to fix the repository status after an
4760 This command tries to fix the repository status after an
4748 interrupted operation. It should only be necessary when Mercurial
4761 interrupted operation. It should only be necessary when Mercurial
4749 suggests it.
4762 suggests it.
4750
4763
4751 Returns 0 if successful, 1 if nothing to recover or verify fails.
4764 Returns 0 if successful, 1 if nothing to recover or verify fails.
4752 """
4765 """
4753 if repo.recover():
4766 if repo.recover():
4754 return hg.verify(repo)
4767 return hg.verify(repo)
4755 return 1
4768 return 1
4756
4769
4757 @command('^remove|rm',
4770 @command('^remove|rm',
4758 [('A', 'after', None, _('record delete for missing files')),
4771 [('A', 'after', None, _('record delete for missing files')),
4759 ('f', 'force', None,
4772 ('f', 'force', None,
4760 _('remove (and delete) file even if added or modified')),
4773 _('remove (and delete) file even if added or modified')),
4761 ] + walkopts,
4774 ] + walkopts,
4762 _('[OPTION]... FILE...'))
4775 _('[OPTION]... FILE...'))
4763 def remove(ui, repo, *pats, **opts):
4776 def remove(ui, repo, *pats, **opts):
4764 """remove the specified files on the next commit
4777 """remove the specified files on the next commit
4765
4778
4766 Schedule the indicated files for removal from the current branch.
4779 Schedule the indicated files for removal from the current branch.
4767
4780
4768 This command schedules the files to be removed at the next commit.
4781 This command schedules the files to be removed at the next commit.
4769 To undo a remove before that, see :hg:`revert`. To undo added
4782 To undo a remove before that, see :hg:`revert`. To undo added
4770 files, see :hg:`forget`.
4783 files, see :hg:`forget`.
4771
4784
4772 .. container:: verbose
4785 .. container:: verbose
4773
4786
4774 -A/--after can be used to remove only files that have already
4787 -A/--after can be used to remove only files that have already
4775 been deleted, -f/--force can be used to force deletion, and -Af
4788 been deleted, -f/--force can be used to force deletion, and -Af
4776 can be used to remove files from the next revision without
4789 can be used to remove files from the next revision without
4777 deleting them from the working directory.
4790 deleting them from the working directory.
4778
4791
4779 The following table details the behavior of remove for different
4792 The following table details the behavior of remove for different
4780 file states (columns) and option combinations (rows). The file
4793 file states (columns) and option combinations (rows). The file
4781 states are Added [A], Clean [C], Modified [M] and Missing [!]
4794 states are Added [A], Clean [C], Modified [M] and Missing [!]
4782 (as reported by :hg:`status`). The actions are Warn, Remove
4795 (as reported by :hg:`status`). The actions are Warn, Remove
4783 (from branch) and Delete (from disk):
4796 (from branch) and Delete (from disk):
4784
4797
4785 ========= == == == ==
4798 ========= == == == ==
4786 opt/state A C M !
4799 opt/state A C M !
4787 ========= == == == ==
4800 ========= == == == ==
4788 none W RD W R
4801 none W RD W R
4789 -f R RD RD R
4802 -f R RD RD R
4790 -A W W W R
4803 -A W W W R
4791 -Af R R R R
4804 -Af R R R R
4792 ========= == == == ==
4805 ========= == == == ==
4793
4806
4794 Note that remove never deletes files in Added [A] state from the
4807 Note that remove never deletes files in Added [A] state from the
4795 working directory, not even if option --force is specified.
4808 working directory, not even if option --force is specified.
4796
4809
4797 Returns 0 on success, 1 if any warnings encountered.
4810 Returns 0 on success, 1 if any warnings encountered.
4798 """
4811 """
4799
4812
4800 ret = 0
4813 ret = 0
4801 after, force = opts.get('after'), opts.get('force')
4814 after, force = opts.get('after'), opts.get('force')
4802 if not pats and not after:
4815 if not pats and not after:
4803 raise util.Abort(_('no files specified'))
4816 raise util.Abort(_('no files specified'))
4804
4817
4805 m = scmutil.match(repo[None], pats, opts)
4818 m = scmutil.match(repo[None], pats, opts)
4806 s = repo.status(match=m, clean=True)
4819 s = repo.status(match=m, clean=True)
4807 modified, added, deleted, clean = s[0], s[1], s[3], s[6]
4820 modified, added, deleted, clean = s[0], s[1], s[3], s[6]
4808
4821
4809 # warn about failure to delete explicit files/dirs
4822 # warn about failure to delete explicit files/dirs
4810 wctx = repo[None]
4823 wctx = repo[None]
4811 for f in m.files():
4824 for f in m.files():
4812 if f in repo.dirstate or f in wctx.dirs():
4825 if f in repo.dirstate or f in wctx.dirs():
4813 continue
4826 continue
4814 if os.path.exists(m.rel(f)):
4827 if os.path.exists(m.rel(f)):
4815 if os.path.isdir(m.rel(f)):
4828 if os.path.isdir(m.rel(f)):
4816 ui.warn(_('not removing %s: no tracked files\n') % m.rel(f))
4829 ui.warn(_('not removing %s: no tracked files\n') % m.rel(f))
4817 else:
4830 else:
4818 ui.warn(_('not removing %s: file is untracked\n') % m.rel(f))
4831 ui.warn(_('not removing %s: file is untracked\n') % m.rel(f))
4819 # missing files will generate a warning elsewhere
4832 # missing files will generate a warning elsewhere
4820 ret = 1
4833 ret = 1
4821
4834
4822 if force:
4835 if force:
4823 list = modified + deleted + clean + added
4836 list = modified + deleted + clean + added
4824 elif after:
4837 elif after:
4825 list = deleted
4838 list = deleted
4826 for f in modified + added + clean:
4839 for f in modified + added + clean:
4827 ui.warn(_('not removing %s: file still exists\n') % m.rel(f))
4840 ui.warn(_('not removing %s: file still exists\n') % m.rel(f))
4828 ret = 1
4841 ret = 1
4829 else:
4842 else:
4830 list = deleted + clean
4843 list = deleted + clean
4831 for f in modified:
4844 for f in modified:
4832 ui.warn(_('not removing %s: file is modified (use -f'
4845 ui.warn(_('not removing %s: file is modified (use -f'
4833 ' to force removal)\n') % m.rel(f))
4846 ' to force removal)\n') % m.rel(f))
4834 ret = 1
4847 ret = 1
4835 for f in added:
4848 for f in added:
4836 ui.warn(_('not removing %s: file has been marked for add'
4849 ui.warn(_('not removing %s: file has been marked for add'
4837 ' (use forget to undo)\n') % m.rel(f))
4850 ' (use forget to undo)\n') % m.rel(f))
4838 ret = 1
4851 ret = 1
4839
4852
4840 for f in sorted(list):
4853 for f in sorted(list):
4841 if ui.verbose or not m.exact(f):
4854 if ui.verbose or not m.exact(f):
4842 ui.status(_('removing %s\n') % m.rel(f))
4855 ui.status(_('removing %s\n') % m.rel(f))
4843
4856
4844 wlock = repo.wlock()
4857 wlock = repo.wlock()
4845 try:
4858 try:
4846 if not after:
4859 if not after:
4847 for f in list:
4860 for f in list:
4848 if f in added:
4861 if f in added:
4849 continue # we never unlink added files on remove
4862 continue # we never unlink added files on remove
4850 util.unlinkpath(repo.wjoin(f), ignoremissing=True)
4863 util.unlinkpath(repo.wjoin(f), ignoremissing=True)
4851 repo[None].forget(list)
4864 repo[None].forget(list)
4852 finally:
4865 finally:
4853 wlock.release()
4866 wlock.release()
4854
4867
4855 return ret
4868 return ret
4856
4869
4857 @command('rename|move|mv',
4870 @command('rename|move|mv',
4858 [('A', 'after', None, _('record a rename that has already occurred')),
4871 [('A', 'after', None, _('record a rename that has already occurred')),
4859 ('f', 'force', None, _('forcibly copy over an existing managed file')),
4872 ('f', 'force', None, _('forcibly copy over an existing managed file')),
4860 ] + walkopts + dryrunopts,
4873 ] + walkopts + dryrunopts,
4861 _('[OPTION]... SOURCE... DEST'))
4874 _('[OPTION]... SOURCE... DEST'))
4862 def rename(ui, repo, *pats, **opts):
4875 def rename(ui, repo, *pats, **opts):
4863 """rename files; equivalent of copy + remove
4876 """rename files; equivalent of copy + remove
4864
4877
4865 Mark dest as copies of sources; mark sources for deletion. If dest
4878 Mark dest as copies of sources; mark sources for deletion. If dest
4866 is a directory, copies are put in that directory. If dest is a
4879 is a directory, copies are put in that directory. If dest is a
4867 file, there can only be one source.
4880 file, there can only be one source.
4868
4881
4869 By default, this command copies the contents of files as they
4882 By default, this command copies the contents of files as they
4870 exist in the working directory. If invoked with -A/--after, the
4883 exist in the working directory. If invoked with -A/--after, the
4871 operation is recorded, but no copying is performed.
4884 operation is recorded, but no copying is performed.
4872
4885
4873 This command takes effect at the next commit. To undo a rename
4886 This command takes effect at the next commit. To undo a rename
4874 before that, see :hg:`revert`.
4887 before that, see :hg:`revert`.
4875
4888
4876 Returns 0 on success, 1 if errors are encountered.
4889 Returns 0 on success, 1 if errors are encountered.
4877 """
4890 """
4878 wlock = repo.wlock(False)
4891 wlock = repo.wlock(False)
4879 try:
4892 try:
4880 return cmdutil.copy(ui, repo, pats, opts, rename=True)
4893 return cmdutil.copy(ui, repo, pats, opts, rename=True)
4881 finally:
4894 finally:
4882 wlock.release()
4895 wlock.release()
4883
4896
4884 @command('resolve',
4897 @command('resolve',
4885 [('a', 'all', None, _('select all unresolved files')),
4898 [('a', 'all', None, _('select all unresolved files')),
4886 ('l', 'list', None, _('list state of files needing merge')),
4899 ('l', 'list', None, _('list state of files needing merge')),
4887 ('m', 'mark', None, _('mark files as resolved')),
4900 ('m', 'mark', None, _('mark files as resolved')),
4888 ('u', 'unmark', None, _('mark files as unresolved')),
4901 ('u', 'unmark', None, _('mark files as unresolved')),
4889 ('n', 'no-status', None, _('hide status prefix'))]
4902 ('n', 'no-status', None, _('hide status prefix'))]
4890 + mergetoolopts + walkopts,
4903 + mergetoolopts + walkopts,
4891 _('[OPTION]... [FILE]...'))
4904 _('[OPTION]... [FILE]...'))
4892 def resolve(ui, repo, *pats, **opts):
4905 def resolve(ui, repo, *pats, **opts):
4893 """redo merges or set/view the merge status of files
4906 """redo merges or set/view the merge status of files
4894
4907
4895 Merges with unresolved conflicts are often the result of
4908 Merges with unresolved conflicts are often the result of
4896 non-interactive merging using the ``internal:merge`` configuration
4909 non-interactive merging using the ``internal:merge`` configuration
4897 setting, or a command-line merge tool like ``diff3``. The resolve
4910 setting, or a command-line merge tool like ``diff3``. The resolve
4898 command is used to manage the files involved in a merge, after
4911 command is used to manage the files involved in a merge, after
4899 :hg:`merge` has been run, and before :hg:`commit` is run (i.e. the
4912 :hg:`merge` has been run, and before :hg:`commit` is run (i.e. the
4900 working directory must have two parents). See :hg:`help
4913 working directory must have two parents). See :hg:`help
4901 merge-tools` for information on configuring merge tools.
4914 merge-tools` for information on configuring merge tools.
4902
4915
4903 The resolve command can be used in the following ways:
4916 The resolve command can be used in the following ways:
4904
4917
4905 - :hg:`resolve [--tool TOOL] FILE...`: attempt to re-merge the specified
4918 - :hg:`resolve [--tool TOOL] FILE...`: attempt to re-merge the specified
4906 files, discarding any previous merge attempts. Re-merging is not
4919 files, discarding any previous merge attempts. Re-merging is not
4907 performed for files already marked as resolved. Use ``--all/-a``
4920 performed for files already marked as resolved. Use ``--all/-a``
4908 to select all unresolved files. ``--tool`` can be used to specify
4921 to select all unresolved files. ``--tool`` can be used to specify
4909 the merge tool used for the given files. It overrides the HGMERGE
4922 the merge tool used for the given files. It overrides the HGMERGE
4910 environment variable and your configuration files. Previous file
4923 environment variable and your configuration files. Previous file
4911 contents are saved with a ``.orig`` suffix.
4924 contents are saved with a ``.orig`` suffix.
4912
4925
4913 - :hg:`resolve -m [FILE]`: mark a file as having been resolved
4926 - :hg:`resolve -m [FILE]`: mark a file as having been resolved
4914 (e.g. after having manually fixed-up the files). The default is
4927 (e.g. after having manually fixed-up the files). The default is
4915 to mark all unresolved files.
4928 to mark all unresolved files.
4916
4929
4917 - :hg:`resolve -u [FILE]...`: mark a file as unresolved. The
4930 - :hg:`resolve -u [FILE]...`: mark a file as unresolved. The
4918 default is to mark all resolved files.
4931 default is to mark all resolved files.
4919
4932
4920 - :hg:`resolve -l`: list files which had or still have conflicts.
4933 - :hg:`resolve -l`: list files which had or still have conflicts.
4921 In the printed list, ``U`` = unresolved and ``R`` = resolved.
4934 In the printed list, ``U`` = unresolved and ``R`` = resolved.
4922
4935
4923 Note that Mercurial will not let you commit files with unresolved
4936 Note that Mercurial will not let you commit files with unresolved
4924 merge conflicts. You must use :hg:`resolve -m ...` before you can
4937 merge conflicts. You must use :hg:`resolve -m ...` before you can
4925 commit after a conflicting merge.
4938 commit after a conflicting merge.
4926
4939
4927 Returns 0 on success, 1 if any files fail a resolve attempt.
4940 Returns 0 on success, 1 if any files fail a resolve attempt.
4928 """
4941 """
4929
4942
4930 all, mark, unmark, show, nostatus = \
4943 all, mark, unmark, show, nostatus = \
4931 [opts.get(o) for o in 'all mark unmark list no_status'.split()]
4944 [opts.get(o) for o in 'all mark unmark list no_status'.split()]
4932
4945
4933 if (show and (mark or unmark)) or (mark and unmark):
4946 if (show and (mark or unmark)) or (mark and unmark):
4934 raise util.Abort(_("too many options specified"))
4947 raise util.Abort(_("too many options specified"))
4935 if pats and all:
4948 if pats and all:
4936 raise util.Abort(_("can't specify --all and patterns"))
4949 raise util.Abort(_("can't specify --all and patterns"))
4937 if not (all or pats or show or mark or unmark):
4950 if not (all or pats or show or mark or unmark):
4938 raise util.Abort(_('no files or directories specified; '
4951 raise util.Abort(_('no files or directories specified; '
4939 'use --all to remerge all files'))
4952 'use --all to remerge all files'))
4940
4953
4941 ms = mergemod.mergestate(repo)
4954 ms = mergemod.mergestate(repo)
4942 m = scmutil.match(repo[None], pats, opts)
4955 m = scmutil.match(repo[None], pats, opts)
4943 ret = 0
4956 ret = 0
4944
4957
4945 for f in ms:
4958 for f in ms:
4946 if m(f):
4959 if m(f):
4947 if show:
4960 if show:
4948 if nostatus:
4961 if nostatus:
4949 ui.write("%s\n" % f)
4962 ui.write("%s\n" % f)
4950 else:
4963 else:
4951 ui.write("%s %s\n" % (ms[f].upper(), f),
4964 ui.write("%s %s\n" % (ms[f].upper(), f),
4952 label='resolve.' +
4965 label='resolve.' +
4953 {'u': 'unresolved', 'r': 'resolved'}[ms[f]])
4966 {'u': 'unresolved', 'r': 'resolved'}[ms[f]])
4954 elif mark:
4967 elif mark:
4955 ms.mark(f, "r")
4968 ms.mark(f, "r")
4956 elif unmark:
4969 elif unmark:
4957 ms.mark(f, "u")
4970 ms.mark(f, "u")
4958 else:
4971 else:
4959 wctx = repo[None]
4972 wctx = repo[None]
4960
4973
4961 # backup pre-resolve (merge uses .orig for its own purposes)
4974 # backup pre-resolve (merge uses .orig for its own purposes)
4962 a = repo.wjoin(f)
4975 a = repo.wjoin(f)
4963 util.copyfile(a, a + ".resolve")
4976 util.copyfile(a, a + ".resolve")
4964
4977
4965 try:
4978 try:
4966 # resolve file
4979 # resolve file
4967 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
4980 ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
4968 if ms.resolve(f, wctx):
4981 if ms.resolve(f, wctx):
4969 ret = 1
4982 ret = 1
4970 finally:
4983 finally:
4971 ui.setconfig('ui', 'forcemerge', '')
4984 ui.setconfig('ui', 'forcemerge', '')
4972 ms.commit()
4985 ms.commit()
4973
4986
4974 # replace filemerge's .orig file with our resolve file
4987 # replace filemerge's .orig file with our resolve file
4975 util.rename(a + ".resolve", a + ".orig")
4988 util.rename(a + ".resolve", a + ".orig")
4976
4989
4977 ms.commit()
4990 ms.commit()
4978 return ret
4991 return ret
4979
4992
4980 @command('revert',
4993 @command('revert',
4981 [('a', 'all', None, _('revert all changes when no arguments given')),
4994 [('a', 'all', None, _('revert all changes when no arguments given')),
4982 ('d', 'date', '', _('tipmost revision matching date'), _('DATE')),
4995 ('d', 'date', '', _('tipmost revision matching date'), _('DATE')),
4983 ('r', 'rev', '', _('revert to the specified revision'), _('REV')),
4996 ('r', 'rev', '', _('revert to the specified revision'), _('REV')),
4984 ('C', 'no-backup', None, _('do not save backup copies of files')),
4997 ('C', 'no-backup', None, _('do not save backup copies of files')),
4985 ] + walkopts + dryrunopts,
4998 ] + walkopts + dryrunopts,
4986 _('[OPTION]... [-r REV] [NAME]...'))
4999 _('[OPTION]... [-r REV] [NAME]...'))
4987 def revert(ui, repo, *pats, **opts):
5000 def revert(ui, repo, *pats, **opts):
4988 """restore files to their checkout state
5001 """restore files to their checkout state
4989
5002
4990 .. note::
5003 .. note::
4991
5004
4992 To check out earlier revisions, you should use :hg:`update REV`.
5005 To check out earlier revisions, you should use :hg:`update REV`.
4993 To cancel an uncommitted merge (and lose your changes),
5006 To cancel an uncommitted merge (and lose your changes),
4994 use :hg:`update --clean .`.
5007 use :hg:`update --clean .`.
4995
5008
4996 With no revision specified, revert the specified files or directories
5009 With no revision specified, revert the specified files or directories
4997 to the contents they had in the parent of the working directory.
5010 to the contents they had in the parent of the working directory.
4998 This restores the contents of files to an unmodified
5011 This restores the contents of files to an unmodified
4999 state and unschedules adds, removes, copies, and renames. If the
5012 state and unschedules adds, removes, copies, and renames. If the
5000 working directory has two parents, you must explicitly specify a
5013 working directory has two parents, you must explicitly specify a
5001 revision.
5014 revision.
5002
5015
5003 Using the -r/--rev or -d/--date options, revert the given files or
5016 Using the -r/--rev or -d/--date options, revert the given files or
5004 directories to their states as of a specific revision. Because
5017 directories to their states as of a specific revision. Because
5005 revert does not change the working directory parents, this will
5018 revert does not change the working directory parents, this will
5006 cause these files to appear modified. This can be helpful to "back
5019 cause these files to appear modified. This can be helpful to "back
5007 out" some or all of an earlier change. See :hg:`backout` for a
5020 out" some or all of an earlier change. See :hg:`backout` for a
5008 related method.
5021 related method.
5009
5022
5010 Modified files are saved with a .orig suffix before reverting.
5023 Modified files are saved with a .orig suffix before reverting.
5011 To disable these backups, use --no-backup.
5024 To disable these backups, use --no-backup.
5012
5025
5013 See :hg:`help dates` for a list of formats valid for -d/--date.
5026 See :hg:`help dates` for a list of formats valid for -d/--date.
5014
5027
5015 Returns 0 on success.
5028 Returns 0 on success.
5016 """
5029 """
5017
5030
5018 if opts.get("date"):
5031 if opts.get("date"):
5019 if opts.get("rev"):
5032 if opts.get("rev"):
5020 raise util.Abort(_("you can't specify a revision and a date"))
5033 raise util.Abort(_("you can't specify a revision and a date"))
5021 opts["rev"] = cmdutil.finddate(ui, repo, opts["date"])
5034 opts["rev"] = cmdutil.finddate(ui, repo, opts["date"])
5022
5035
5023 parent, p2 = repo.dirstate.parents()
5036 parent, p2 = repo.dirstate.parents()
5024 if not opts.get('rev') and p2 != nullid:
5037 if not opts.get('rev') and p2 != nullid:
5025 # revert after merge is a trap for new users (issue2915)
5038 # revert after merge is a trap for new users (issue2915)
5026 raise util.Abort(_('uncommitted merge with no revision specified'),
5039 raise util.Abort(_('uncommitted merge with no revision specified'),
5027 hint=_('use "hg update" or see "hg help revert"'))
5040 hint=_('use "hg update" or see "hg help revert"'))
5028
5041
5029 ctx = scmutil.revsingle(repo, opts.get('rev'))
5042 ctx = scmutil.revsingle(repo, opts.get('rev'))
5030
5043
5031 if not pats and not opts.get('all'):
5044 if not pats and not opts.get('all'):
5032 msg = _("no files or directories specified")
5045 msg = _("no files or directories specified")
5033 if p2 != nullid:
5046 if p2 != nullid:
5034 hint = _("uncommitted merge, use --all to discard all changes,"
5047 hint = _("uncommitted merge, use --all to discard all changes,"
5035 " or 'hg update -C .' to abort the merge")
5048 " or 'hg update -C .' to abort the merge")
5036 raise util.Abort(msg, hint=hint)
5049 raise util.Abort(msg, hint=hint)
5037 dirty = util.any(repo.status())
5050 dirty = util.any(repo.status())
5038 node = ctx.node()
5051 node = ctx.node()
5039 if node != parent:
5052 if node != parent:
5040 if dirty:
5053 if dirty:
5041 hint = _("uncommitted changes, use --all to discard all"
5054 hint = _("uncommitted changes, use --all to discard all"
5042 " changes, or 'hg update %s' to update") % ctx.rev()
5055 " changes, or 'hg update %s' to update") % ctx.rev()
5043 else:
5056 else:
5044 hint = _("use --all to revert all files,"
5057 hint = _("use --all to revert all files,"
5045 " or 'hg update %s' to update") % ctx.rev()
5058 " or 'hg update %s' to update") % ctx.rev()
5046 elif dirty:
5059 elif dirty:
5047 hint = _("uncommitted changes, use --all to discard all changes")
5060 hint = _("uncommitted changes, use --all to discard all changes")
5048 else:
5061 else:
5049 hint = _("use --all to revert all files")
5062 hint = _("use --all to revert all files")
5050 raise util.Abort(msg, hint=hint)
5063 raise util.Abort(msg, hint=hint)
5051
5064
5052 return cmdutil.revert(ui, repo, ctx, (parent, p2), *pats, **opts)
5065 return cmdutil.revert(ui, repo, ctx, (parent, p2), *pats, **opts)
5053
5066
5054 @command('rollback', dryrunopts +
5067 @command('rollback', dryrunopts +
5055 [('f', 'force', False, _('ignore safety measures'))])
5068 [('f', 'force', False, _('ignore safety measures'))])
5056 def rollback(ui, repo, **opts):
5069 def rollback(ui, repo, **opts):
5057 """roll back the last transaction (DANGEROUS) (DEPRECATED)
5070 """roll back the last transaction (DANGEROUS) (DEPRECATED)
5058
5071
5059 Please use :hg:`commit --amend` instead of rollback to correct
5072 Please use :hg:`commit --amend` instead of rollback to correct
5060 mistakes in the last commit.
5073 mistakes in the last commit.
5061
5074
5062 This command should be used with care. There is only one level of
5075 This command should be used with care. There is only one level of
5063 rollback, and there is no way to undo a rollback. It will also
5076 rollback, and there is no way to undo a rollback. It will also
5064 restore the dirstate at the time of the last transaction, losing
5077 restore the dirstate at the time of the last transaction, losing
5065 any dirstate changes since that time. This command does not alter
5078 any dirstate changes since that time. This command does not alter
5066 the working directory.
5079 the working directory.
5067
5080
5068 Transactions are used to encapsulate the effects of all commands
5081 Transactions are used to encapsulate the effects of all commands
5069 that create new changesets or propagate existing changesets into a
5082 that create new changesets or propagate existing changesets into a
5070 repository.
5083 repository.
5071
5084
5072 .. container:: verbose
5085 .. container:: verbose
5073
5086
5074 For example, the following commands are transactional, and their
5087 For example, the following commands are transactional, and their
5075 effects can be rolled back:
5088 effects can be rolled back:
5076
5089
5077 - commit
5090 - commit
5078 - import
5091 - import
5079 - pull
5092 - pull
5080 - push (with this repository as the destination)
5093 - push (with this repository as the destination)
5081 - unbundle
5094 - unbundle
5082
5095
5083 To avoid permanent data loss, rollback will refuse to rollback a
5096 To avoid permanent data loss, rollback will refuse to rollback a
5084 commit transaction if it isn't checked out. Use --force to
5097 commit transaction if it isn't checked out. Use --force to
5085 override this protection.
5098 override this protection.
5086
5099
5087 This command is not intended for use on public repositories. Once
5100 This command is not intended for use on public repositories. Once
5088 changes are visible for pull by other users, rolling a transaction
5101 changes are visible for pull by other users, rolling a transaction
5089 back locally is ineffective (someone else may already have pulled
5102 back locally is ineffective (someone else may already have pulled
5090 the changes). Furthermore, a race is possible with readers of the
5103 the changes). Furthermore, a race is possible with readers of the
5091 repository; for example an in-progress pull from the repository
5104 repository; for example an in-progress pull from the repository
5092 may fail if a rollback is performed.
5105 may fail if a rollback is performed.
5093
5106
5094 Returns 0 on success, 1 if no rollback data is available.
5107 Returns 0 on success, 1 if no rollback data is available.
5095 """
5108 """
5096 return repo.rollback(dryrun=opts.get('dry_run'),
5109 return repo.rollback(dryrun=opts.get('dry_run'),
5097 force=opts.get('force'))
5110 force=opts.get('force'))
5098
5111
5099 @command('root', [])
5112 @command('root', [])
5100 def root(ui, repo):
5113 def root(ui, repo):
5101 """print the root (top) of the current working directory
5114 """print the root (top) of the current working directory
5102
5115
5103 Print the root directory of the current repository.
5116 Print the root directory of the current repository.
5104
5117
5105 Returns 0 on success.
5118 Returns 0 on success.
5106 """
5119 """
5107 ui.write(repo.root + "\n")
5120 ui.write(repo.root + "\n")
5108
5121
5109 @command('^serve',
5122 @command('^serve',
5110 [('A', 'accesslog', '', _('name of access log file to write to'),
5123 [('A', 'accesslog', '', _('name of access log file to write to'),
5111 _('FILE')),
5124 _('FILE')),
5112 ('d', 'daemon', None, _('run server in background')),
5125 ('d', 'daemon', None, _('run server in background')),
5113 ('', 'daemon-pipefds', '', _('used internally by daemon mode'), _('NUM')),
5126 ('', 'daemon-pipefds', '', _('used internally by daemon mode'), _('NUM')),
5114 ('E', 'errorlog', '', _('name of error log file to write to'), _('FILE')),
5127 ('E', 'errorlog', '', _('name of error log file to write to'), _('FILE')),
5115 # use string type, then we can check if something was passed
5128 # use string type, then we can check if something was passed
5116 ('p', 'port', '', _('port to listen on (default: 8000)'), _('PORT')),
5129 ('p', 'port', '', _('port to listen on (default: 8000)'), _('PORT')),
5117 ('a', 'address', '', _('address to listen on (default: all interfaces)'),
5130 ('a', 'address', '', _('address to listen on (default: all interfaces)'),
5118 _('ADDR')),
5131 _('ADDR')),
5119 ('', 'prefix', '', _('prefix path to serve from (default: server root)'),
5132 ('', 'prefix', '', _('prefix path to serve from (default: server root)'),
5120 _('PREFIX')),
5133 _('PREFIX')),
5121 ('n', 'name', '',
5134 ('n', 'name', '',
5122 _('name to show in web pages (default: working directory)'), _('NAME')),
5135 _('name to show in web pages (default: working directory)'), _('NAME')),
5123 ('', 'web-conf', '',
5136 ('', 'web-conf', '',
5124 _('name of the hgweb config file (see "hg help hgweb")'), _('FILE')),
5137 _('name of the hgweb config file (see "hg help hgweb")'), _('FILE')),
5125 ('', 'webdir-conf', '', _('name of the hgweb config file (DEPRECATED)'),
5138 ('', 'webdir-conf', '', _('name of the hgweb config file (DEPRECATED)'),
5126 _('FILE')),
5139 _('FILE')),
5127 ('', 'pid-file', '', _('name of file to write process ID to'), _('FILE')),
5140 ('', 'pid-file', '', _('name of file to write process ID to'), _('FILE')),
5128 ('', 'stdio', None, _('for remote clients')),
5141 ('', 'stdio', None, _('for remote clients')),
5129 ('', 'cmdserver', '', _('for remote clients'), _('MODE')),
5142 ('', 'cmdserver', '', _('for remote clients'), _('MODE')),
5130 ('t', 'templates', '', _('web templates to use'), _('TEMPLATE')),
5143 ('t', 'templates', '', _('web templates to use'), _('TEMPLATE')),
5131 ('', 'style', '', _('template style to use'), _('STYLE')),
5144 ('', 'style', '', _('template style to use'), _('STYLE')),
5132 ('6', 'ipv6', None, _('use IPv6 in addition to IPv4')),
5145 ('6', 'ipv6', None, _('use IPv6 in addition to IPv4')),
5133 ('', 'certificate', '', _('SSL certificate file'), _('FILE'))],
5146 ('', 'certificate', '', _('SSL certificate file'), _('FILE'))],
5134 _('[OPTION]...'))
5147 _('[OPTION]...'))
5135 def serve(ui, repo, **opts):
5148 def serve(ui, repo, **opts):
5136 """start stand-alone webserver
5149 """start stand-alone webserver
5137
5150
5138 Start a local HTTP repository browser and pull server. You can use
5151 Start a local HTTP repository browser and pull server. You can use
5139 this for ad-hoc sharing and browsing of repositories. It is
5152 this for ad-hoc sharing and browsing of repositories. It is
5140 recommended to use a real web server to serve a repository for
5153 recommended to use a real web server to serve a repository for
5141 longer periods of time.
5154 longer periods of time.
5142
5155
5143 Please note that the server does not implement access control.
5156 Please note that the server does not implement access control.
5144 This means that, by default, anybody can read from the server and
5157 This means that, by default, anybody can read from the server and
5145 nobody can write to it by default. Set the ``web.allow_push``
5158 nobody can write to it by default. Set the ``web.allow_push``
5146 option to ``*`` to allow everybody to push to the server. You
5159 option to ``*`` to allow everybody to push to the server. You
5147 should use a real web server if you need to authenticate users.
5160 should use a real web server if you need to authenticate users.
5148
5161
5149 By default, the server logs accesses to stdout and errors to
5162 By default, the server logs accesses to stdout and errors to
5150 stderr. Use the -A/--accesslog and -E/--errorlog options to log to
5163 stderr. Use the -A/--accesslog and -E/--errorlog options to log to
5151 files.
5164 files.
5152
5165
5153 To have the server choose a free port number to listen on, specify
5166 To have the server choose a free port number to listen on, specify
5154 a port number of 0; in this case, the server will print the port
5167 a port number of 0; in this case, the server will print the port
5155 number it uses.
5168 number it uses.
5156
5169
5157 Returns 0 on success.
5170 Returns 0 on success.
5158 """
5171 """
5159
5172
5160 if opts["stdio"] and opts["cmdserver"]:
5173 if opts["stdio"] and opts["cmdserver"]:
5161 raise util.Abort(_("cannot use --stdio with --cmdserver"))
5174 raise util.Abort(_("cannot use --stdio with --cmdserver"))
5162
5175
5163 def checkrepo():
5176 def checkrepo():
5164 if repo is None:
5177 if repo is None:
5165 raise error.RepoError(_("there is no Mercurial repository here"
5178 raise error.RepoError(_("there is no Mercurial repository here"
5166 " (.hg not found)"))
5179 " (.hg not found)"))
5167
5180
5168 if opts["stdio"]:
5181 if opts["stdio"]:
5169 checkrepo()
5182 checkrepo()
5170 s = sshserver.sshserver(ui, repo)
5183 s = sshserver.sshserver(ui, repo)
5171 s.serve_forever()
5184 s.serve_forever()
5172
5185
5173 if opts["cmdserver"]:
5186 if opts["cmdserver"]:
5174 s = commandserver.server(ui, repo, opts["cmdserver"])
5187 s = commandserver.server(ui, repo, opts["cmdserver"])
5175 return s.serve()
5188 return s.serve()
5176
5189
5177 # this way we can check if something was given in the command-line
5190 # this way we can check if something was given in the command-line
5178 if opts.get('port'):
5191 if opts.get('port'):
5179 opts['port'] = util.getport(opts.get('port'))
5192 opts['port'] = util.getport(opts.get('port'))
5180
5193
5181 baseui = repo and repo.baseui or ui
5194 baseui = repo and repo.baseui or ui
5182 optlist = ("name templates style address port prefix ipv6"
5195 optlist = ("name templates style address port prefix ipv6"
5183 " accesslog errorlog certificate encoding")
5196 " accesslog errorlog certificate encoding")
5184 for o in optlist.split():
5197 for o in optlist.split():
5185 val = opts.get(o, '')
5198 val = opts.get(o, '')
5186 if val in (None, ''): # should check against default options instead
5199 if val in (None, ''): # should check against default options instead
5187 continue
5200 continue
5188 baseui.setconfig("web", o, val)
5201 baseui.setconfig("web", o, val)
5189 if repo and repo.ui != baseui:
5202 if repo and repo.ui != baseui:
5190 repo.ui.setconfig("web", o, val)
5203 repo.ui.setconfig("web", o, val)
5191
5204
5192 o = opts.get('web_conf') or opts.get('webdir_conf')
5205 o = opts.get('web_conf') or opts.get('webdir_conf')
5193 if not o:
5206 if not o:
5194 if not repo:
5207 if not repo:
5195 raise error.RepoError(_("there is no Mercurial repository"
5208 raise error.RepoError(_("there is no Mercurial repository"
5196 " here (.hg not found)"))
5209 " here (.hg not found)"))
5197 o = repo
5210 o = repo
5198
5211
5199 app = hgweb.hgweb(o, baseui=baseui)
5212 app = hgweb.hgweb(o, baseui=baseui)
5200 service = httpservice(ui, app, opts)
5213 service = httpservice(ui, app, opts)
5201 cmdutil.service(opts, initfn=service.init, runfn=service.run)
5214 cmdutil.service(opts, initfn=service.init, runfn=service.run)
5202
5215
5203 class httpservice(object):
5216 class httpservice(object):
5204 def __init__(self, ui, app, opts):
5217 def __init__(self, ui, app, opts):
5205 self.ui = ui
5218 self.ui = ui
5206 self.app = app
5219 self.app = app
5207 self.opts = opts
5220 self.opts = opts
5208
5221
5209 def init(self):
5222 def init(self):
5210 util.setsignalhandler()
5223 util.setsignalhandler()
5211 self.httpd = hgweb_server.create_server(self.ui, self.app)
5224 self.httpd = hgweb_server.create_server(self.ui, self.app)
5212
5225
5213 if self.opts['port'] and not self.ui.verbose:
5226 if self.opts['port'] and not self.ui.verbose:
5214 return
5227 return
5215
5228
5216 if self.httpd.prefix:
5229 if self.httpd.prefix:
5217 prefix = self.httpd.prefix.strip('/') + '/'
5230 prefix = self.httpd.prefix.strip('/') + '/'
5218 else:
5231 else:
5219 prefix = ''
5232 prefix = ''
5220
5233
5221 port = ':%d' % self.httpd.port
5234 port = ':%d' % self.httpd.port
5222 if port == ':80':
5235 if port == ':80':
5223 port = ''
5236 port = ''
5224
5237
5225 bindaddr = self.httpd.addr
5238 bindaddr = self.httpd.addr
5226 if bindaddr == '0.0.0.0':
5239 if bindaddr == '0.0.0.0':
5227 bindaddr = '*'
5240 bindaddr = '*'
5228 elif ':' in bindaddr: # IPv6
5241 elif ':' in bindaddr: # IPv6
5229 bindaddr = '[%s]' % bindaddr
5242 bindaddr = '[%s]' % bindaddr
5230
5243
5231 fqaddr = self.httpd.fqaddr
5244 fqaddr = self.httpd.fqaddr
5232 if ':' in fqaddr:
5245 if ':' in fqaddr:
5233 fqaddr = '[%s]' % fqaddr
5246 fqaddr = '[%s]' % fqaddr
5234 if self.opts['port']:
5247 if self.opts['port']:
5235 write = self.ui.status
5248 write = self.ui.status
5236 else:
5249 else:
5237 write = self.ui.write
5250 write = self.ui.write
5238 write(_('listening at http://%s%s/%s (bound to %s:%d)\n') %
5251 write(_('listening at http://%s%s/%s (bound to %s:%d)\n') %
5239 (fqaddr, port, prefix, bindaddr, self.httpd.port))
5252 (fqaddr, port, prefix, bindaddr, self.httpd.port))
5240
5253
5241 def run(self):
5254 def run(self):
5242 self.httpd.serve_forever()
5255 self.httpd.serve_forever()
5243
5256
5244
5257
5245 @command('^status|st',
5258 @command('^status|st',
5246 [('A', 'all', None, _('show status of all files')),
5259 [('A', 'all', None, _('show status of all files')),
5247 ('m', 'modified', None, _('show only modified files')),
5260 ('m', 'modified', None, _('show only modified files')),
5248 ('a', 'added', None, _('show only added files')),
5261 ('a', 'added', None, _('show only added files')),
5249 ('r', 'removed', None, _('show only removed files')),
5262 ('r', 'removed', None, _('show only removed files')),
5250 ('d', 'deleted', None, _('show only deleted (but tracked) files')),
5263 ('d', 'deleted', None, _('show only deleted (but tracked) files')),
5251 ('c', 'clean', None, _('show only files without changes')),
5264 ('c', 'clean', None, _('show only files without changes')),
5252 ('u', 'unknown', None, _('show only unknown (not tracked) files')),
5265 ('u', 'unknown', None, _('show only unknown (not tracked) files')),
5253 ('i', 'ignored', None, _('show only ignored files')),
5266 ('i', 'ignored', None, _('show only ignored files')),
5254 ('n', 'no-status', None, _('hide status prefix')),
5267 ('n', 'no-status', None, _('hide status prefix')),
5255 ('C', 'copies', None, _('show source of copied files')),
5268 ('C', 'copies', None, _('show source of copied files')),
5256 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
5269 ('0', 'print0', None, _('end filenames with NUL, for use with xargs')),
5257 ('', 'rev', [], _('show difference from revision'), _('REV')),
5270 ('', 'rev', [], _('show difference from revision'), _('REV')),
5258 ('', 'change', '', _('list the changed files of a revision'), _('REV')),
5271 ('', 'change', '', _('list the changed files of a revision'), _('REV')),
5259 ] + walkopts + subrepoopts,
5272 ] + walkopts + subrepoopts,
5260 _('[OPTION]... [FILE]...'))
5273 _('[OPTION]... [FILE]...'))
5261 def status(ui, repo, *pats, **opts):
5274 def status(ui, repo, *pats, **opts):
5262 """show changed files in the working directory
5275 """show changed files in the working directory
5263
5276
5264 Show status of files in the repository. If names are given, only
5277 Show status of files in the repository. If names are given, only
5265 files that match are shown. Files that are clean or ignored or
5278 files that match are shown. Files that are clean or ignored or
5266 the source of a copy/move operation, are not listed unless
5279 the source of a copy/move operation, are not listed unless
5267 -c/--clean, -i/--ignored, -C/--copies or -A/--all are given.
5280 -c/--clean, -i/--ignored, -C/--copies or -A/--all are given.
5268 Unless options described with "show only ..." are given, the
5281 Unless options described with "show only ..." are given, the
5269 options -mardu are used.
5282 options -mardu are used.
5270
5283
5271 Option -q/--quiet hides untracked (unknown and ignored) files
5284 Option -q/--quiet hides untracked (unknown and ignored) files
5272 unless explicitly requested with -u/--unknown or -i/--ignored.
5285 unless explicitly requested with -u/--unknown or -i/--ignored.
5273
5286
5274 .. note::
5287 .. note::
5275
5288
5276 status may appear to disagree with diff if permissions have
5289 status may appear to disagree with diff if permissions have
5277 changed or a merge has occurred. The standard diff format does
5290 changed or a merge has occurred. The standard diff format does
5278 not report permission changes and diff only reports changes
5291 not report permission changes and diff only reports changes
5279 relative to one merge parent.
5292 relative to one merge parent.
5280
5293
5281 If one revision is given, it is used as the base revision.
5294 If one revision is given, it is used as the base revision.
5282 If two revisions are given, the differences between them are
5295 If two revisions are given, the differences between them are
5283 shown. The --change option can also be used as a shortcut to list
5296 shown. The --change option can also be used as a shortcut to list
5284 the changed files of a revision from its first parent.
5297 the changed files of a revision from its first parent.
5285
5298
5286 The codes used to show the status of files are::
5299 The codes used to show the status of files are::
5287
5300
5288 M = modified
5301 M = modified
5289 A = added
5302 A = added
5290 R = removed
5303 R = removed
5291 C = clean
5304 C = clean
5292 ! = missing (deleted by non-hg command, but still tracked)
5305 ! = missing (deleted by non-hg command, but still tracked)
5293 ? = not tracked
5306 ? = not tracked
5294 I = ignored
5307 I = ignored
5295 = origin of the previous file (with --copies)
5308 = origin of the previous file (with --copies)
5296
5309
5297 .. container:: verbose
5310 .. container:: verbose
5298
5311
5299 Examples:
5312 Examples:
5300
5313
5301 - show changes in the working directory relative to a
5314 - show changes in the working directory relative to a
5302 changeset::
5315 changeset::
5303
5316
5304 hg status --rev 9353
5317 hg status --rev 9353
5305
5318
5306 - show all changes including copies in an existing changeset::
5319 - show all changes including copies in an existing changeset::
5307
5320
5308 hg status --copies --change 9353
5321 hg status --copies --change 9353
5309
5322
5310 - get a NUL separated list of added files, suitable for xargs::
5323 - get a NUL separated list of added files, suitable for xargs::
5311
5324
5312 hg status -an0
5325 hg status -an0
5313
5326
5314 Returns 0 on success.
5327 Returns 0 on success.
5315 """
5328 """
5316
5329
5317 revs = opts.get('rev')
5330 revs = opts.get('rev')
5318 change = opts.get('change')
5331 change = opts.get('change')
5319
5332
5320 if revs and change:
5333 if revs and change:
5321 msg = _('cannot specify --rev and --change at the same time')
5334 msg = _('cannot specify --rev and --change at the same time')
5322 raise util.Abort(msg)
5335 raise util.Abort(msg)
5323 elif change:
5336 elif change:
5324 node2 = scmutil.revsingle(repo, change, None).node()
5337 node2 = scmutil.revsingle(repo, change, None).node()
5325 node1 = repo[node2].p1().node()
5338 node1 = repo[node2].p1().node()
5326 else:
5339 else:
5327 node1, node2 = scmutil.revpair(repo, revs)
5340 node1, node2 = scmutil.revpair(repo, revs)
5328
5341
5329 cwd = (pats and repo.getcwd()) or ''
5342 cwd = (pats and repo.getcwd()) or ''
5330 end = opts.get('print0') and '\0' or '\n'
5343 end = opts.get('print0') and '\0' or '\n'
5331 copy = {}
5344 copy = {}
5332 states = 'modified added removed deleted unknown ignored clean'.split()
5345 states = 'modified added removed deleted unknown ignored clean'.split()
5333 show = [k for k in states if opts.get(k)]
5346 show = [k for k in states if opts.get(k)]
5334 if opts.get('all'):
5347 if opts.get('all'):
5335 show += ui.quiet and (states[:4] + ['clean']) or states
5348 show += ui.quiet and (states[:4] + ['clean']) or states
5336 if not show:
5349 if not show:
5337 show = ui.quiet and states[:4] or states[:5]
5350 show = ui.quiet and states[:4] or states[:5]
5338
5351
5339 stat = repo.status(node1, node2, scmutil.match(repo[node2], pats, opts),
5352 stat = repo.status(node1, node2, scmutil.match(repo[node2], pats, opts),
5340 'ignored' in show, 'clean' in show, 'unknown' in show,
5353 'ignored' in show, 'clean' in show, 'unknown' in show,
5341 opts.get('subrepos'))
5354 opts.get('subrepos'))
5342 changestates = zip(states, 'MAR!?IC', stat)
5355 changestates = zip(states, 'MAR!?IC', stat)
5343
5356
5344 if (opts.get('all') or opts.get('copies')) and not opts.get('no_status'):
5357 if (opts.get('all') or opts.get('copies')) and not opts.get('no_status'):
5345 copy = copies.pathcopies(repo[node1], repo[node2])
5358 copy = copies.pathcopies(repo[node1], repo[node2])
5346
5359
5347 fm = ui.formatter('status', opts)
5360 fm = ui.formatter('status', opts)
5348 fmt = '%s' + end
5361 fmt = '%s' + end
5349 showchar = not opts.get('no_status')
5362 showchar = not opts.get('no_status')
5350
5363
5351 for state, char, files in changestates:
5364 for state, char, files in changestates:
5352 if state in show:
5365 if state in show:
5353 label = 'status.' + state
5366 label = 'status.' + state
5354 for f in files:
5367 for f in files:
5355 fm.startitem()
5368 fm.startitem()
5356 fm.condwrite(showchar, 'status', '%s ', char, label=label)
5369 fm.condwrite(showchar, 'status', '%s ', char, label=label)
5357 fm.write('path', fmt, repo.pathto(f, cwd), label=label)
5370 fm.write('path', fmt, repo.pathto(f, cwd), label=label)
5358 if f in copy:
5371 if f in copy:
5359 fm.write("copy", ' %s' + end, repo.pathto(copy[f], cwd),
5372 fm.write("copy", ' %s' + end, repo.pathto(copy[f], cwd),
5360 label='status.copied')
5373 label='status.copied')
5361 fm.end()
5374 fm.end()
5362
5375
5363 @command('^summary|sum',
5376 @command('^summary|sum',
5364 [('', 'remote', None, _('check for push and pull'))], '[--remote]')
5377 [('', 'remote', None, _('check for push and pull'))], '[--remote]')
5365 def summary(ui, repo, **opts):
5378 def summary(ui, repo, **opts):
5366 """summarize working directory state
5379 """summarize working directory state
5367
5380
5368 This generates a brief summary of the working directory state,
5381 This generates a brief summary of the working directory state,
5369 including parents, branch, commit status, and available updates.
5382 including parents, branch, commit status, and available updates.
5370
5383
5371 With the --remote option, this will check the default paths for
5384 With the --remote option, this will check the default paths for
5372 incoming and outgoing changes. This can be time-consuming.
5385 incoming and outgoing changes. This can be time-consuming.
5373
5386
5374 Returns 0 on success.
5387 Returns 0 on success.
5375 """
5388 """
5376
5389
5377 ctx = repo[None]
5390 ctx = repo[None]
5378 parents = ctx.parents()
5391 parents = ctx.parents()
5379 pnode = parents[0].node()
5392 pnode = parents[0].node()
5380 marks = []
5393 marks = []
5381
5394
5382 for p in parents:
5395 for p in parents:
5383 # label with log.changeset (instead of log.parent) since this
5396 # label with log.changeset (instead of log.parent) since this
5384 # shows a working directory parent *changeset*:
5397 # shows a working directory parent *changeset*:
5385 # i18n: column positioning for "hg summary"
5398 # i18n: column positioning for "hg summary"
5386 ui.write(_('parent: %d:%s ') % (p.rev(), str(p)),
5399 ui.write(_('parent: %d:%s ') % (p.rev(), str(p)),
5387 label='log.changeset changeset.%s' % p.phasestr())
5400 label='log.changeset changeset.%s' % p.phasestr())
5388 ui.write(' '.join(p.tags()), label='log.tag')
5401 ui.write(' '.join(p.tags()), label='log.tag')
5389 if p.bookmarks():
5402 if p.bookmarks():
5390 marks.extend(p.bookmarks())
5403 marks.extend(p.bookmarks())
5391 if p.rev() == -1:
5404 if p.rev() == -1:
5392 if not len(repo):
5405 if not len(repo):
5393 ui.write(_(' (empty repository)'))
5406 ui.write(_(' (empty repository)'))
5394 else:
5407 else:
5395 ui.write(_(' (no revision checked out)'))
5408 ui.write(_(' (no revision checked out)'))
5396 ui.write('\n')
5409 ui.write('\n')
5397 if p.description():
5410 if p.description():
5398 ui.status(' ' + p.description().splitlines()[0].strip() + '\n',
5411 ui.status(' ' + p.description().splitlines()[0].strip() + '\n',
5399 label='log.summary')
5412 label='log.summary')
5400
5413
5401 branch = ctx.branch()
5414 branch = ctx.branch()
5402 bheads = repo.branchheads(branch)
5415 bheads = repo.branchheads(branch)
5403 # i18n: column positioning for "hg summary"
5416 # i18n: column positioning for "hg summary"
5404 m = _('branch: %s\n') % branch
5417 m = _('branch: %s\n') % branch
5405 if branch != 'default':
5418 if branch != 'default':
5406 ui.write(m, label='log.branch')
5419 ui.write(m, label='log.branch')
5407 else:
5420 else:
5408 ui.status(m, label='log.branch')
5421 ui.status(m, label='log.branch')
5409
5422
5410 if marks:
5423 if marks:
5411 current = repo._bookmarkcurrent
5424 current = repo._bookmarkcurrent
5412 # i18n: column positioning for "hg summary"
5425 # i18n: column positioning for "hg summary"
5413 ui.write(_('bookmarks:'), label='log.bookmark')
5426 ui.write(_('bookmarks:'), label='log.bookmark')
5414 if current is not None:
5427 if current is not None:
5415 if current in marks:
5428 if current in marks:
5416 ui.write(' *' + current, label='bookmarks.current')
5429 ui.write(' *' + current, label='bookmarks.current')
5417 marks.remove(current)
5430 marks.remove(current)
5418 else:
5431 else:
5419 ui.write(' [%s]' % current, label='bookmarks.current')
5432 ui.write(' [%s]' % current, label='bookmarks.current')
5420 for m in marks:
5433 for m in marks:
5421 ui.write(' ' + m, label='log.bookmark')
5434 ui.write(' ' + m, label='log.bookmark')
5422 ui.write('\n', label='log.bookmark')
5435 ui.write('\n', label='log.bookmark')
5423
5436
5424 st = list(repo.status(unknown=True))[:6]
5437 st = list(repo.status(unknown=True))[:6]
5425
5438
5426 c = repo.dirstate.copies()
5439 c = repo.dirstate.copies()
5427 copied, renamed = [], []
5440 copied, renamed = [], []
5428 for d, s in c.iteritems():
5441 for d, s in c.iteritems():
5429 if s in st[2]:
5442 if s in st[2]:
5430 st[2].remove(s)
5443 st[2].remove(s)
5431 renamed.append(d)
5444 renamed.append(d)
5432 else:
5445 else:
5433 copied.append(d)
5446 copied.append(d)
5434 if d in st[1]:
5447 if d in st[1]:
5435 st[1].remove(d)
5448 st[1].remove(d)
5436 st.insert(3, renamed)
5449 st.insert(3, renamed)
5437 st.insert(4, copied)
5450 st.insert(4, copied)
5438
5451
5439 ms = mergemod.mergestate(repo)
5452 ms = mergemod.mergestate(repo)
5440 st.append([f for f in ms if ms[f] == 'u'])
5453 st.append([f for f in ms if ms[f] == 'u'])
5441
5454
5442 subs = [s for s in ctx.substate if ctx.sub(s).dirty()]
5455 subs = [s for s in ctx.substate if ctx.sub(s).dirty()]
5443 st.append(subs)
5456 st.append(subs)
5444
5457
5445 labels = [ui.label(_('%d modified'), 'status.modified'),
5458 labels = [ui.label(_('%d modified'), 'status.modified'),
5446 ui.label(_('%d added'), 'status.added'),
5459 ui.label(_('%d added'), 'status.added'),
5447 ui.label(_('%d removed'), 'status.removed'),
5460 ui.label(_('%d removed'), 'status.removed'),
5448 ui.label(_('%d renamed'), 'status.copied'),
5461 ui.label(_('%d renamed'), 'status.copied'),
5449 ui.label(_('%d copied'), 'status.copied'),
5462 ui.label(_('%d copied'), 'status.copied'),
5450 ui.label(_('%d deleted'), 'status.deleted'),
5463 ui.label(_('%d deleted'), 'status.deleted'),
5451 ui.label(_('%d unknown'), 'status.unknown'),
5464 ui.label(_('%d unknown'), 'status.unknown'),
5452 ui.label(_('%d ignored'), 'status.ignored'),
5465 ui.label(_('%d ignored'), 'status.ignored'),
5453 ui.label(_('%d unresolved'), 'resolve.unresolved'),
5466 ui.label(_('%d unresolved'), 'resolve.unresolved'),
5454 ui.label(_('%d subrepos'), 'status.modified')]
5467 ui.label(_('%d subrepos'), 'status.modified')]
5455 t = []
5468 t = []
5456 for s, l in zip(st, labels):
5469 for s, l in zip(st, labels):
5457 if s:
5470 if s:
5458 t.append(l % len(s))
5471 t.append(l % len(s))
5459
5472
5460 t = ', '.join(t)
5473 t = ', '.join(t)
5461 cleanworkdir = False
5474 cleanworkdir = False
5462
5475
5463 if repo.vfs.exists('updatestate'):
5476 if repo.vfs.exists('updatestate'):
5464 t += _(' (interrupted update)')
5477 t += _(' (interrupted update)')
5465 elif len(parents) > 1:
5478 elif len(parents) > 1:
5466 t += _(' (merge)')
5479 t += _(' (merge)')
5467 elif branch != parents[0].branch():
5480 elif branch != parents[0].branch():
5468 t += _(' (new branch)')
5481 t += _(' (new branch)')
5469 elif (parents[0].closesbranch() and
5482 elif (parents[0].closesbranch() and
5470 pnode in repo.branchheads(branch, closed=True)):
5483 pnode in repo.branchheads(branch, closed=True)):
5471 t += _(' (head closed)')
5484 t += _(' (head closed)')
5472 elif not (st[0] or st[1] or st[2] or st[3] or st[4] or st[9]):
5485 elif not (st[0] or st[1] or st[2] or st[3] or st[4] or st[9]):
5473 t += _(' (clean)')
5486 t += _(' (clean)')
5474 cleanworkdir = True
5487 cleanworkdir = True
5475 elif pnode not in bheads:
5488 elif pnode not in bheads:
5476 t += _(' (new branch head)')
5489 t += _(' (new branch head)')
5477
5490
5478 if cleanworkdir:
5491 if cleanworkdir:
5479 # i18n: column positioning for "hg summary"
5492 # i18n: column positioning for "hg summary"
5480 ui.status(_('commit: %s\n') % t.strip())
5493 ui.status(_('commit: %s\n') % t.strip())
5481 else:
5494 else:
5482 # i18n: column positioning for "hg summary"
5495 # i18n: column positioning for "hg summary"
5483 ui.write(_('commit: %s\n') % t.strip())
5496 ui.write(_('commit: %s\n') % t.strip())
5484
5497
5485 # all ancestors of branch heads - all ancestors of parent = new csets
5498 # all ancestors of branch heads - all ancestors of parent = new csets
5486 new = len(repo.changelog.findmissing([ctx.node() for ctx in parents],
5499 new = len(repo.changelog.findmissing([ctx.node() for ctx in parents],
5487 bheads))
5500 bheads))
5488
5501
5489 if new == 0:
5502 if new == 0:
5490 # i18n: column positioning for "hg summary"
5503 # i18n: column positioning for "hg summary"
5491 ui.status(_('update: (current)\n'))
5504 ui.status(_('update: (current)\n'))
5492 elif pnode not in bheads:
5505 elif pnode not in bheads:
5493 # i18n: column positioning for "hg summary"
5506 # i18n: column positioning for "hg summary"
5494 ui.write(_('update: %d new changesets (update)\n') % new)
5507 ui.write(_('update: %d new changesets (update)\n') % new)
5495 else:
5508 else:
5496 # i18n: column positioning for "hg summary"
5509 # i18n: column positioning for "hg summary"
5497 ui.write(_('update: %d new changesets, %d branch heads (merge)\n') %
5510 ui.write(_('update: %d new changesets, %d branch heads (merge)\n') %
5498 (new, len(bheads)))
5511 (new, len(bheads)))
5499
5512
5500 cmdutil.summaryhooks(ui, repo)
5513 cmdutil.summaryhooks(ui, repo)
5501
5514
5502 if opts.get('remote'):
5515 if opts.get('remote'):
5503 t = []
5516 t = []
5504 source, branches = hg.parseurl(ui.expandpath('default'))
5517 source, branches = hg.parseurl(ui.expandpath('default'))
5505 sbranch = branches[0]
5518 sbranch = branches[0]
5506 other = hg.peer(repo, {}, source)
5519 other = hg.peer(repo, {}, source)
5507 revs, checkout = hg.addbranchrevs(repo, other, branches, None)
5520 revs, checkout = hg.addbranchrevs(repo, other, branches, None)
5508 if revs:
5521 if revs:
5509 revs = [other.lookup(rev) for rev in revs]
5522 revs = [other.lookup(rev) for rev in revs]
5510 ui.debug('comparing with %s\n' % util.hidepassword(source))
5523 ui.debug('comparing with %s\n' % util.hidepassword(source))
5511 repo.ui.pushbuffer()
5524 repo.ui.pushbuffer()
5512 commoninc = discovery.findcommonincoming(repo, other, heads=revs)
5525 commoninc = discovery.findcommonincoming(repo, other, heads=revs)
5513 _common, incoming, _rheads = commoninc
5526 _common, incoming, _rheads = commoninc
5514 repo.ui.popbuffer()
5527 repo.ui.popbuffer()
5515 if incoming:
5528 if incoming:
5516 t.append(_('1 or more incoming'))
5529 t.append(_('1 or more incoming'))
5517
5530
5518 dest, branches = hg.parseurl(ui.expandpath('default-push', 'default'))
5531 dest, branches = hg.parseurl(ui.expandpath('default-push', 'default'))
5519 dbranch = branches[0]
5532 dbranch = branches[0]
5520 revs, checkout = hg.addbranchrevs(repo, repo, branches, None)
5533 revs, checkout = hg.addbranchrevs(repo, repo, branches, None)
5521 if source != dest:
5534 if source != dest:
5522 other = hg.peer(repo, {}, dest)
5535 other = hg.peer(repo, {}, dest)
5523 ui.debug('comparing with %s\n' % util.hidepassword(dest))
5536 ui.debug('comparing with %s\n' % util.hidepassword(dest))
5524 if (source != dest or (sbranch is not None and sbranch != dbranch)):
5537 if (source != dest or (sbranch is not None and sbranch != dbranch)):
5525 commoninc = None
5538 commoninc = None
5526 if revs:
5539 if revs:
5527 revs = [repo.lookup(rev) for rev in revs]
5540 revs = [repo.lookup(rev) for rev in revs]
5528 repo.ui.pushbuffer()
5541 repo.ui.pushbuffer()
5529 outgoing = discovery.findcommonoutgoing(repo, other, onlyheads=revs,
5542 outgoing = discovery.findcommonoutgoing(repo, other, onlyheads=revs,
5530 commoninc=commoninc)
5543 commoninc=commoninc)
5531 repo.ui.popbuffer()
5544 repo.ui.popbuffer()
5532 o = outgoing.missing
5545 o = outgoing.missing
5533 if o:
5546 if o:
5534 t.append(_('%d outgoing') % len(o))
5547 t.append(_('%d outgoing') % len(o))
5535 if 'bookmarks' in other.listkeys('namespaces'):
5548 if 'bookmarks' in other.listkeys('namespaces'):
5536 lmarks = repo.listkeys('bookmarks')
5549 lmarks = repo.listkeys('bookmarks')
5537 rmarks = other.listkeys('bookmarks')
5550 rmarks = other.listkeys('bookmarks')
5538 diff = set(rmarks) - set(lmarks)
5551 diff = set(rmarks) - set(lmarks)
5539 if len(diff) > 0:
5552 if len(diff) > 0:
5540 t.append(_('%d incoming bookmarks') % len(diff))
5553 t.append(_('%d incoming bookmarks') % len(diff))
5541 diff = set(lmarks) - set(rmarks)
5554 diff = set(lmarks) - set(rmarks)
5542 if len(diff) > 0:
5555 if len(diff) > 0:
5543 t.append(_('%d outgoing bookmarks') % len(diff))
5556 t.append(_('%d outgoing bookmarks') % len(diff))
5544
5557
5545 if t:
5558 if t:
5546 # i18n: column positioning for "hg summary"
5559 # i18n: column positioning for "hg summary"
5547 ui.write(_('remote: %s\n') % (', '.join(t)))
5560 ui.write(_('remote: %s\n') % (', '.join(t)))
5548 else:
5561 else:
5549 # i18n: column positioning for "hg summary"
5562 # i18n: column positioning for "hg summary"
5550 ui.status(_('remote: (synced)\n'))
5563 ui.status(_('remote: (synced)\n'))
5551
5564
5552 @command('tag',
5565 @command('tag',
5553 [('f', 'force', None, _('force tag')),
5566 [('f', 'force', None, _('force tag')),
5554 ('l', 'local', None, _('make the tag local')),
5567 ('l', 'local', None, _('make the tag local')),
5555 ('r', 'rev', '', _('revision to tag'), _('REV')),
5568 ('r', 'rev', '', _('revision to tag'), _('REV')),
5556 ('', 'remove', None, _('remove a tag')),
5569 ('', 'remove', None, _('remove a tag')),
5557 # -l/--local is already there, commitopts cannot be used
5570 # -l/--local is already there, commitopts cannot be used
5558 ('e', 'edit', None, _('edit commit message')),
5571 ('e', 'edit', None, _('edit commit message')),
5559 ('m', 'message', '', _('use <text> as commit message'), _('TEXT')),
5572 ('m', 'message', '', _('use <text> as commit message'), _('TEXT')),
5560 ] + commitopts2,
5573 ] + commitopts2,
5561 _('[-f] [-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME...'))
5574 _('[-f] [-l] [-m TEXT] [-d DATE] [-u USER] [-r REV] NAME...'))
5562 def tag(ui, repo, name1, *names, **opts):
5575 def tag(ui, repo, name1, *names, **opts):
5563 """add one or more tags for the current or given revision
5576 """add one or more tags for the current or given revision
5564
5577
5565 Name a particular revision using <name>.
5578 Name a particular revision using <name>.
5566
5579
5567 Tags are used to name particular revisions of the repository and are
5580 Tags are used to name particular revisions of the repository and are
5568 very useful to compare different revisions, to go back to significant
5581 very useful to compare different revisions, to go back to significant
5569 earlier versions or to mark branch points as releases, etc. Changing
5582 earlier versions or to mark branch points as releases, etc. Changing
5570 an existing tag is normally disallowed; use -f/--force to override.
5583 an existing tag is normally disallowed; use -f/--force to override.
5571
5584
5572 If no revision is given, the parent of the working directory is
5585 If no revision is given, the parent of the working directory is
5573 used.
5586 used.
5574
5587
5575 To facilitate version control, distribution, and merging of tags,
5588 To facilitate version control, distribution, and merging of tags,
5576 they are stored as a file named ".hgtags" which is managed similarly
5589 they are stored as a file named ".hgtags" which is managed similarly
5577 to other project files and can be hand-edited if necessary. This
5590 to other project files and can be hand-edited if necessary. This
5578 also means that tagging creates a new commit. The file
5591 also means that tagging creates a new commit. The file
5579 ".hg/localtags" is used for local tags (not shared among
5592 ".hg/localtags" is used for local tags (not shared among
5580 repositories).
5593 repositories).
5581
5594
5582 Tag commits are usually made at the head of a branch. If the parent
5595 Tag commits are usually made at the head of a branch. If the parent
5583 of the working directory is not a branch head, :hg:`tag` aborts; use
5596 of the working directory is not a branch head, :hg:`tag` aborts; use
5584 -f/--force to force the tag commit to be based on a non-head
5597 -f/--force to force the tag commit to be based on a non-head
5585 changeset.
5598 changeset.
5586
5599
5587 See :hg:`help dates` for a list of formats valid for -d/--date.
5600 See :hg:`help dates` for a list of formats valid for -d/--date.
5588
5601
5589 Since tag names have priority over branch names during revision
5602 Since tag names have priority over branch names during revision
5590 lookup, using an existing branch name as a tag name is discouraged.
5603 lookup, using an existing branch name as a tag name is discouraged.
5591
5604
5592 Returns 0 on success.
5605 Returns 0 on success.
5593 """
5606 """
5594 wlock = lock = None
5607 wlock = lock = None
5595 try:
5608 try:
5596 wlock = repo.wlock()
5609 wlock = repo.wlock()
5597 lock = repo.lock()
5610 lock = repo.lock()
5598 rev_ = "."
5611 rev_ = "."
5599 names = [t.strip() for t in (name1,) + names]
5612 names = [t.strip() for t in (name1,) + names]
5600 if len(names) != len(set(names)):
5613 if len(names) != len(set(names)):
5601 raise util.Abort(_('tag names must be unique'))
5614 raise util.Abort(_('tag names must be unique'))
5602 for n in names:
5615 for n in names:
5603 scmutil.checknewlabel(repo, n, 'tag')
5616 scmutil.checknewlabel(repo, n, 'tag')
5604 if not n:
5617 if not n:
5605 raise util.Abort(_('tag names cannot consist entirely of '
5618 raise util.Abort(_('tag names cannot consist entirely of '
5606 'whitespace'))
5619 'whitespace'))
5607 if opts.get('rev') and opts.get('remove'):
5620 if opts.get('rev') and opts.get('remove'):
5608 raise util.Abort(_("--rev and --remove are incompatible"))
5621 raise util.Abort(_("--rev and --remove are incompatible"))
5609 if opts.get('rev'):
5622 if opts.get('rev'):
5610 rev_ = opts['rev']
5623 rev_ = opts['rev']
5611 message = opts.get('message')
5624 message = opts.get('message')
5612 if opts.get('remove'):
5625 if opts.get('remove'):
5613 expectedtype = opts.get('local') and 'local' or 'global'
5626 expectedtype = opts.get('local') and 'local' or 'global'
5614 for n in names:
5627 for n in names:
5615 if not repo.tagtype(n):
5628 if not repo.tagtype(n):
5616 raise util.Abort(_("tag '%s' does not exist") % n)
5629 raise util.Abort(_("tag '%s' does not exist") % n)
5617 if repo.tagtype(n) != expectedtype:
5630 if repo.tagtype(n) != expectedtype:
5618 if expectedtype == 'global':
5631 if expectedtype == 'global':
5619 raise util.Abort(_("tag '%s' is not a global tag") % n)
5632 raise util.Abort(_("tag '%s' is not a global tag") % n)
5620 else:
5633 else:
5621 raise util.Abort(_("tag '%s' is not a local tag") % n)
5634 raise util.Abort(_("tag '%s' is not a local tag") % n)
5622 rev_ = nullid
5635 rev_ = nullid
5623 if not message:
5636 if not message:
5624 # we don't translate commit messages
5637 # we don't translate commit messages
5625 message = 'Removed tag %s' % ', '.join(names)
5638 message = 'Removed tag %s' % ', '.join(names)
5626 elif not opts.get('force'):
5639 elif not opts.get('force'):
5627 for n in names:
5640 for n in names:
5628 if n in repo.tags():
5641 if n in repo.tags():
5629 raise util.Abort(_("tag '%s' already exists "
5642 raise util.Abort(_("tag '%s' already exists "
5630 "(use -f to force)") % n)
5643 "(use -f to force)") % n)
5631 if not opts.get('local'):
5644 if not opts.get('local'):
5632 p1, p2 = repo.dirstate.parents()
5645 p1, p2 = repo.dirstate.parents()
5633 if p2 != nullid:
5646 if p2 != nullid:
5634 raise util.Abort(_('uncommitted merge'))
5647 raise util.Abort(_('uncommitted merge'))
5635 bheads = repo.branchheads()
5648 bheads = repo.branchheads()
5636 if not opts.get('force') and bheads and p1 not in bheads:
5649 if not opts.get('force') and bheads and p1 not in bheads:
5637 raise util.Abort(_('not at a branch head (use -f to force)'))
5650 raise util.Abort(_('not at a branch head (use -f to force)'))
5638 r = scmutil.revsingle(repo, rev_).node()
5651 r = scmutil.revsingle(repo, rev_).node()
5639
5652
5640 if not message:
5653 if not message:
5641 # we don't translate commit messages
5654 # we don't translate commit messages
5642 message = ('Added tag %s for changeset %s' %
5655 message = ('Added tag %s for changeset %s' %
5643 (', '.join(names), short(r)))
5656 (', '.join(names), short(r)))
5644
5657
5645 date = opts.get('date')
5658 date = opts.get('date')
5646 if date:
5659 if date:
5647 date = util.parsedate(date)
5660 date = util.parsedate(date)
5648
5661
5649 if opts.get('edit'):
5662 if opts.get('edit'):
5650 message = ui.edit(message, ui.username())
5663 message = ui.edit(message, ui.username())
5651 repo.savecommitmessage(message)
5664 repo.savecommitmessage(message)
5652
5665
5653 # don't allow tagging the null rev
5666 # don't allow tagging the null rev
5654 if (not opts.get('remove') and
5667 if (not opts.get('remove') and
5655 scmutil.revsingle(repo, rev_).rev() == nullrev):
5668 scmutil.revsingle(repo, rev_).rev() == nullrev):
5656 raise util.Abort(_("cannot tag null revision"))
5669 raise util.Abort(_("cannot tag null revision"))
5657
5670
5658 repo.tag(names, r, message, opts.get('local'), opts.get('user'), date)
5671 repo.tag(names, r, message, opts.get('local'), opts.get('user'), date)
5659 finally:
5672 finally:
5660 release(lock, wlock)
5673 release(lock, wlock)
5661
5674
5662 @command('tags', [], '')
5675 @command('tags', [], '')
5663 def tags(ui, repo, **opts):
5676 def tags(ui, repo, **opts):
5664 """list repository tags
5677 """list repository tags
5665
5678
5666 This lists both regular and local tags. When the -v/--verbose
5679 This lists both regular and local tags. When the -v/--verbose
5667 switch is used, a third column "local" is printed for local tags.
5680 switch is used, a third column "local" is printed for local tags.
5668
5681
5669 Returns 0 on success.
5682 Returns 0 on success.
5670 """
5683 """
5671
5684
5672 fm = ui.formatter('tags', opts)
5685 fm = ui.formatter('tags', opts)
5673 hexfunc = ui.debugflag and hex or short
5686 hexfunc = ui.debugflag and hex or short
5674 tagtype = ""
5687 tagtype = ""
5675
5688
5676 for t, n in reversed(repo.tagslist()):
5689 for t, n in reversed(repo.tagslist()):
5677 hn = hexfunc(n)
5690 hn = hexfunc(n)
5678 label = 'tags.normal'
5691 label = 'tags.normal'
5679 tagtype = ''
5692 tagtype = ''
5680 if repo.tagtype(t) == 'local':
5693 if repo.tagtype(t) == 'local':
5681 label = 'tags.local'
5694 label = 'tags.local'
5682 tagtype = 'local'
5695 tagtype = 'local'
5683
5696
5684 fm.startitem()
5697 fm.startitem()
5685 fm.write('tag', '%s', t, label=label)
5698 fm.write('tag', '%s', t, label=label)
5686 fmt = " " * (30 - encoding.colwidth(t)) + ' %5d:%s'
5699 fmt = " " * (30 - encoding.colwidth(t)) + ' %5d:%s'
5687 fm.condwrite(not ui.quiet, 'rev id', fmt,
5700 fm.condwrite(not ui.quiet, 'rev id', fmt,
5688 repo.changelog.rev(n), hn, label=label)
5701 repo.changelog.rev(n), hn, label=label)
5689 fm.condwrite(ui.verbose and tagtype, 'type', ' %s',
5702 fm.condwrite(ui.verbose and tagtype, 'type', ' %s',
5690 tagtype, label=label)
5703 tagtype, label=label)
5691 fm.plain('\n')
5704 fm.plain('\n')
5692 fm.end()
5705 fm.end()
5693
5706
5694 @command('tip',
5707 @command('tip',
5695 [('p', 'patch', None, _('show patch')),
5708 [('p', 'patch', None, _('show patch')),
5696 ('g', 'git', None, _('use git extended diff format')),
5709 ('g', 'git', None, _('use git extended diff format')),
5697 ] + templateopts,
5710 ] + templateopts,
5698 _('[-p] [-g]'))
5711 _('[-p] [-g]'))
5699 def tip(ui, repo, **opts):
5712 def tip(ui, repo, **opts):
5700 """show the tip revision (DEPRECATED)
5713 """show the tip revision (DEPRECATED)
5701
5714
5702 The tip revision (usually just called the tip) is the changeset
5715 The tip revision (usually just called the tip) is the changeset
5703 most recently added to the repository (and therefore the most
5716 most recently added to the repository (and therefore the most
5704 recently changed head).
5717 recently changed head).
5705
5718
5706 If you have just made a commit, that commit will be the tip. If
5719 If you have just made a commit, that commit will be the tip. If
5707 you have just pulled changes from another repository, the tip of
5720 you have just pulled changes from another repository, the tip of
5708 that repository becomes the current tip. The "tip" tag is special
5721 that repository becomes the current tip. The "tip" tag is special
5709 and cannot be renamed or assigned to a different changeset.
5722 and cannot be renamed or assigned to a different changeset.
5710
5723
5711 This command is deprecated, please use :hg:`heads` instead.
5724 This command is deprecated, please use :hg:`heads` instead.
5712
5725
5713 Returns 0 on success.
5726 Returns 0 on success.
5714 """
5727 """
5715 displayer = cmdutil.show_changeset(ui, repo, opts)
5728 displayer = cmdutil.show_changeset(ui, repo, opts)
5716 displayer.show(repo['tip'])
5729 displayer.show(repo['tip'])
5717 displayer.close()
5730 displayer.close()
5718
5731
5719 @command('unbundle',
5732 @command('unbundle',
5720 [('u', 'update', None,
5733 [('u', 'update', None,
5721 _('update to new branch head if changesets were unbundled'))],
5734 _('update to new branch head if changesets were unbundled'))],
5722 _('[-u] FILE...'))
5735 _('[-u] FILE...'))
5723 def unbundle(ui, repo, fname1, *fnames, **opts):
5736 def unbundle(ui, repo, fname1, *fnames, **opts):
5724 """apply one or more changegroup files
5737 """apply one or more changegroup files
5725
5738
5726 Apply one or more compressed changegroup files generated by the
5739 Apply one or more compressed changegroup files generated by the
5727 bundle command.
5740 bundle command.
5728
5741
5729 Returns 0 on success, 1 if an update has unresolved files.
5742 Returns 0 on success, 1 if an update has unresolved files.
5730 """
5743 """
5731 fnames = (fname1,) + fnames
5744 fnames = (fname1,) + fnames
5732
5745
5733 lock = repo.lock()
5746 lock = repo.lock()
5734 wc = repo['.']
5747 wc = repo['.']
5735 try:
5748 try:
5736 for fname in fnames:
5749 for fname in fnames:
5737 f = hg.openpath(ui, fname)
5750 f = hg.openpath(ui, fname)
5738 gen = changegroup.readbundle(f, fname)
5751 gen = changegroup.readbundle(f, fname)
5739 modheads = repo.addchangegroup(gen, 'unbundle', 'bundle:' + fname)
5752 modheads = repo.addchangegroup(gen, 'unbundle', 'bundle:' + fname)
5740 finally:
5753 finally:
5741 lock.release()
5754 lock.release()
5742 bookmarks.updatecurrentbookmark(repo, wc.node(), wc.branch())
5755 bookmarks.updatecurrentbookmark(repo, wc.node(), wc.branch())
5743 return postincoming(ui, repo, modheads, opts.get('update'), None)
5756 return postincoming(ui, repo, modheads, opts.get('update'), None)
5744
5757
5745 @command('^update|up|checkout|co',
5758 @command('^update|up|checkout|co',
5746 [('C', 'clean', None, _('discard uncommitted changes (no backup)')),
5759 [('C', 'clean', None, _('discard uncommitted changes (no backup)')),
5747 ('c', 'check', None,
5760 ('c', 'check', None,
5748 _('update across branches if no uncommitted changes')),
5761 _('update across branches if no uncommitted changes')),
5749 ('d', 'date', '', _('tipmost revision matching date'), _('DATE')),
5762 ('d', 'date', '', _('tipmost revision matching date'), _('DATE')),
5750 ('r', 'rev', '', _('revision'), _('REV'))],
5763 ('r', 'rev', '', _('revision'), _('REV'))],
5751 _('[-c] [-C] [-d DATE] [[-r] REV]'))
5764 _('[-c] [-C] [-d DATE] [[-r] REV]'))
5752 def update(ui, repo, node=None, rev=None, clean=False, date=None, check=False):
5765 def update(ui, repo, node=None, rev=None, clean=False, date=None, check=False):
5753 """update working directory (or switch revisions)
5766 """update working directory (or switch revisions)
5754
5767
5755 Update the repository's working directory to the specified
5768 Update the repository's working directory to the specified
5756 changeset. If no changeset is specified, update to the tip of the
5769 changeset. If no changeset is specified, update to the tip of the
5757 current named branch and move the current bookmark (see :hg:`help
5770 current named branch and move the current bookmark (see :hg:`help
5758 bookmarks`).
5771 bookmarks`).
5759
5772
5760 Update sets the working directory's parent revision to the specified
5773 Update sets the working directory's parent revision to the specified
5761 changeset (see :hg:`help parents`).
5774 changeset (see :hg:`help parents`).
5762
5775
5763 If the changeset is not a descendant or ancestor of the working
5776 If the changeset is not a descendant or ancestor of the working
5764 directory's parent, the update is aborted. With the -c/--check
5777 directory's parent, the update is aborted. With the -c/--check
5765 option, the working directory is checked for uncommitted changes; if
5778 option, the working directory is checked for uncommitted changes; if
5766 none are found, the working directory is updated to the specified
5779 none are found, the working directory is updated to the specified
5767 changeset.
5780 changeset.
5768
5781
5769 .. container:: verbose
5782 .. container:: verbose
5770
5783
5771 The following rules apply when the working directory contains
5784 The following rules apply when the working directory contains
5772 uncommitted changes:
5785 uncommitted changes:
5773
5786
5774 1. If neither -c/--check nor -C/--clean is specified, and if
5787 1. If neither -c/--check nor -C/--clean is specified, and if
5775 the requested changeset is an ancestor or descendant of
5788 the requested changeset is an ancestor or descendant of
5776 the working directory's parent, the uncommitted changes
5789 the working directory's parent, the uncommitted changes
5777 are merged into the requested changeset and the merged
5790 are merged into the requested changeset and the merged
5778 result is left uncommitted. If the requested changeset is
5791 result is left uncommitted. If the requested changeset is
5779 not an ancestor or descendant (that is, it is on another
5792 not an ancestor or descendant (that is, it is on another
5780 branch), the update is aborted and the uncommitted changes
5793 branch), the update is aborted and the uncommitted changes
5781 are preserved.
5794 are preserved.
5782
5795
5783 2. With the -c/--check option, the update is aborted and the
5796 2. With the -c/--check option, the update is aborted and the
5784 uncommitted changes are preserved.
5797 uncommitted changes are preserved.
5785
5798
5786 3. With the -C/--clean option, uncommitted changes are discarded and
5799 3. With the -C/--clean option, uncommitted changes are discarded and
5787 the working directory is updated to the requested changeset.
5800 the working directory is updated to the requested changeset.
5788
5801
5789 To cancel an uncommitted merge (and lose your changes), use
5802 To cancel an uncommitted merge (and lose your changes), use
5790 :hg:`update --clean .`.
5803 :hg:`update --clean .`.
5791
5804
5792 Use null as the changeset to remove the working directory (like
5805 Use null as the changeset to remove the working directory (like
5793 :hg:`clone -U`).
5806 :hg:`clone -U`).
5794
5807
5795 If you want to revert just one file to an older revision, use
5808 If you want to revert just one file to an older revision, use
5796 :hg:`revert [-r REV] NAME`.
5809 :hg:`revert [-r REV] NAME`.
5797
5810
5798 See :hg:`help dates` for a list of formats valid for -d/--date.
5811 See :hg:`help dates` for a list of formats valid for -d/--date.
5799
5812
5800 Returns 0 on success, 1 if there are unresolved files.
5813 Returns 0 on success, 1 if there are unresolved files.
5801 """
5814 """
5802 if rev and node:
5815 if rev and node:
5803 raise util.Abort(_("please specify just one revision"))
5816 raise util.Abort(_("please specify just one revision"))
5804
5817
5805 if rev is None or rev == '':
5818 if rev is None or rev == '':
5806 rev = node
5819 rev = node
5807
5820
5808 cmdutil.clearunfinished(repo)
5821 cmdutil.clearunfinished(repo)
5809
5822
5810 # with no argument, we also move the current bookmark, if any
5823 # with no argument, we also move the current bookmark, if any
5811 rev, movemarkfrom = bookmarks.calculateupdate(ui, repo, rev)
5824 rev, movemarkfrom = bookmarks.calculateupdate(ui, repo, rev)
5812
5825
5813 # if we defined a bookmark, we have to remember the original bookmark name
5826 # if we defined a bookmark, we have to remember the original bookmark name
5814 brev = rev
5827 brev = rev
5815 rev = scmutil.revsingle(repo, rev, rev).rev()
5828 rev = scmutil.revsingle(repo, rev, rev).rev()
5816
5829
5817 if check and clean:
5830 if check and clean:
5818 raise util.Abort(_("cannot specify both -c/--check and -C/--clean"))
5831 raise util.Abort(_("cannot specify both -c/--check and -C/--clean"))
5819
5832
5820 if date:
5833 if date:
5821 if rev is not None:
5834 if rev is not None:
5822 raise util.Abort(_("you can't specify a revision and a date"))
5835 raise util.Abort(_("you can't specify a revision and a date"))
5823 rev = cmdutil.finddate(ui, repo, date)
5836 rev = cmdutil.finddate(ui, repo, date)
5824
5837
5825 if check:
5838 if check:
5826 c = repo[None]
5839 c = repo[None]
5827 if c.dirty(merge=False, branch=False, missing=True):
5840 if c.dirty(merge=False, branch=False, missing=True):
5828 raise util.Abort(_("uncommitted changes"))
5841 raise util.Abort(_("uncommitted changes"))
5829 if rev is None:
5842 if rev is None:
5830 rev = repo[repo[None].branch()].rev()
5843 rev = repo[repo[None].branch()].rev()
5831 mergemod._checkunknown(repo, repo[None], repo[rev])
5844 mergemod._checkunknown(repo, repo[None], repo[rev])
5832
5845
5833 if clean:
5846 if clean:
5834 ret = hg.clean(repo, rev)
5847 ret = hg.clean(repo, rev)
5835 else:
5848 else:
5836 ret = hg.update(repo, rev)
5849 ret = hg.update(repo, rev)
5837
5850
5838 if not ret and movemarkfrom:
5851 if not ret and movemarkfrom:
5839 if bookmarks.update(repo, [movemarkfrom], repo['.'].node()):
5852 if bookmarks.update(repo, [movemarkfrom], repo['.'].node()):
5840 ui.status(_("updating bookmark %s\n") % repo._bookmarkcurrent)
5853 ui.status(_("updating bookmark %s\n") % repo._bookmarkcurrent)
5841 elif brev in repo._bookmarks:
5854 elif brev in repo._bookmarks:
5842 bookmarks.setcurrent(repo, brev)
5855 bookmarks.setcurrent(repo, brev)
5843 elif brev:
5856 elif brev:
5844 bookmarks.unsetcurrent(repo)
5857 bookmarks.unsetcurrent(repo)
5845
5858
5846 return ret
5859 return ret
5847
5860
5848 @command('verify', [])
5861 @command('verify', [])
5849 def verify(ui, repo):
5862 def verify(ui, repo):
5850 """verify the integrity of the repository
5863 """verify the integrity of the repository
5851
5864
5852 Verify the integrity of the current repository.
5865 Verify the integrity of the current repository.
5853
5866
5854 This will perform an extensive check of the repository's
5867 This will perform an extensive check of the repository's
5855 integrity, validating the hashes and checksums of each entry in
5868 integrity, validating the hashes and checksums of each entry in
5856 the changelog, manifest, and tracked files, as well as the
5869 the changelog, manifest, and tracked files, as well as the
5857 integrity of their crosslinks and indices.
5870 integrity of their crosslinks and indices.
5858
5871
5859 Please see http://mercurial.selenic.com/wiki/RepositoryCorruption
5872 Please see http://mercurial.selenic.com/wiki/RepositoryCorruption
5860 for more information about recovery from corruption of the
5873 for more information about recovery from corruption of the
5861 repository.
5874 repository.
5862
5875
5863 Returns 0 on success, 1 if errors are encountered.
5876 Returns 0 on success, 1 if errors are encountered.
5864 """
5877 """
5865 return hg.verify(repo)
5878 return hg.verify(repo)
5866
5879
5867 @command('version', [])
5880 @command('version', [])
5868 def version_(ui):
5881 def version_(ui):
5869 """output version and copyright information"""
5882 """output version and copyright information"""
5870 ui.write(_("Mercurial Distributed SCM (version %s)\n")
5883 ui.write(_("Mercurial Distributed SCM (version %s)\n")
5871 % util.version())
5884 % util.version())
5872 ui.status(_(
5885 ui.status(_(
5873 "(see http://mercurial.selenic.com for more information)\n"
5886 "(see http://mercurial.selenic.com for more information)\n"
5874 "\nCopyright (C) 2005-2014 Matt Mackall and others\n"
5887 "\nCopyright (C) 2005-2014 Matt Mackall and others\n"
5875 "This is free software; see the source for copying conditions. "
5888 "This is free software; see the source for copying conditions. "
5876 "There is NO\nwarranty; "
5889 "There is NO\nwarranty; "
5877 "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
5890 "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
5878 ))
5891 ))
5879
5892
5880 norepo = ("clone init version help debugcommands debugcomplete"
5893 norepo = ("clone init version help debugcommands debugcomplete"
5881 " debugdate debuginstall debugfsinfo debugpushkey debugwireargs"
5894 " debugdate debuginstall debugfsinfo debugpushkey debugwireargs"
5882 " debugknown debuggetbundle debugbundle")
5895 " debugknown debuggetbundle debugbundle")
5883 optionalrepo = ("identify paths serve config showconfig debugancestor debugdag"
5896 optionalrepo = ("identify paths serve config showconfig debugancestor debugdag"
5884 " debugdata debugindex debugindexdot debugrevlog")
5897 " debugdata debugindex debugindexdot debugrevlog")
5885 inferrepo = ("add addremove annotate cat commit diff grep forget log parents"
5898 inferrepo = ("add addremove annotate cat commit diff grep forget log parents"
5886 " remove resolve status debugwalk")
5899 " remove resolve status debugwalk")
@@ -1,332 +1,332 b''
1 Show all commands except debug commands
1 Show all commands except debug commands
2 $ hg debugcomplete
2 $ hg debugcomplete
3 add
3 add
4 addremove
4 addremove
5 annotate
5 annotate
6 archive
6 archive
7 backout
7 backout
8 bisect
8 bisect
9 bookmarks
9 bookmarks
10 branch
10 branch
11 branches
11 branches
12 bundle
12 bundle
13 cat
13 cat
14 clone
14 clone
15 commit
15 commit
16 config
16 config
17 copy
17 copy
18 diff
18 diff
19 export
19 export
20 forget
20 forget
21 graft
21 graft
22 grep
22 grep
23 heads
23 heads
24 help
24 help
25 identify
25 identify
26 import
26 import
27 incoming
27 incoming
28 init
28 init
29 locate
29 locate
30 log
30 log
31 manifest
31 manifest
32 merge
32 merge
33 outgoing
33 outgoing
34 parents
34 parents
35 paths
35 paths
36 phase
36 phase
37 pull
37 pull
38 push
38 push
39 recover
39 recover
40 remove
40 remove
41 rename
41 rename
42 resolve
42 resolve
43 revert
43 revert
44 rollback
44 rollback
45 root
45 root
46 serve
46 serve
47 status
47 status
48 summary
48 summary
49 tag
49 tag
50 tags
50 tags
51 tip
51 tip
52 unbundle
52 unbundle
53 update
53 update
54 verify
54 verify
55 version
55 version
56
56
57 Show all commands that start with "a"
57 Show all commands that start with "a"
58 $ hg debugcomplete a
58 $ hg debugcomplete a
59 add
59 add
60 addremove
60 addremove
61 annotate
61 annotate
62 archive
62 archive
63
63
64 Do not show debug commands if there are other candidates
64 Do not show debug commands if there are other candidates
65 $ hg debugcomplete d
65 $ hg debugcomplete d
66 diff
66 diff
67
67
68 Show debug commands if there are no other candidates
68 Show debug commands if there are no other candidates
69 $ hg debugcomplete debug
69 $ hg debugcomplete debug
70 debugancestor
70 debugancestor
71 debugbuilddag
71 debugbuilddag
72 debugbundle
72 debugbundle
73 debugcheckstate
73 debugcheckstate
74 debugcommands
74 debugcommands
75 debugcomplete
75 debugcomplete
76 debugconfig
76 debugconfig
77 debugdag
77 debugdag
78 debugdata
78 debugdata
79 debugdate
79 debugdate
80 debugdirstate
80 debugdirstate
81 debugdiscovery
81 debugdiscovery
82 debugfileset
82 debugfileset
83 debugfsinfo
83 debugfsinfo
84 debuggetbundle
84 debuggetbundle
85 debugignore
85 debugignore
86 debugindex
86 debugindex
87 debugindexdot
87 debugindexdot
88 debuginstall
88 debuginstall
89 debugknown
89 debugknown
90 debuglabelcomplete
90 debuglabelcomplete
91 debugobsolete
91 debugobsolete
92 debugpathcomplete
92 debugpathcomplete
93 debugpushkey
93 debugpushkey
94 debugpvec
94 debugpvec
95 debugrebuilddirstate
95 debugrebuilddirstate
96 debugrename
96 debugrename
97 debugrevlog
97 debugrevlog
98 debugrevspec
98 debugrevspec
99 debugsetparents
99 debugsetparents
100 debugsub
100 debugsub
101 debugsuccessorssets
101 debugsuccessorssets
102 debugwalk
102 debugwalk
103 debugwireargs
103 debugwireargs
104
104
105 Do not show the alias of a debug command if there are other candidates
105 Do not show the alias of a debug command if there are other candidates
106 (this should hide rawcommit)
106 (this should hide rawcommit)
107 $ hg debugcomplete r
107 $ hg debugcomplete r
108 recover
108 recover
109 remove
109 remove
110 rename
110 rename
111 resolve
111 resolve
112 revert
112 revert
113 rollback
113 rollback
114 root
114 root
115 Show the alias of a debug command if there are no other candidates
115 Show the alias of a debug command if there are no other candidates
116 $ hg debugcomplete rawc
116 $ hg debugcomplete rawc
117
117
118
118
119 Show the global options
119 Show the global options
120 $ hg debugcomplete --options | sort
120 $ hg debugcomplete --options | sort
121 --config
121 --config
122 --cwd
122 --cwd
123 --debug
123 --debug
124 --debugger
124 --debugger
125 --encoding
125 --encoding
126 --encodingmode
126 --encodingmode
127 --help
127 --help
128 --hidden
128 --hidden
129 --noninteractive
129 --noninteractive
130 --profile
130 --profile
131 --quiet
131 --quiet
132 --repository
132 --repository
133 --time
133 --time
134 --traceback
134 --traceback
135 --verbose
135 --verbose
136 --version
136 --version
137 -R
137 -R
138 -h
138 -h
139 -q
139 -q
140 -v
140 -v
141 -y
141 -y
142
142
143 Show the options for the "serve" command
143 Show the options for the "serve" command
144 $ hg debugcomplete --options serve | sort
144 $ hg debugcomplete --options serve | sort
145 --accesslog
145 --accesslog
146 --address
146 --address
147 --certificate
147 --certificate
148 --cmdserver
148 --cmdserver
149 --config
149 --config
150 --cwd
150 --cwd
151 --daemon
151 --daemon
152 --daemon-pipefds
152 --daemon-pipefds
153 --debug
153 --debug
154 --debugger
154 --debugger
155 --encoding
155 --encoding
156 --encodingmode
156 --encodingmode
157 --errorlog
157 --errorlog
158 --help
158 --help
159 --hidden
159 --hidden
160 --ipv6
160 --ipv6
161 --name
161 --name
162 --noninteractive
162 --noninteractive
163 --pid-file
163 --pid-file
164 --port
164 --port
165 --prefix
165 --prefix
166 --profile
166 --profile
167 --quiet
167 --quiet
168 --repository
168 --repository
169 --stdio
169 --stdio
170 --style
170 --style
171 --templates
171 --templates
172 --time
172 --time
173 --traceback
173 --traceback
174 --verbose
174 --verbose
175 --version
175 --version
176 --web-conf
176 --web-conf
177 -6
177 -6
178 -A
178 -A
179 -E
179 -E
180 -R
180 -R
181 -a
181 -a
182 -d
182 -d
183 -h
183 -h
184 -n
184 -n
185 -p
185 -p
186 -q
186 -q
187 -t
187 -t
188 -v
188 -v
189 -y
189 -y
190
190
191 Show an error if we use --options with an ambiguous abbreviation
191 Show an error if we use --options with an ambiguous abbreviation
192 $ hg debugcomplete --options s
192 $ hg debugcomplete --options s
193 hg: command 's' is ambiguous:
193 hg: command 's' is ambiguous:
194 serve showconfig status summary
194 serve showconfig status summary
195 [255]
195 [255]
196
196
197 Show all commands + options
197 Show all commands + options
198 $ hg debugcommands
198 $ hg debugcommands
199 add: include, exclude, subrepos, dry-run
199 add: include, exclude, subrepos, dry-run
200 annotate: rev, follow, no-follow, text, user, file, date, number, changeset, line-number, ignore-all-space, ignore-space-change, ignore-blank-lines, include, exclude
200 annotate: rev, follow, no-follow, text, user, file, date, number, changeset, line-number, ignore-all-space, ignore-space-change, ignore-blank-lines, include, exclude
201 clone: noupdate, updaterev, rev, branch, pull, uncompressed, ssh, remotecmd, insecure
201 clone: noupdate, updaterev, rev, branch, pull, uncompressed, ssh, remotecmd, insecure
202 commit: addremove, close-branch, amend, secret, include, exclude, message, logfile, date, user, subrepos
202 commit: addremove, close-branch, amend, secret, include, exclude, message, logfile, date, user, subrepos
203 diff: rev, change, text, git, nodates, show-function, reverse, ignore-all-space, ignore-space-change, ignore-blank-lines, unified, stat, include, exclude, subrepos
203 diff: rev, change, text, git, nodates, show-function, reverse, ignore-all-space, ignore-space-change, ignore-blank-lines, unified, stat, include, exclude, subrepos
204 export: output, switch-parent, rev, text, git, nodates
204 export: output, switch-parent, rev, text, git, nodates
205 forget: include, exclude
205 forget: include, exclude
206 init: ssh, remotecmd, insecure
206 init: ssh, remotecmd, insecure
207 log: follow, follow-first, date, copies, keyword, rev, removed, only-merges, user, only-branch, branch, prune, patch, git, limit, no-merges, stat, graph, style, template, include, exclude
207 log: follow, follow-first, date, copies, keyword, rev, removed, only-merges, user, only-branch, branch, prune, patch, git, limit, no-merges, stat, graph, style, template, include, exclude
208 merge: force, rev, preview, tool
208 merge: force, rev, preview, tool
209 pull: update, force, rev, bookmark, branch, ssh, remotecmd, insecure
209 pull: update, force, rev, bookmark, branch, ssh, remotecmd, insecure
210 push: force, rev, bookmark, branch, new-branch, ssh, remotecmd, insecure
210 push: force, rev, bookmark, branch, new-branch, ssh, remotecmd, insecure
211 remove: after, force, include, exclude
211 remove: after, force, include, exclude
212 serve: accesslog, daemon, daemon-pipefds, errorlog, port, address, prefix, name, web-conf, webdir-conf, pid-file, stdio, cmdserver, templates, style, ipv6, certificate
212 serve: accesslog, daemon, daemon-pipefds, errorlog, port, address, prefix, name, web-conf, webdir-conf, pid-file, stdio, cmdserver, templates, style, ipv6, certificate
213 status: all, modified, added, removed, deleted, clean, unknown, ignored, no-status, copies, print0, rev, change, include, exclude, subrepos
213 status: all, modified, added, removed, deleted, clean, unknown, ignored, no-status, copies, print0, rev, change, include, exclude, subrepos
214 summary: remote
214 summary: remote
215 update: clean, check, date, rev
215 update: clean, check, date, rev
216 addremove: similarity, include, exclude, dry-run
216 addremove: similarity, include, exclude, dry-run
217 archive: no-decode, prefix, rev, type, subrepos, include, exclude
217 archive: no-decode, prefix, rev, type, subrepos, include, exclude
218 backout: merge, parent, rev, tool, include, exclude, message, logfile, date, user
218 backout: merge, parent, rev, tool, include, exclude, message, logfile, date, user
219 bisect: reset, good, bad, skip, extend, command, noupdate
219 bisect: reset, good, bad, skip, extend, command, noupdate
220 bookmarks: force, rev, delete, rename, inactive
220 bookmarks: force, rev, delete, rename, inactive
221 branch: force, clean
221 branch: force, clean
222 branches: active, closed
222 branches: active, closed
223 bundle: force, rev, branch, base, all, type, ssh, remotecmd, insecure
223 bundle: force, rev, branch, base, all, type, ssh, remotecmd, insecure
224 cat: output, rev, decode, include, exclude
224 cat: output, rev, decode, include, exclude
225 config: untrusted, edit
225 config: untrusted, edit, local, global
226 copy: after, force, include, exclude, dry-run
226 copy: after, force, include, exclude, dry-run
227 debugancestor:
227 debugancestor:
228 debugbuilddag: mergeable-file, overwritten-file, new-file
228 debugbuilddag: mergeable-file, overwritten-file, new-file
229 debugbundle: all
229 debugbundle: all
230 debugcheckstate:
230 debugcheckstate:
231 debugcommands:
231 debugcommands:
232 debugcomplete: options
232 debugcomplete: options
233 debugdag: tags, branches, dots, spaces
233 debugdag: tags, branches, dots, spaces
234 debugdata: changelog, manifest
234 debugdata: changelog, manifest
235 debugdate: extended
235 debugdate: extended
236 debugdirstate: nodates, datesort
236 debugdirstate: nodates, datesort
237 debugdiscovery: old, nonheads, ssh, remotecmd, insecure
237 debugdiscovery: old, nonheads, ssh, remotecmd, insecure
238 debugfileset: rev
238 debugfileset: rev
239 debugfsinfo:
239 debugfsinfo:
240 debuggetbundle: head, common, type
240 debuggetbundle: head, common, type
241 debugignore:
241 debugignore:
242 debugindex: changelog, manifest, format
242 debugindex: changelog, manifest, format
243 debugindexdot:
243 debugindexdot:
244 debuginstall:
244 debuginstall:
245 debugknown:
245 debugknown:
246 debuglabelcomplete:
246 debuglabelcomplete:
247 debugobsolete: flags, date, user
247 debugobsolete: flags, date, user
248 debugpathcomplete: full, normal, added, removed
248 debugpathcomplete: full, normal, added, removed
249 debugpushkey:
249 debugpushkey:
250 debugpvec:
250 debugpvec:
251 debugrebuilddirstate: rev
251 debugrebuilddirstate: rev
252 debugrename: rev
252 debugrename: rev
253 debugrevlog: changelog, manifest, dump
253 debugrevlog: changelog, manifest, dump
254 debugrevspec: optimize
254 debugrevspec: optimize
255 debugsetparents:
255 debugsetparents:
256 debugsub: rev
256 debugsub: rev
257 debugsuccessorssets:
257 debugsuccessorssets:
258 debugwalk: include, exclude
258 debugwalk: include, exclude
259 debugwireargs: three, four, five, ssh, remotecmd, insecure
259 debugwireargs: three, four, five, ssh, remotecmd, insecure
260 graft: rev, continue, edit, log, currentdate, currentuser, date, user, tool, dry-run
260 graft: rev, continue, edit, log, currentdate, currentuser, date, user, tool, dry-run
261 grep: print0, all, text, follow, ignore-case, files-with-matches, line-number, rev, user, date, include, exclude
261 grep: print0, all, text, follow, ignore-case, files-with-matches, line-number, rev, user, date, include, exclude
262 heads: rev, topo, active, closed, style, template
262 heads: rev, topo, active, closed, style, template
263 help: extension, command, keyword
263 help: extension, command, keyword
264 identify: rev, num, id, branch, tags, bookmarks, ssh, remotecmd, insecure
264 identify: rev, num, id, branch, tags, bookmarks, ssh, remotecmd, insecure
265 import: strip, base, edit, force, no-commit, bypass, exact, import-branch, message, logfile, date, user, similarity
265 import: strip, base, edit, force, no-commit, bypass, exact, import-branch, message, logfile, date, user, similarity
266 incoming: force, newest-first, bundle, rev, bookmarks, branch, patch, git, limit, no-merges, stat, graph, style, template, ssh, remotecmd, insecure, subrepos
266 incoming: force, newest-first, bundle, rev, bookmarks, branch, patch, git, limit, no-merges, stat, graph, style, template, ssh, remotecmd, insecure, subrepos
267 locate: rev, print0, fullpath, include, exclude
267 locate: rev, print0, fullpath, include, exclude
268 manifest: rev, all
268 manifest: rev, all
269 outgoing: force, rev, newest-first, bookmarks, branch, patch, git, limit, no-merges, stat, graph, style, template, ssh, remotecmd, insecure, subrepos
269 outgoing: force, rev, newest-first, bookmarks, branch, patch, git, limit, no-merges, stat, graph, style, template, ssh, remotecmd, insecure, subrepos
270 parents: rev, style, template
270 parents: rev, style, template
271 paths:
271 paths:
272 phase: public, draft, secret, force, rev
272 phase: public, draft, secret, force, rev
273 recover:
273 recover:
274 rename: after, force, include, exclude, dry-run
274 rename: after, force, include, exclude, dry-run
275 resolve: all, list, mark, unmark, no-status, tool, include, exclude
275 resolve: all, list, mark, unmark, no-status, tool, include, exclude
276 revert: all, date, rev, no-backup, include, exclude, dry-run
276 revert: all, date, rev, no-backup, include, exclude, dry-run
277 rollback: dry-run, force
277 rollback: dry-run, force
278 root:
278 root:
279 tag: force, local, rev, remove, edit, message, date, user
279 tag: force, local, rev, remove, edit, message, date, user
280 tags:
280 tags:
281 tip: patch, git, style, template
281 tip: patch, git, style, template
282 unbundle: update
282 unbundle: update
283 verify:
283 verify:
284 version:
284 version:
285
285
286 $ hg init a
286 $ hg init a
287 $ cd a
287 $ cd a
288 $ echo fee > fee
288 $ echo fee > fee
289 $ hg ci -q -Amfee
289 $ hg ci -q -Amfee
290 $ hg tag fee
290 $ hg tag fee
291 $ mkdir fie
291 $ mkdir fie
292 $ echo dead > fie/dead
292 $ echo dead > fie/dead
293 $ echo live > fie/live
293 $ echo live > fie/live
294 $ hg bookmark fo
294 $ hg bookmark fo
295 $ hg branch -q fie
295 $ hg branch -q fie
296 $ hg ci -q -Amfie
296 $ hg ci -q -Amfie
297 $ echo fo > fo
297 $ echo fo > fo
298 $ hg branch -qf default
298 $ hg branch -qf default
299 $ hg ci -q -Amfo
299 $ hg ci -q -Amfo
300 $ echo Fum > Fum
300 $ echo Fum > Fum
301 $ hg ci -q -AmFum
301 $ hg ci -q -AmFum
302 $ hg bookmark Fum
302 $ hg bookmark Fum
303
303
304 Test debugpathcomplete
304 Test debugpathcomplete
305
305
306 $ hg debugpathcomplete f
306 $ hg debugpathcomplete f
307 fee
307 fee
308 fie
308 fie
309 fo
309 fo
310 $ hg debugpathcomplete -f f
310 $ hg debugpathcomplete -f f
311 fee
311 fee
312 fie/dead
312 fie/dead
313 fie/live
313 fie/live
314 fo
314 fo
315
315
316 $ hg rm Fum
316 $ hg rm Fum
317 $ hg debugpathcomplete -r F
317 $ hg debugpathcomplete -r F
318 Fum
318 Fum
319
319
320 Test debuglabelcomplete
320 Test debuglabelcomplete
321
321
322 $ hg debuglabelcomplete
322 $ hg debuglabelcomplete
323 Fum
323 Fum
324 default
324 default
325 fee
325 fee
326 fie
326 fie
327 fo
327 fo
328 tip
328 tip
329 $ hg debuglabelcomplete f
329 $ hg debuglabelcomplete f
330 fee
330 fee
331 fie
331 fie
332 fo
332 fo
General Comments 0
You need to be logged in to leave comments. Login now